From webhook-mailer at python.org Tue Mar 1 08:53:22 2022 From: webhook-mailer at python.org (markshannon) Date: Tue, 01 Mar 2022 13:53:22 -0000 Subject: [Python-checkins] bpo-46841: Use inline caching for `COMPARE_OP` (GH-31622) Message-ID: https://github.com/python/cpython/commit/7820a5897e7762df23bff1cbe749652130654a08 commit: 7820a5897e7762df23bff1cbe749652130654a08 branch: main author: Brandt Bucher committer: markshannon date: 2022-03-01T13:53:13Z summary: bpo-46841: Use inline caching for `COMPARE_OP` (GH-31622) files: A Misc/NEWS.d/next/Core and Builtins/2022-02-28-12-01-04.bpo-46841.r60AMJ.rst M Include/internal/pycore_code.h M Include/opcode.h M Lib/importlib/_bootstrap_external.py M Lib/opcode.py M Lib/test/test_compile.py M Lib/test/test_dis.py M Python/ceval.c M Python/specialize.c diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index dfa15b8cd61e4..47c1998c88d21 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -77,13 +77,20 @@ typedef struct { } _PyBinaryOpCache; #define INLINE_CACHE_ENTRIES_BINARY_OP CACHE_ENTRIES(_PyBinaryOpCache) + typedef struct { _Py_CODEUNIT counter; } _PyUnpackSequenceCache; - #define INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE \ - (sizeof(_PyUnpackSequenceCache) / sizeof(_Py_CODEUNIT)) + CACHE_ENTRIES(_PyUnpackSequenceCache) + +typedef struct { + _Py_CODEUNIT counter; + _Py_CODEUNIT mask; +} _PyCompareOpCache; + +#define INLINE_CACHE_ENTRIES_COMPARE_OP CACHE_ENTRIES(_PyCompareOpCache) /* Maximum size of code to quicken, in code units. */ #define MAX_SIZE_TO_QUICKEN 5000 @@ -323,8 +330,9 @@ extern int _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, int narg extern int _Py_Specialize_Precall(PyObject *callable, _Py_CODEUNIT *instr, int nargs, PyObject *kwnames, SpecializedCacheEntry *cache, PyObject *builtins); extern void _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, - int oparg); -extern void _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, SpecializedCacheEntry *cache); + int oparg); +extern void _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, + _Py_CODEUNIT *instr, int oparg); extern void _Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr, int oparg); diff --git a/Include/opcode.h b/Include/opcode.h index 99480def30da5..ba85b7ff75fcd 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -212,6 +212,7 @@ static const uint32_t _PyOpcode_Jump[8] = { const uint8_t _PyOpcode_InlineCacheEntries[256] = { [UNPACK_SEQUENCE] = 1, + [COMPARE_OP] = 2, [LOAD_GLOBAL] = 5, [BINARY_OP] = 1, }; diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index f051dfe9492f5..c69c0c73e7a27 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -389,6 +389,7 @@ def _write_atomic(path, data, mode=0o666): # Python 3.11a5 3480 (New CALL opcodes, second iteration) # Python 3.11a5 3481 (Use inline cache for BINARY_OP) # Python 3.11a5 3482 (Use inline caching for UNPACK_SEQUENCE and LOAD_GLOBAL) +# Python 3.11a5 3483 (Use inline caching for COMPARE_OP) # Python 3.12 will start with magic number 3500 @@ -403,7 +404,7 @@ def _write_atomic(path, data, mode=0o666): # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array # in PC/launcher.c must also be updated. -MAGIC_NUMBER = (3482).to_bytes(2, 'little') + b'\r\n' +MAGIC_NUMBER = (3483).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c _PYCACHE = '__pycache__' diff --git a/Lib/opcode.py b/Lib/opcode.py index fb2d24fd1f007..dc45cff3017a6 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -125,7 +125,7 @@ def jabs_op(name, op, entries=0): def_op('BUILD_SET', 104) # Number of set items def_op('BUILD_MAP', 105) # Number of dict entries name_op('LOAD_ATTR', 106) # Index in name list -def_op('COMPARE_OP', 107) # Comparison operator +def_op('COMPARE_OP', 107, 2) # Comparison operator hascompare.append(107) name_op('IMPORT_NAME', 108) # Index in name list name_op('IMPORT_FROM', 109) # Index in name list diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 5268192b7cd97..79046b8615e3e 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -1002,7 +1002,9 @@ def if_else_break(): 'JUMP_FORWARD', ) - for line, instr in enumerate(dis.Bytecode(if_else_break)): + for line, instr in enumerate( + dis.Bytecode(if_else_break, show_caches=True) + ): if instr.opname == 'JUMP_FORWARD': self.assertNotEqual(instr.arg, 0) elif instr.opname in HANDLED_JUMPS: diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index a13e0f6edb874..8de2ed09e8352 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -1223,7 +1223,7 @@ def _prepare_test_cases(): Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=18, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=20, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='GET_ITER', opcode=68, arg=None, argval=None, argrepr='', offset=22, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='FOR_ITER', opcode=93, arg=24, argval=74, argrepr='to 74', offset=24, starts_line=None, is_jump_target=True, positions=None), + Instruction(opname='FOR_ITER', opcode=93, arg=28, argval=82, argrepr='to 82', offset=24, starts_line=None, is_jump_target=True, positions=None), Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=26, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=28, starts_line=4, is_jump_target=False, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=30, starts_line=None, is_jump_target=False, positions=None), @@ -1234,128 +1234,128 @@ def _prepare_test_cases(): Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=50, starts_line=5, is_jump_target=False, positions=None), Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=52, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=54, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=30, argval=60, argrepr='to 60', offset=56, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=12, argval=24, argrepr='to 24', offset=58, starts_line=6, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=60, starts_line=7, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=62, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=64, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=36, argval=72, argrepr='to 72', offset=66, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=68, starts_line=8, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=12, argval=96, argrepr='to 96', offset=70, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=12, argval=24, argrepr='to 24', offset=72, starts_line=7, is_jump_target=True, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=74, starts_line=10, is_jump_target=True, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=76, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=88, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=90, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=92, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=94, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=96, starts_line=11, is_jump_target=True, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=78, argval=156, argrepr='to 156', offset=98, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=100, starts_line=12, is_jump_target=True, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=102, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=114, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=116, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=118, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=120, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=122, starts_line=13, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=124, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BINARY_OP', opcode=122, arg=23, argval=23, argrepr='-=', offset=126, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=130, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=132, starts_line=14, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=134, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=136, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=71, argval=142, argrepr='to 142', offset=138, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=48, argval=96, argrepr='to 96', offset=140, starts_line=15, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=142, starts_line=16, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=144, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=146, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=76, argval=152, argrepr='to 152', offset=148, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=13, argval=178, argrepr='to 178', offset=150, starts_line=17, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=152, starts_line=11, is_jump_target=True, positions=None), - Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=50, argval=100, argrepr='to 100', offset=154, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=156, starts_line=19, is_jump_target=True, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=158, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=170, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=172, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=174, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=176, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=178, starts_line=20, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=180, starts_line=21, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=182, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BINARY_OP', opcode=122, arg=11, argval=11, argrepr='/', offset=184, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=188, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=190, starts_line=25, is_jump_target=False, positions=None), - Instruction(opname='BEFORE_WITH', opcode=53, arg=None, argval=None, argrepr='', offset=192, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=194, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=196, starts_line=26, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=198, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval='Never reach this', argrepr="'Never reach this'", offset=210, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=212, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=214, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=216, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=218, starts_line=25, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=220, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=222, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=2, argval=2, argrepr='', offset=224, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=2, argval=2, argrepr='', offset=226, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=228, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=11, argval=254, argrepr='to 254', offset=230, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=232, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='WITH_EXCEPT_START', opcode=49, arg=None, argval=None, argrepr='', offset=234, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=123, argval=246, argrepr='to 246', offset=236, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=2, argval=2, argrepr='', offset=238, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=240, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=242, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=244, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=246, starts_line=None, is_jump_target=True, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=248, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=250, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=252, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=26, argval=308, argrepr='to 308', offset=254, starts_line=None, is_jump_target=True, positions=None), - Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=256, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=2, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=258, starts_line=22, is_jump_target=False, positions=None), - Instruction(opname='JUMP_IF_NOT_EXC_MATCH', opcode=121, arg=150, argval=300, argrepr='to 300', offset=270, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=272, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=274, starts_line=23, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=276, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=288, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=290, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=292, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=294, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=296, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=17, argval=334, argrepr='to 334', offset=298, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=300, starts_line=22, is_jump_target=True, positions=None), - Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=302, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=304, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=306, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=308, starts_line=28, is_jump_target=True, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=310, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=322, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=324, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=326, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=328, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=330, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=332, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=334, starts_line=23, is_jump_target=True, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=336, starts_line=28, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=338, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=350, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=352, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=354, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=356, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=358, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=360, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=362, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=364, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=366, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=378, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=380, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=382, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=384, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=386, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=388, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=390, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=392, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=32, argval=64, argrepr='to 64', offset=60, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=12, argval=24, argrepr='to 24', offset=62, starts_line=6, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=64, starts_line=7, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=66, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=68, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=40, argval=80, argrepr='to 80', offset=74, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=76, starts_line=8, is_jump_target=False, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=12, argval=104, argrepr='to 104', offset=78, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=12, argval=24, argrepr='to 24', offset=80, starts_line=7, is_jump_target=True, positions=None), + Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=82, starts_line=10, is_jump_target=True, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=84, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=96, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=98, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=100, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=102, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=104, starts_line=11, is_jump_target=True, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=86, argval=172, argrepr='to 172', offset=106, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=108, starts_line=12, is_jump_target=True, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=110, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=122, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=124, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=126, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=128, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=130, starts_line=13, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=132, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='BINARY_OP', opcode=122, arg=23, argval=23, argrepr='-=', offset=134, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=138, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=140, starts_line=14, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=142, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=144, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=77, argval=154, argrepr='to 154', offset=150, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=52, argval=104, argrepr='to 104', offset=152, starts_line=15, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=154, starts_line=16, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=156, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=158, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=84, argval=168, argrepr='to 168', offset=164, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=13, argval=194, argrepr='to 194', offset=166, starts_line=17, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=168, starts_line=11, is_jump_target=True, positions=None), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=54, argval=108, argrepr='to 108', offset=170, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=172, starts_line=19, is_jump_target=True, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=174, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=186, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=188, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=190, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=192, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=194, starts_line=20, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=196, starts_line=21, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=198, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='BINARY_OP', opcode=122, arg=11, argval=11, argrepr='/', offset=200, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=204, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=206, starts_line=25, is_jump_target=False, positions=None), + Instruction(opname='BEFORE_WITH', opcode=53, arg=None, argval=None, argrepr='', offset=208, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=210, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=212, starts_line=26, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=214, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval='Never reach this', argrepr="'Never reach this'", offset=226, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=228, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=230, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=232, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=234, starts_line=25, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=236, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=238, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=2, argval=2, argrepr='', offset=240, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=2, argval=2, argrepr='', offset=242, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=244, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=11, argval=270, argrepr='to 270', offset=246, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=248, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='WITH_EXCEPT_START', opcode=49, arg=None, argval=None, argrepr='', offset=250, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=131, argval=262, argrepr='to 262', offset=252, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=2, argval=2, argrepr='', offset=254, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=256, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=258, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=260, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=262, starts_line=None, is_jump_target=True, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=264, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=266, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=268, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=26, argval=324, argrepr='to 324', offset=270, starts_line=None, is_jump_target=True, positions=None), + Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=272, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=2, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=274, starts_line=22, is_jump_target=False, positions=None), + Instruction(opname='JUMP_IF_NOT_EXC_MATCH', opcode=121, arg=158, argval=316, argrepr='to 316', offset=286, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=288, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=290, starts_line=23, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=292, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=304, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=306, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=308, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=310, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=312, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=17, argval=350, argrepr='to 350', offset=314, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=316, starts_line=22, is_jump_target=True, positions=None), + Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=318, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=320, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=322, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=324, starts_line=28, is_jump_target=True, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=326, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=338, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=340, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=342, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=344, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=346, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=348, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=350, starts_line=23, is_jump_target=True, positions=None), + Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=352, starts_line=28, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=354, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=366, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=368, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=370, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=372, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=374, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=376, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=378, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=380, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=382, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=394, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=396, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=398, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=400, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=402, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=404, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=406, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=408, starts_line=None, is_jump_target=False, positions=None), ] # One last piece of inspect fodder to check the default line number handling diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-28-12-01-04.bpo-46841.r60AMJ.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-28-12-01-04.bpo-46841.r60AMJ.rst new file mode 100644 index 0000000000000..bc885be5174e8 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-02-28-12-01-04.bpo-46841.r60AMJ.rst @@ -0,0 +1 @@ +Use inline caching for :opcode:`COMPARE_OP`. diff --git a/Python/ceval.c b/Python/ceval.c index 13866ba355e97..0f57e7dc94a04 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3671,8 +3671,10 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int SET_TOP(res); Py_DECREF(left); Py_DECREF(right); - if (res == NULL) + if (res == NULL) { goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_COMPARE_OP); PREDICT(POP_JUMP_IF_FALSE); PREDICT(POP_JUMP_IF_TRUE); DISPATCH(); @@ -3680,18 +3682,17 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int TARGET(COMPARE_OP_ADAPTIVE) { assert(cframe.use_tracing == 0); - SpecializedCacheEntry *cache = GET_CACHE(); - if (cache->adaptive.counter == 0) { + _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr; + if (cache->counter == 0) { PyObject *right = TOP(); PyObject *left = SECOND(); next_instr--; - _Py_Specialize_CompareOp(left, right, next_instr, cache); + _Py_Specialize_CompareOp(left, right, next_instr, oparg); DISPATCH(); } else { STAT_INC(COMPARE_OP, deferred); - cache->adaptive.counter--; - oparg = cache->adaptive.original_oparg; + cache->counter--; JUMP_TO_INSTRUCTION(COMPARE_OP); } } @@ -3699,8 +3700,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int TARGET(COMPARE_OP_FLOAT_JUMP) { assert(cframe.use_tracing == 0); // Combined: COMPARE_OP (float ? float) + POP_JUMP_IF_(true/false) - SpecializedCacheEntry *caches = GET_CACHE(); - int when_to_jump_mask = caches[0].adaptive.index; + _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr; + int when_to_jump_mask = cache->mask; PyObject *right = TOP(); PyObject *left = SECOND(); DEOPT_IF(!PyFloat_CheckExact(left), COMPARE_OP); @@ -3711,6 +3712,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int DEOPT_IF(isnan(dleft), COMPARE_OP); DEOPT_IF(isnan(dright), COMPARE_OP); STAT_INC(COMPARE_OP, hit); + JUMPBY(INLINE_CACHE_ENTRIES_COMPARE_OP); NEXTOPARG(); STACK_SHRINK(2); Py_DECREF(left); @@ -3731,8 +3733,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int TARGET(COMPARE_OP_INT_JUMP) { assert(cframe.use_tracing == 0); // Combined: COMPARE_OP (int ? int) + POP_JUMP_IF_(true/false) - SpecializedCacheEntry *caches = GET_CACHE(); - int when_to_jump_mask = caches[0].adaptive.index; + _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr; + int when_to_jump_mask = cache->mask; PyObject *right = TOP(); PyObject *left = SECOND(); DEOPT_IF(!PyLong_CheckExact(left), COMPARE_OP); @@ -3744,6 +3746,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int Py_ssize_t ileft = Py_SIZE(left) * ((PyLongObject *)left)->ob_digit[0]; Py_ssize_t iright = Py_SIZE(right) * ((PyLongObject *)right)->ob_digit[0]; int sign = (ileft > iright) - (ileft < iright); + JUMPBY(INLINE_CACHE_ENTRIES_COMPARE_OP); NEXTOPARG(); STACK_SHRINK(2); Py_DECREF(left); @@ -3764,8 +3767,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int TARGET(COMPARE_OP_STR_JUMP) { assert(cframe.use_tracing == 0); // Combined: COMPARE_OP (str == str or str != str) + POP_JUMP_IF_(true/false) - SpecializedCacheEntry *caches = GET_CACHE(); - int invert = caches[0].adaptive.index; + _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr; + int invert = cache->mask; PyObject *right = TOP(); PyObject *left = SECOND(); DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_OP); @@ -3775,8 +3778,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int if (res < 0) { goto error; } - assert(caches[0].adaptive.original_oparg == Py_EQ || - caches[0].adaptive.original_oparg == Py_NE); + assert(oparg == Py_EQ || oparg == Py_NE); + JUMPBY(INLINE_CACHE_ENTRIES_COMPARE_OP); NEXTOPARG(); assert(opcode == POP_JUMP_IF_TRUE || opcode == POP_JUMP_IF_FALSE); STACK_SHRINK(2); @@ -5601,7 +5604,7 @@ MISS_WITH_CACHE(LOAD_METHOD) MISS_WITH_CACHE(PRECALL) MISS_WITH_CACHE(CALL) MISS_WITH_INLINE_CACHE(BINARY_OP) -MISS_WITH_CACHE(COMPARE_OP) +MISS_WITH_INLINE_CACHE(COMPARE_OP) MISS_WITH_CACHE(BINARY_SUBSCR) MISS_WITH_INLINE_CACHE(UNPACK_SEQUENCE) MISS_WITH_OPARG_COUNTER(STORE_SUBSCR) diff --git a/Python/specialize.c b/Python/specialize.c index 38907f675e809..925edf3f88d5f 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -65,7 +65,6 @@ static uint8_t cache_requirements[256] = { [CALL] = 2, /* _PyAdaptiveEntry and _PyObjectCache/_PyCallCache */ [PRECALL] = 2, /* _PyAdaptiveEntry and _PyObjectCache/_PyCallCache */ [STORE_ATTR] = 1, // _PyAdaptiveEntry - [COMPARE_OP] = 1, /* _PyAdaptiveEntry */ }; Py_ssize_t _Py_QuickenedCount = 0; @@ -2057,26 +2056,27 @@ static int compare_masks[] = { }; void -_Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, - _Py_CODEUNIT *instr, SpecializedCacheEntry *cache) +_Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, + int oparg) { - _PyAdaptiveEntry *adaptive = &cache->adaptive; - int op = adaptive->original_oparg; - int next_opcode = _Py_OPCODE(instr[1]); + assert(_PyOpcode_InlineCacheEntries[COMPARE_OP] == + INLINE_CACHE_ENTRIES_COMPARE_OP); + _PyCompareOpCache *cache = (_PyCompareOpCache *)(instr + 1); + int next_opcode = _Py_OPCODE(instr[INLINE_CACHE_ENTRIES_COMPARE_OP + 1]); if (next_opcode != POP_JUMP_IF_FALSE && next_opcode != POP_JUMP_IF_TRUE) { // Can't ever combine, so don't don't bother being adaptive (unless // we're collecting stats, where it's more important to get accurate hit // counts for the unadaptive version and each of the different failure // types): #ifndef Py_STATS - *instr = _Py_MAKECODEUNIT(COMPARE_OP, adaptive->original_oparg); + *instr = _Py_MAKECODEUNIT(COMPARE_OP, oparg); return; #endif SPECIALIZATION_FAIL(COMPARE_OP, SPEC_FAIL_COMPARE_OP_NOT_FOLLOWED_BY_COND_JUMP); goto failure; } - assert(op <= Py_GE); - int when_to_jump_mask = compare_masks[op]; + assert(oparg <= Py_GE); + int when_to_jump_mask = compare_masks[oparg]; if (next_opcode == POP_JUMP_IF_FALSE) { when_to_jump_mask = (1 | 2 | 4) & ~when_to_jump_mask; } @@ -2085,14 +2085,14 @@ _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, goto failure; } if (PyFloat_CheckExact(lhs)) { - *instr = _Py_MAKECODEUNIT(COMPARE_OP_FLOAT_JUMP, _Py_OPARG(*instr)); - adaptive->index = when_to_jump_mask; + *instr = _Py_MAKECODEUNIT(COMPARE_OP_FLOAT_JUMP, oparg); + cache->mask = when_to_jump_mask; goto success; } if (PyLong_CheckExact(lhs)) { if (Py_ABS(Py_SIZE(lhs)) <= 1 && Py_ABS(Py_SIZE(rhs)) <= 1) { - *instr = _Py_MAKECODEUNIT(COMPARE_OP_INT_JUMP, _Py_OPARG(*instr)); - adaptive->index = when_to_jump_mask; + *instr = _Py_MAKECODEUNIT(COMPARE_OP_INT_JUMP, oparg); + cache->mask = when_to_jump_mask; goto success; } else { @@ -2101,24 +2101,24 @@ _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, } } if (PyUnicode_CheckExact(lhs)) { - if (op != Py_EQ && op != Py_NE) { + if (oparg != Py_EQ && oparg != Py_NE) { SPECIALIZATION_FAIL(COMPARE_OP, SPEC_FAIL_COMPARE_OP_STRING); goto failure; } else { - *instr = _Py_MAKECODEUNIT(COMPARE_OP_STR_JUMP, _Py_OPARG(*instr)); - adaptive->index = (when_to_jump_mask & 2) == 0; + *instr = _Py_MAKECODEUNIT(COMPARE_OP_STR_JUMP, oparg); + cache->mask = (when_to_jump_mask & 2) == 0; goto success; } } SPECIALIZATION_FAIL(COMPARE_OP, compare_op_fail_kind(lhs, rhs)); failure: STAT_INC(COMPARE_OP, failure); - cache_backoff(adaptive); + cache->counter = ADAPTIVE_CACHE_BACKOFF; return; success: STAT_INC(COMPARE_OP, success); - adaptive->counter = initial_counter_value(); + cache->counter = initial_counter_value(); } #ifdef Py_STATS From webhook-mailer at python.org Tue Mar 1 09:21:15 2022 From: webhook-mailer at python.org (markshannon) Date: Tue, 01 Mar 2022 14:21:15 -0000 Subject: [Python-checkins] bpo-46311: Clean up PyLong_FromLong and PyLong_FromLongLong (GH-30496) Message-ID: https://github.com/python/cpython/commit/c60e6b6ad7aaf9c72035ff9fb1575e2710aeb4b4 commit: c60e6b6ad7aaf9c72035ff9fb1575e2710aeb4b4 branch: main author: Mark Dickinson committer: markshannon date: 2022-03-01T14:20:52Z summary: bpo-46311: Clean up PyLong_FromLong and PyLong_FromLongLong (GH-30496) files: A Misc/NEWS.d/next/Core and Builtins/2022-01-09-11-59-04.bpo-30496.KvuuGT.rst M Objects/longobject.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-01-09-11-59-04.bpo-30496.KvuuGT.rst b/Misc/NEWS.d/next/Core and Builtins/2022-01-09-11-59-04.bpo-30496.KvuuGT.rst new file mode 100644 index 0000000000000..cc296841c4a4b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-01-09-11-59-04.bpo-30496.KvuuGT.rst @@ -0,0 +1,3 @@ +Fixed a minor portability issue in the implementation of +:c:func:`PyLong_FromLong`, and added a fast path for single-digit integers +to :c:func:`PyLong_FromLongLong`. diff --git a/Objects/longobject.c b/Objects/longobject.c index 3438906d84275..f85ef241a445d 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -272,44 +272,40 @@ _PyLong_Negate(PyLongObject **x_p) } /* Create a new int object from a C long int */ + PyObject * PyLong_FromLong(long ival) { + PyLongObject *v; + unsigned long abs_ival, t; + int ndigits; + + /* Handle small and medium cases. */ if (IS_SMALL_INT(ival)) { return get_small_int((sdigit)ival); } - unsigned long abs_ival; - int sign; - if (ival < 0) { - /* negate: can't write this as abs_ival = -ival since that - invokes undefined behaviour when ival is LONG_MIN */ - abs_ival = 0U-(twodigits)ival; - sign = -1; - } - else { - abs_ival = (unsigned long)ival; - sign = 1; - } - /* Fast path for single-digit ints */ - if (!(abs_ival >> PyLong_SHIFT)) { + if (-(long)PyLong_MASK <= ival && ival <= (long)PyLong_MASK) { return _PyLong_FromMedium((sdigit)ival); } - /* Must be at least two digits. - * Do shift in two steps to avoid undefined behavior. */ - unsigned long t = (abs_ival >> PyLong_SHIFT) >> PyLong_SHIFT; - Py_ssize_t ndigits = 2; + + /* Count digits (at least two - smaller cases were handled above). */ + abs_ival = ival < 0 ? 0U-(unsigned long)ival : (unsigned long)ival; + /* Do shift in two steps to avoid possible undefined behavior. */ + t = abs_ival >> PyLong_SHIFT >> PyLong_SHIFT; + ndigits = 2; while (t) { ++ndigits; t >>= PyLong_SHIFT; } - PyLongObject *v = _PyLong_New(ndigits); + + /* Construct output value. */ + v = _PyLong_New(ndigits); if (v != NULL) { digit *p = v->ob_digit; - Py_SET_SIZE(v, ndigits * sign); + Py_SET_SIZE(v, ival < 0 ? -ndigits : ndigits); t = abs_ival; while (t) { - *p++ = Py_SAFE_DOWNCAST( - t & PyLong_MASK, unsigned long, digit); + *p++ = (digit)(t & PyLong_MASK); t >>= PyLong_SHIFT; } } @@ -1105,38 +1101,32 @@ PyObject * PyLong_FromLongLong(long long ival) { PyLongObject *v; - unsigned long long abs_ival; - unsigned long long t; /* unsigned so >> doesn't propagate sign bit */ - int ndigits = 0; - int negative = 0; + unsigned long long abs_ival, t; + int ndigits; + /* Handle small and medium cases. */ if (IS_SMALL_INT(ival)) { return get_small_int((sdigit)ival); } - - if (ival < 0) { - /* avoid signed overflow on negation; see comments - in PyLong_FromLong above. */ - abs_ival = (unsigned long long)(-1-ival) + 1; - negative = 1; - } - else { - abs_ival = (unsigned long long)ival; + if (-(long long)PyLong_MASK <= ival && ival <= (long long)PyLong_MASK) { + return _PyLong_FromMedium((sdigit)ival); } - /* Count the number of Python digits. - We used to pick 5 ("big enough for anything"), but that's a - waste of time and space given that 5*15 = 75 bits are rarely - needed. */ - t = abs_ival; + /* Count digits (at least two - smaller cases were handled above). */ + abs_ival = ival < 0 ? 0U-(unsigned long long)ival : (unsigned long long)ival; + /* Do shift in two steps to avoid possible undefined behavior. */ + t = abs_ival >> PyLong_SHIFT >> PyLong_SHIFT; + ndigits = 2; while (t) { ++ndigits; t >>= PyLong_SHIFT; } + + /* Construct output value. */ v = _PyLong_New(ndigits); if (v != NULL) { digit *p = v->ob_digit; - Py_SET_SIZE(v, negative ? -ndigits : ndigits); + Py_SET_SIZE(v, ival < 0 ? -ndigits : ndigits); t = abs_ival; while (t) { *p++ = (digit)(t & PyLong_MASK); From webhook-mailer at python.org Tue Mar 1 09:35:56 2022 From: webhook-mailer at python.org (corona10) Date: Tue, 01 Mar 2022 14:35:56 -0000 Subject: [Python-checkins] bpo-46541: Remove usage of _Py_IDENTIFIER from multibytecodec (GH-31475) Message-ID: https://github.com/python/cpython/commit/0cc63641859b2f60ea65bb7c0b6d1cfcec1e2f1a commit: 0cc63641859b2f60ea65bb7c0b6d1cfcec1e2f1a branch: main author: Dong-hee Na committer: corona10 date: 2022-03-01T23:35:43+09:00 summary: bpo-46541: Remove usage of _Py_IDENTIFIER from multibytecodec (GH-31475) files: M Modules/cjkcodecs/clinic/multibytecodec.c.h M Modules/cjkcodecs/multibytecodec.c diff --git a/Modules/cjkcodecs/clinic/multibytecodec.c.h b/Modules/cjkcodecs/clinic/multibytecodec.c.h index 563888370d06c..1dfb9a1224827 100644 --- a/Modules/cjkcodecs/clinic/multibytecodec.c.h +++ b/Modules/cjkcodecs/clinic/multibytecodec.c.h @@ -481,7 +481,30 @@ PyDoc_STRVAR(_multibytecodec_MultibyteStreamWriter_write__doc__, "\n"); #define _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITE_METHODDEF \ - {"write", (PyCFunction)_multibytecodec_MultibyteStreamWriter_write, METH_O, _multibytecodec_MultibyteStreamWriter_write__doc__}, + {"write", (PyCFunction)(void(*)(void))_multibytecodec_MultibyteStreamWriter_write, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _multibytecodec_MultibyteStreamWriter_write__doc__}, + +static PyObject * +_multibytecodec_MultibyteStreamWriter_write_impl(MultibyteStreamWriterObject *self, + PyTypeObject *cls, + PyObject *strobj); + +static PyObject * +_multibytecodec_MultibyteStreamWriter_write(MultibyteStreamWriterObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = {"O:write", _keywords, 0}; + PyObject *strobj; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &strobj)) { + goto exit; + } + return_value = _multibytecodec_MultibyteStreamWriter_write_impl(self, cls, strobj); + +exit: + return return_value; +} PyDoc_STRVAR(_multibytecodec_MultibyteStreamWriter_writelines__doc__, "writelines($self, lines, /)\n" @@ -489,7 +512,30 @@ PyDoc_STRVAR(_multibytecodec_MultibyteStreamWriter_writelines__doc__, "\n"); #define _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITELINES_METHODDEF \ - {"writelines", (PyCFunction)_multibytecodec_MultibyteStreamWriter_writelines, METH_O, _multibytecodec_MultibyteStreamWriter_writelines__doc__}, + {"writelines", (PyCFunction)(void(*)(void))_multibytecodec_MultibyteStreamWriter_writelines, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _multibytecodec_MultibyteStreamWriter_writelines__doc__}, + +static PyObject * +_multibytecodec_MultibyteStreamWriter_writelines_impl(MultibyteStreamWriterObject *self, + PyTypeObject *cls, + PyObject *lines); + +static PyObject * +_multibytecodec_MultibyteStreamWriter_writelines(MultibyteStreamWriterObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = {"O:writelines", _keywords, 0}; + PyObject *lines; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &lines)) { + goto exit; + } + return_value = _multibytecodec_MultibyteStreamWriter_writelines_impl(self, cls, lines); + +exit: + return return_value; +} PyDoc_STRVAR(_multibytecodec_MultibyteStreamWriter_reset__doc__, "reset($self, /)\n" @@ -497,15 +543,27 @@ PyDoc_STRVAR(_multibytecodec_MultibyteStreamWriter_reset__doc__, "\n"); #define _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_RESET_METHODDEF \ - {"reset", (PyCFunction)_multibytecodec_MultibyteStreamWriter_reset, METH_NOARGS, _multibytecodec_MultibyteStreamWriter_reset__doc__}, + {"reset", (PyCFunction)(void(*)(void))_multibytecodec_MultibyteStreamWriter_reset, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _multibytecodec_MultibyteStreamWriter_reset__doc__}, static PyObject * -_multibytecodec_MultibyteStreamWriter_reset_impl(MultibyteStreamWriterObject *self); +_multibytecodec_MultibyteStreamWriter_reset_impl(MultibyteStreamWriterObject *self, + PyTypeObject *cls); static PyObject * -_multibytecodec_MultibyteStreamWriter_reset(MultibyteStreamWriterObject *self, PyObject *Py_UNUSED(ignored)) +_multibytecodec_MultibyteStreamWriter_reset(MultibyteStreamWriterObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _multibytecodec_MultibyteStreamWriter_reset_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":reset", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = _multibytecodec_MultibyteStreamWriter_reset_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(_multibytecodec___create_codec__doc__, @@ -515,4 +573,4 @@ PyDoc_STRVAR(_multibytecodec___create_codec__doc__, #define _MULTIBYTECODEC___CREATE_CODEC_METHODDEF \ {"__create_codec", (PyCFunction)_multibytecodec___create_codec, METH_O, _multibytecodec___create_codec__doc__}, -/*[clinic end generated code: output=5c0f74129db07c87 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8813c05077580bda input=a9049054013a1b77]*/ diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index acfe96654a226..4769ab26b1b9e 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -5,7 +5,6 @@ */ #define PY_SSIZE_T_CLEAN -#define NEEDS_PY_IDENTIFIER #include "Python.h" #include "structmember.h" // PyMemberDef #include "multibytecodec.h" @@ -19,6 +18,7 @@ typedef struct { PyTypeObject *reader_type; PyTypeObject *writer_type; PyTypeObject *multibytecodec_type; + PyObject *str_write; } _multibytecodec_state; static _multibytecodec_state * @@ -72,8 +72,6 @@ static PyObject *multibytecodec_encode(MultibyteCodec *, #define MBENC_RESET MBENC_MAX<<1 /* reset after an encoding session */ -_Py_IDENTIFIER(write); - static PyObject * make_tuple(PyObject *object, Py_ssize_t len) { @@ -1715,7 +1713,7 @@ static PyType_Spec reader_spec = { static int mbstreamwriter_iwrite(MultibyteStreamWriterObject *self, - PyObject *unistr) + PyObject *unistr, PyObject *str_write) { PyObject *str, *wr; @@ -1723,7 +1721,7 @@ mbstreamwriter_iwrite(MultibyteStreamWriterObject *self, if (str == NULL) return -1; - wr = _PyObject_CallMethodIdOneArg(self->stream, &PyId_write, str); + wr = _PyObject_CallMethodOneArg(self->stream, str_write, str); Py_DECREF(str); if (wr == NULL) return -1; @@ -1735,32 +1733,38 @@ mbstreamwriter_iwrite(MultibyteStreamWriterObject *self, /*[clinic input] _multibytecodec.MultibyteStreamWriter.write + cls: defining_class strobj: object / [clinic start generated code]*/ static PyObject * -_multibytecodec_MultibyteStreamWriter_write(MultibyteStreamWriterObject *self, - PyObject *strobj) -/*[clinic end generated code: output=e13ae841c895251e input=551dc4c018c10a2b]*/ +_multibytecodec_MultibyteStreamWriter_write_impl(MultibyteStreamWriterObject *self, + PyTypeObject *cls, + PyObject *strobj) +/*[clinic end generated code: output=68ade3aea26410ac input=199f26f68bd8425a]*/ { - if (mbstreamwriter_iwrite(self, strobj)) + _multibytecodec_state *state = PyType_GetModuleState(cls); + assert(state != NULL); + if (mbstreamwriter_iwrite(self, strobj, state->str_write)) { return NULL; - else - Py_RETURN_NONE; + } + Py_RETURN_NONE; } /*[clinic input] _multibytecodec.MultibyteStreamWriter.writelines + cls: defining_class lines: object / [clinic start generated code]*/ static PyObject * -_multibytecodec_MultibyteStreamWriter_writelines(MultibyteStreamWriterObject *self, - PyObject *lines) -/*[clinic end generated code: output=e5c4285ac8e7d522 input=57797fe7008d4e96]*/ +_multibytecodec_MultibyteStreamWriter_writelines_impl(MultibyteStreamWriterObject *self, + PyTypeObject *cls, + PyObject *lines) +/*[clinic end generated code: output=b4c99d2cf23ffb88 input=a6d5fe7c74972a34]*/ { PyObject *strobj; int i, r; @@ -1771,13 +1775,15 @@ _multibytecodec_MultibyteStreamWriter_writelines(MultibyteStreamWriterObject *se return NULL; } + _multibytecodec_state *state = PyType_GetModuleState(cls); + assert(state != NULL); for (i = 0; i < PySequence_Length(lines); i++) { /* length can be changed even within this loop */ strobj = PySequence_GetItem(lines, i); if (strobj == NULL) return NULL; - r = mbstreamwriter_iwrite(self, strobj); + r = mbstreamwriter_iwrite(self, strobj, state->str_write); Py_DECREF(strobj); if (r == -1) return NULL; @@ -1791,11 +1797,16 @@ _multibytecodec_MultibyteStreamWriter_writelines(MultibyteStreamWriterObject *se /*[clinic input] _multibytecodec.MultibyteStreamWriter.reset + + cls: defining_class + / + [clinic start generated code]*/ static PyObject * -_multibytecodec_MultibyteStreamWriter_reset_impl(MultibyteStreamWriterObject *self) -/*[clinic end generated code: output=8f54a4d9b03db5ff input=b56dbcbaf35cc10c]*/ +_multibytecodec_MultibyteStreamWriter_reset_impl(MultibyteStreamWriterObject *self, + PyTypeObject *cls) +/*[clinic end generated code: output=32ef224c2a38aa3d input=28af6a9cd38d1979]*/ { PyObject *pwrt; @@ -1814,10 +1825,14 @@ _multibytecodec_MultibyteStreamWriter_reset_impl(MultibyteStreamWriterObject *se return NULL; assert(PyBytes_Check(pwrt)); + + _multibytecodec_state *state = PyType_GetModuleState(cls); + assert(state != NULL); + if (PyBytes_Size(pwrt) > 0) { PyObject *wr; - wr = _PyObject_CallMethodIdOneArg(self->stream, &PyId_write, pwrt); + wr = _PyObject_CallMethodOneArg(self->stream, state->str_write, pwrt); if (wr == NULL) { Py_DECREF(pwrt); return NULL; @@ -1989,6 +2004,7 @@ _multibytecodec_clear(PyObject *mod) Py_CLEAR(state->decoder_type); Py_CLEAR(state->reader_type); Py_CLEAR(state->writer_type); + Py_CLEAR(state->str_write); return 0; } @@ -2017,6 +2033,10 @@ static int _multibytecodec_exec(PyObject *mod) { _multibytecodec_state *state = _multibytecodec_get_state(mod); + state->str_write = PyUnicode_InternFromString("write"); + if (state->str_write == NULL) { + return -1; + } CREATE_TYPE(mod, state->multibytecodec_type, &multibytecodec_spec); CREATE_TYPE(mod, state->encoder_type, &encoder_spec); CREATE_TYPE(mod, state->decoder_type, &decoder_spec); From webhook-mailer at python.org Tue Mar 1 09:44:18 2022 From: webhook-mailer at python.org (vstinner) Date: Tue, 01 Mar 2022 14:44:18 -0000 Subject: [Python-checkins] bpo-46633: Skip tests on ASAN and/or MSAN builds (GH-31632) Message-ID: https://github.com/python/cpython/commit/9204bb72a2da5885facc747e63d2bd2d654606fe commit: 9204bb72a2da5885facc747e63d2bd2d654606fe branch: main author: Victor Stinner committer: vstinner date: 2022-03-01T15:44:08+01:00 summary: bpo-46633: Skip tests on ASAN and/or MSAN builds (GH-31632) Skip tests on ASAN and/or MSAN builds: * multiprocessing tests * test___all__ * test_concurrent_futures * test_decimal * test_peg_generator * test_tools The ASAN job of GitHub Actions no longer excludes these tests. files: M .github/workflows/build.yml M Lib/test/_test_multiprocessing.py M Lib/test/test___all__.py M Lib/test/test_concurrent_futures.py M Lib/test/test_decimal.py M Lib/test/test_peg_generator/__init__.py M Lib/test/test_tools/__init__.py diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5d36dffa80108..f6df74357d2f5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -306,12 +306,4 @@ jobs: - name: Display build info run: make pythoninfo - name: Tests - # Skip test_tools test_peg_generator test_concurrent_futures because - # there are too slow: between 5 and 20 minutes on this CI. - # - # Skip multiprocessing and concurrent.futures tests which are affected by - # bpo-45200 bug: libasan dead lock in pthread_create(). - # - # test___all__ is skipped because importing some modules directly can trigger - # known problems with ASAN (like tk or crypt). - run: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu -x test___all__ test_multiprocessing_fork test_multiprocessing_forkserver test_multiprocessing_spawn test_tools test_peg_generator test_concurrent_futures" + run: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu" diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 6b1b1677910d1..bb73d9e7cc75e 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -73,6 +73,12 @@ msvcrt = None +if support.check_sanitizer(address=True): + # bpo-45200: 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") + + def latin(s): return s.encode('latin') diff --git a/Lib/test/test___all__.py b/Lib/test/test___all__.py index 81293e15f8163..a1a3d899e4e03 100644 --- a/Lib/test/test___all__.py +++ b/Lib/test/test___all__.py @@ -11,6 +11,13 @@ _multiprocessing = None +if support.check_sanitizer(address=True, memory=True): + # bpo-46633: test___all__ is skipped because importing some modules + # directly can trigger known problems with ASAN (like tk or crypt). + raise unittest.SkipTest("workaround ASAN build issues on loading tests " + "like tk or crypt") + + class NoAll(RuntimeError): pass diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py index 71c88a3cadd25..8adba36a387ad 100644 --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -32,6 +32,12 @@ import multiprocessing.util +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 diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index 9ced801afc2e9..b68cfbef23f16 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -34,7 +34,7 @@ import locale from test.support import (run_unittest, run_doctest, is_resource_enabled, requires_IEEE_754, requires_docstrings, - requires_legacy_unicode_capi) + requires_legacy_unicode_capi, check_sanitizer) from test.support import (TestFailed, run_with_locale, cpython_only, darwin_malloc_err_warning) @@ -43,17 +43,6 @@ import random import inspect import threading -import sysconfig -_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 -) - -ADDRESS_SANITIZER = ( - '-fsanitize=address' in _cflags -) if sys.platform == 'darwin': @@ -5518,7 +5507,8 @@ def __abs__(self): # Issue 41540: @unittest.skipIf(sys.platform.startswith("aix"), "AIX: default ulimit: test is flaky because of extreme over-allocation") - @unittest.skipIf(MEMORY_SANITIZER or ADDRESS_SANITIZER, "sanitizer defaults to crashing " + @unittest.skipIf(check_sanitizer(address=True, memory=True), + "ASAN/MSAN sanitizer defaults to crashing " "instead of returning NULL for malloc failure.") def test_maxcontext_exact_arith(self): diff --git a/Lib/test/test_peg_generator/__init__.py b/Lib/test/test_peg_generator/__init__.py index fa855f2104c58..77f72fcc7c6e3 100644 --- a/Lib/test/test_peg_generator/__init__.py +++ b/Lib/test/test_peg_generator/__init__.py @@ -1,7 +1,15 @@ -import os - +import os.path +import unittest +from test import support from test.support import load_package_tests + +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") + + # Load all tests in package def load_tests(*args): return load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_tools/__init__.py b/Lib/test/test_tools/__init__.py index 61af6578e0953..34b0d3b8fb3eb 100644 --- a/Lib/test/test_tools/__init__.py +++ b/Lib/test/test_tools/__init__.py @@ -6,6 +6,13 @@ from test import support from test.support import import_helper + +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") + + basepath = os.path.normpath( os.path.dirname( # os.path.dirname( # Lib From webhook-mailer at python.org Tue Mar 1 10:38:48 2022 From: webhook-mailer at python.org (corona10) Date: Tue, 01 Mar 2022 15:38:48 -0000 Subject: [Python-checkins] bpo-46541: remove usage of _Py_IDENTIFIER from _ssl module (GH-31599) Message-ID: https://github.com/python/cpython/commit/e91b0a7139d4a4cbd2351ccb5cd021a100cf42d2 commit: e91b0a7139d4a4cbd2351ccb5cd021a100cf42d2 branch: main author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> committer: corona10 date: 2022-03-02T00:38:21+09:00 summary: bpo-46541: remove usage of _Py_IDENTIFIER from _ssl module (GH-31599) files: M Modules/_ssl.c M Modules/_ssl.h diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 312b2eabe3db5..e67ab42050b26 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -22,7 +22,6 @@ #define OPENSSL_NO_DEPRECATED 1 #define PY_SSIZE_T_CLEAN -#define NEEDS_PY_IDENTIFIER #include "Python.h" @@ -447,10 +446,6 @@ fill_and_set_sslerror(_sslmodulestate *state, PyObject *err_value = NULL, *reason_obj = NULL, *lib_obj = NULL; PyObject *verify_obj = NULL, *verify_code_obj = NULL; PyObject *init_value, *msg, *key; - _Py_IDENTIFIER(reason); - _Py_IDENTIFIER(library); - _Py_IDENTIFIER(verify_message); - _Py_IDENTIFIER(verify_code); if (errcode != 0) { int lib, reason; @@ -544,20 +539,20 @@ fill_and_set_sslerror(_sslmodulestate *state, if (reason_obj == NULL) reason_obj = Py_None; - if (_PyObject_SetAttrId(err_value, &PyId_reason, reason_obj)) + if (PyObject_SetAttr(err_value, state->str_reason, reason_obj)) goto fail; if (lib_obj == NULL) lib_obj = Py_None; - if (_PyObject_SetAttrId(err_value, &PyId_library, lib_obj)) + if (PyObject_SetAttr(err_value, state->str_library, lib_obj)) goto fail; if ((sslsock != NULL) && (type == state->PySSLCertVerificationErrorObject)) { /* Only set verify code / message for SSLCertVerificationError */ - if (_PyObject_SetAttrId(err_value, &PyId_verify_code, + if (PyObject_SetAttr(err_value, state->str_verify_code, verify_code_obj)) goto fail; - if (_PyObject_SetAttrId(err_value, &PyId_verify_message, verify_obj)) + if (PyObject_SetAttr(err_value, state->str_verify_message, verify_obj)) goto fail; } @@ -6158,6 +6153,29 @@ sslmodule_init_types(PyObject *module) return 0; } +static int +sslmodule_init_strings(PyObject *module) +{ + _sslmodulestate *state = get_ssl_state(module); + state->str_library = PyUnicode_InternFromString("library"); + if (state->str_library == NULL) { + return -1; + } + state->str_reason = PyUnicode_InternFromString("reason"); + if (state->str_reason == NULL) { + return -1; + } + state->str_verify_message = PyUnicode_InternFromString("verify_message"); + if (state->str_verify_message == NULL) { + return -1; + } + state->str_verify_code = PyUnicode_InternFromString("verify_code"); + if (state->str_verify_code == NULL) { + return -1; + } + return 0; +} + static PyModuleDef_Slot sslmodule_slots[] = { {Py_mod_exec, sslmodule_init_types}, {Py_mod_exec, sslmodule_init_exceptions}, @@ -6165,6 +6183,7 @@ static PyModuleDef_Slot sslmodule_slots[] = { {Py_mod_exec, sslmodule_init_errorcodes}, {Py_mod_exec, sslmodule_init_constants}, {Py_mod_exec, sslmodule_init_versioninfo}, + {Py_mod_exec, sslmodule_init_strings}, {0, NULL} }; @@ -6214,7 +6233,10 @@ sslmodule_clear(PyObject *m) Py_CLEAR(state->err_names_to_codes); Py_CLEAR(state->lib_codes_to_names); Py_CLEAR(state->Sock_Type); - + Py_CLEAR(state->str_library); + Py_CLEAR(state->str_reason); + Py_CLEAR(state->str_verify_code); + Py_CLEAR(state->str_verify_message); return 0; } diff --git a/Modules/_ssl.h b/Modules/_ssl.h index 5593a455de4dc..d68ccdec5e88c 100644 --- a/Modules/_ssl.h +++ b/Modules/_ssl.h @@ -29,6 +29,11 @@ typedef struct { PyObject *lib_codes_to_names; /* socket type from module CAPI */ PyTypeObject *Sock_Type; + /* Interned strings */ + PyObject *str_library; + PyObject *str_reason; + PyObject *str_verify_code; + PyObject *str_verify_message; } _sslmodulestate; static struct PyModuleDef _sslmodule_def; From webhook-mailer at python.org Tue Mar 1 11:00:52 2022 From: webhook-mailer at python.org (markshannon) Date: Tue, 01 Mar 2022 16:00:52 -0000 Subject: [Python-checkins] bpo-46841: Use inline cache for `BINARY_SUBSCR`. (GH-31618) Message-ID: https://github.com/python/cpython/commit/3b0f1c5a710eff289dc44bec972dbaea353cc54f commit: 3b0f1c5a710eff289dc44bec972dbaea353cc54f branch: main author: Mark Shannon committer: markshannon date: 2022-03-01T16:00:34Z summary: bpo-46841: Use inline cache for `BINARY_SUBSCR`. (GH-31618) files: A Misc/NEWS.d/next/Core and Builtins/2022-02-28-15-46-36.bpo-46841.MDQoty.rst M Include/cpython/object.h M Include/internal/pycore_code.h M Include/opcode.h M Lib/importlib/_bootstrap_external.py M Lib/opcode.py M Lib/test/test_capi.py M Lib/test/test_sys.py M Programs/test_frozenmain.h M Python/ceval.c M Python/specialize.c diff --git a/Include/cpython/object.h b/Include/cpython/object.h index 5f978eec46580..b018dabf9d862 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -229,6 +229,13 @@ struct _typeobject { vectorcallfunc tp_vectorcall; }; +/* This struct is used by the specializer + * It should should be treated as an opaque blob + * by code other than the specializer and interpreter. */ +struct _specialization_cache { + PyObject *getitem; +}; + /* The *real* layout of a type object when allocated on the heap */ typedef struct _heaptypeobject { /* Note: there's a dependency on the order of these members @@ -247,6 +254,7 @@ typedef struct _heaptypeobject { struct _dictkeysobject *ht_cached_keys; PyObject *ht_module; char *_ht_tpname; // Storage for "tp_name"; see PyType_FromModuleAndSpec + struct _specialization_cache _spec_cache; // For use by the specializer. /* here are optional user slots, followed by the members. */ } PyHeapTypeObject; diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index 47c1998c88d21..b9671d0ec32bb 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -92,6 +92,15 @@ typedef struct { #define INLINE_CACHE_ENTRIES_COMPARE_OP CACHE_ENTRIES(_PyCompareOpCache) +typedef struct { + _Py_CODEUNIT counter; + _Py_CODEUNIT type_version; + _Py_CODEUNIT _t1; + _Py_CODEUNIT func_version; +} _PyBinarySubscrCache; + +#define INLINE_CACHE_ENTRIES_BINARY_SUBSCR CACHE_ENTRIES(_PyBinarySubscrCache) + /* Maximum size of code to quicken, in code units. */ #define MAX_SIZE_TO_QUICKEN 5000 @@ -323,7 +332,7 @@ extern int _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObjec extern int _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, SpecializedCacheEntry *cache); extern int _Py_Specialize_LoadGlobal(PyObject *globals, PyObject *builtins, _Py_CODEUNIT *instr, PyObject *name); extern int _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, SpecializedCacheEntry *cache); -extern int _Py_Specialize_BinarySubscr(PyObject *sub, PyObject *container, _Py_CODEUNIT *instr, SpecializedCacheEntry *cache); +extern int _Py_Specialize_BinarySubscr(PyObject *sub, PyObject *container, _Py_CODEUNIT *instr); extern int _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *instr); extern int _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, PyObject *kwnames, SpecializedCacheEntry *cache); diff --git a/Include/opcode.h b/Include/opcode.h index ba85b7ff75fcd..f6330d9056aa1 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -211,6 +211,7 @@ static const uint32_t _PyOpcode_Jump[8] = { }; const uint8_t _PyOpcode_InlineCacheEntries[256] = { + [BINARY_SUBSCR] = 4, [UNPACK_SEQUENCE] = 1, [COMPARE_OP] = 2, [LOAD_GLOBAL] = 5, diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index c69c0c73e7a27..dd1f6ffd64cee 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -389,7 +389,7 @@ def _write_atomic(path, data, mode=0o666): # Python 3.11a5 3480 (New CALL opcodes, second iteration) # Python 3.11a5 3481 (Use inline cache for BINARY_OP) # Python 3.11a5 3482 (Use inline caching for UNPACK_SEQUENCE and LOAD_GLOBAL) -# Python 3.11a5 3483 (Use inline caching for COMPARE_OP) +# Python 3.11a5 3483 (Use inline caching for COMPARE_OP and BINARY_SUBSCR) # Python 3.12 will start with magic number 3500 diff --git a/Lib/opcode.py b/Lib/opcode.py index dc45cff3017a6..9b08562cd04f6 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -68,7 +68,7 @@ def jabs_op(name, op, entries=0): def_op('UNARY_INVERT', 15) -def_op('BINARY_SUBSCR', 25) +def_op('BINARY_SUBSCR', 25, 4) def_op('GET_LEN', 30) def_op('MATCH_MAPPING', 31) diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 8832292a9991a..d9615430327a4 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -335,7 +335,7 @@ class C(): pass *_, count = line.split(b' ') count = int(count) self.assertLessEqual(count, i*5) - self.assertGreaterEqual(count, i*5-1) + self.assertGreaterEqual(count, i*5-2) def test_mapping_keys_values_items(self): class Mapping1(dict): diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index f828d1b15d286..70768f56fa9f1 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -1501,7 +1501,9 @@ def delx(self): del self.__x '3P' # PyMappingMethods '10P' # PySequenceMethods '2P' # PyBufferProcs - '6P') + '6P' + '1P' # Specializer cache + ) class newstyleclass(object): pass # Separate block for PyDictKeysObject with 8 keys and 5 entries check(newstyleclass, s + calcsize(DICT_KEY_STRUCT_FORMAT) + 64 + 42*calcsize("n2P")) diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-28-15-46-36.bpo-46841.MDQoty.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-28-15-46-36.bpo-46841.MDQoty.rst new file mode 100644 index 0000000000000..97b03debcf092 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-02-28-15-46-36.bpo-46841.MDQoty.rst @@ -0,0 +1 @@ +Use inline cache for :opcode:`BINARY_SUBSCR`. diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h index 11593a9ba3d68..3fef981e42ff9 100644 --- a/Programs/test_frozenmain.h +++ b/Programs/test_frozenmain.h @@ -1,13 +1,14 @@ // Auto-generated by Programs/freeze_test_frozenmain.py unsigned char M_test_frozenmain[] = { 227,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0, - 0,0,0,0,0,115,104,0,0,0,151,0,100,0,100,1, + 0,0,0,0,0,115,120,0,0,0,151,0,100,0,100,1, 108,0,90,0,100,0,100,1,108,1,90,1,2,0,101,2, 100,2,166,1,171,1,1,0,2,0,101,2,100,3,101,0, 106,3,166,2,171,2,1,0,2,0,101,1,106,4,166,0, - 171,0,100,4,25,0,90,5,100,5,68,0,93,16,90,6, - 2,0,101,2,100,6,101,6,155,0,100,7,101,5,101,6, - 25,0,155,0,157,4,166,1,171,1,1,0,113,33,100,1, + 171,0,100,4,25,0,3,0,3,0,3,0,3,0,90,5, + 100,5,68,0,93,20,90,6,2,0,101,2,100,6,101,6, + 155,0,100,7,101,5,101,6,25,0,3,0,3,0,3,0, + 3,0,155,0,157,4,166,1,171,1,1,0,113,37,100,1, 83,0,41,8,233,0,0,0,0,78,122,18,70,114,111,122, 101,110,32,72,101,108,108,111,32,87,111,114,108,100,122,8, 115,121,115,46,97,114,103,118,218,6,99,111,110,102,105,103, @@ -24,14 +25,15 @@ unsigned char M_test_frozenmain[] = { 0,0,250,18,116,101,115,116,95,102,114,111,122,101,110,109, 97,105,110,46,112,121,250,8,60,109,111,100,117,108,101,62, 114,11,0,0,0,1,0,0,0,115,18,0,0,0,2,128, - 8,3,8,1,12,2,16,1,16,1,8,1,30,7,4,249, - 115,20,0,0,0,2,128,8,3,8,1,12,2,16,1,16, - 1,2,7,4,1,2,249,34,7,115,104,0,0,0,0,0, + 8,3,8,1,12,2,16,1,24,1,8,1,38,7,4,249, + 115,20,0,0,0,2,128,8,3,8,1,12,2,16,1,24, + 1,2,7,4,1,2,249,42,7,115,120,0,0,0,0,0, 1,11,1,11,1,11,1,11,1,25,1,25,1,25,1,25, 1,6,1,6,7,27,1,28,1,28,1,28,1,6,1,6, 7,17,19,22,19,27,1,28,1,28,1,28,10,39,10,27, - 10,39,10,41,10,41,42,50,10,51,1,7,12,2,1,42, - 1,42,5,8,5,10,5,10,11,41,21,24,11,41,11,41, - 28,34,35,38,28,39,11,41,11,41,5,42,5,42,5,42, + 10,39,10,41,10,41,42,50,10,51,10,51,10,51,10,51, + 10,51,1,7,12,2,1,42,1,42,5,8,5,10,5,10, + 11,41,21,24,11,41,11,41,28,34,35,38,28,39,28,39, + 28,39,28,39,28,39,11,41,11,41,5,42,5,42,5,42, 5,42,1,42,1,42,114,9,0,0,0, }; diff --git a/Python/ceval.c b/Python/ceval.c index 0f57e7dc94a04..b3673d7d04ab2 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2102,25 +2102,24 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int SET_TOP(res); if (res == NULL) goto error; + JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); DISPATCH(); } TARGET(BINARY_SUBSCR_ADAPTIVE) { - SpecializedCacheEntry *cache = GET_CACHE(); - if (cache->adaptive.counter == 0) { + _PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr; + if (cache->counter == 0) { PyObject *sub = TOP(); PyObject *container = SECOND(); next_instr--; - if (_Py_Specialize_BinarySubscr(container, sub, next_instr, cache) < 0) { + if (_Py_Specialize_BinarySubscr(container, sub, next_instr) < 0) { goto error; } DISPATCH(); } else { STAT_INC(BINARY_SUBSCR, deferred); - cache->adaptive.counter--; - assert(cache->adaptive.original_oparg == 0); - /* No need to set oparg here; it isn't used by BINARY_SUBSCR */ + cache->counter--; JUMP_TO_INSTRUCTION(BINARY_SUBSCR); } } @@ -2146,6 +2145,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int Py_DECREF(sub); SET_TOP(res); Py_DECREF(list); + JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); NOTRACE_DISPATCH(); } @@ -2170,6 +2170,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int Py_DECREF(sub); SET_TOP(res); Py_DECREF(tuple); + JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); NOTRACE_DISPATCH(); } @@ -2188,18 +2189,22 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int Py_DECREF(sub); SET_TOP(res); Py_DECREF(dict); + JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); DISPATCH(); } TARGET(BINARY_SUBSCR_GETITEM) { PyObject *sub = TOP(); PyObject *container = SECOND(); - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAdaptiveEntry *cache0 = &caches[0].adaptive; - _PyObjectCache *cache1 = &caches[-1].obj; - PyFunctionObject *getitem = (PyFunctionObject *)cache1->obj; - DEOPT_IF(Py_TYPE(container)->tp_version_tag != cache0->version, BINARY_SUBSCR); - DEOPT_IF(getitem->func_version != cache0->index, BINARY_SUBSCR); + _PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr; + uint32_t type_version = read32(&cache->type_version); + PyTypeObject *tp = Py_TYPE(container); + DEOPT_IF(tp->tp_version_tag != type_version, BINARY_SUBSCR); + assert(tp->tp_flags & Py_TPFLAGS_HEAPTYPE); + PyObject *cached = ((PyHeapTypeObject *)tp)->_spec_cache.getitem; + assert(PyFunction_Check(cached)); + PyFunctionObject *getitem = (PyFunctionObject *)cached; + DEOPT_IF(getitem->func_version != cache->func_version, BINARY_SUBSCR); PyCodeObject *code = (PyCodeObject *)getitem->func_code; size_t size = code->co_nlocalsplus + code->co_stacksize + FRAME_SPECIALS_SIZE; assert(code->co_argcount == 2); @@ -2218,6 +2223,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int new_frame->localsplus[i] = NULL; } _PyFrame_SetStackPointer(frame, stack_pointer); + frame->f_lasti += INLINE_CACHE_ENTRIES_BINARY_SUBSCR; new_frame->previous = frame; frame = cframe.current_frame = new_frame; CALL_STAT_INC(inlined_py_calls); @@ -5605,7 +5611,7 @@ MISS_WITH_CACHE(PRECALL) MISS_WITH_CACHE(CALL) MISS_WITH_INLINE_CACHE(BINARY_OP) MISS_WITH_INLINE_CACHE(COMPARE_OP) -MISS_WITH_CACHE(BINARY_SUBSCR) +MISS_WITH_INLINE_CACHE(BINARY_SUBSCR) MISS_WITH_INLINE_CACHE(UNPACK_SEQUENCE) MISS_WITH_OPARG_COUNTER(STORE_SUBSCR) diff --git a/Python/specialize.c b/Python/specialize.c index 925edf3f88d5f..5486b5b1f65dc 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -60,7 +60,6 @@ static uint8_t adaptive_opcodes[256] = { static uint8_t cache_requirements[256] = { [LOAD_ATTR] = 1, // _PyAdaptiveEntry [LOAD_METHOD] = 3, /* _PyAdaptiveEntry, _PyAttrCache and _PyObjectCache */ - [BINARY_SUBSCR] = 2, /* _PyAdaptiveEntry, _PyObjectCache */ [STORE_SUBSCR] = 0, [CALL] = 2, /* _PyAdaptiveEntry and _PyObjectCache/_PyCallCache */ [PRECALL] = 2, /* _PyAdaptiveEntry and _PyObjectCache/_PyCallCache */ @@ -385,6 +384,8 @@ optimize(SpecializedCacheOrInstruction *quickened, int len) if (adaptive_opcode) { if (_PyOpcode_InlineCacheEntries[opcode]) { instructions[i] = _Py_MAKECODEUNIT(adaptive_opcode, oparg); + previous_opcode = -1; + i += _PyOpcode_InlineCacheEntries[opcode]; } else if (previous_opcode != EXTENDED_ARG) { int new_oparg = oparg_from_instruction_and_update_offset( @@ -553,6 +554,7 @@ initial_counter_value(void) { #define SPEC_FAIL_SUBSCR_PY_SIMPLE 20 #define SPEC_FAIL_SUBSCR_PY_OTHER 21 #define SPEC_FAIL_SUBSCR_DICT_SUBCLASS_NO_OVERRIDE 22 +#define SPEC_FAIL_SUBSCR_NOT_HEAP_TYPE 23 /* Binary op */ @@ -1335,9 +1337,11 @@ function_kind(PyCodeObject *code) { int _Py_Specialize_BinarySubscr( - PyObject *container, PyObject *sub, _Py_CODEUNIT *instr, SpecializedCacheEntry *cache) + PyObject *container, PyObject *sub, _Py_CODEUNIT *instr) { - _PyAdaptiveEntry *cache0 = &cache->adaptive; + assert(_PyOpcode_InlineCacheEntries[BINARY_SUBSCR] == + INLINE_CACHE_ENTRIES_BINARY_SUBSCR); + _PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)(instr + 1); PyTypeObject *container_type = Py_TYPE(container); if (container_type == &PyList_Type) { if (PyLong_CheckExact(sub)) { @@ -1364,26 +1368,30 @@ _Py_Specialize_BinarySubscr( PyTypeObject *cls = Py_TYPE(container); PyObject *descriptor = _PyType_Lookup(cls, &_Py_ID(__getitem__)); if (descriptor && Py_TYPE(descriptor) == &PyFunction_Type) { + if (!(container_type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_SUBSCR_NOT_HEAP_TYPE); + goto fail; + } PyFunctionObject *func = (PyFunctionObject *)descriptor; - PyCodeObject *code = (PyCodeObject *)func->func_code; - int kind = function_kind(code); + PyCodeObject *fcode = (PyCodeObject *)func->func_code; + int kind = function_kind(fcode); if (kind != SIMPLE_FUNCTION) { SPECIALIZATION_FAIL(BINARY_SUBSCR, kind); goto fail; } - if (code->co_argcount != 2) { + if (fcode->co_argcount != 2) { SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); goto fail; } assert(cls->tp_version_tag != 0); - cache0->version = cls->tp_version_tag; + write32(&cache->type_version, cls->tp_version_tag); int version = _PyFunction_GetVersionForCurrentState(func); if (version == 0 || version != (uint16_t)version) { SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_OUT_OF_VERSIONS); goto fail; } - cache0->index = version; - cache[-1].obj.obj = descriptor; + cache->func_version = version; + ((PyHeapTypeObject *)container_type)->_spec_cache.getitem = descriptor; *instr = _Py_MAKECODEUNIT(BINARY_SUBSCR_GETITEM, _Py_OPARG(*instr)); goto success; } @@ -1392,12 +1400,12 @@ _Py_Specialize_BinarySubscr( fail: STAT_INC(BINARY_SUBSCR, failure); assert(!PyErr_Occurred()); - cache_backoff(cache0); + cache->counter = ADAPTIVE_CACHE_BACKOFF; return 0; success: STAT_INC(BINARY_SUBSCR, success); assert(!PyErr_Occurred()); - cache0->counter = initial_counter_value(); + cache->counter = initial_counter_value(); return 0; } From webhook-mailer at python.org Tue Mar 1 15:56:41 2022 From: webhook-mailer at python.org (ned-deily) Date: Tue, 01 Mar 2022 20:56:41 -0000 Subject: [Python-checkins] bpo-42982: update pbkdf2 example & add another link (GH-30966) (#30968) Message-ID: https://github.com/python/cpython/commit/7dbb2f8eaf07c105f4d2bb0fe61763463e68372d commit: 7dbb2f8eaf07c105f4d2bb0fe61763463e68372d branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ned-deily date: 2022-03-01T15:56:25-05:00 summary: bpo-42982: update pbkdf2 example & add another link (GH-30966) (#30968) Automerge-Triggered-By: GH:gpshead (cherry picked from commit ace0aa2a2793ba4a2b03e56c4ec375c5470edee8) Co-authored-by: Gregory P. Smith files: M Doc/library/hashlib.rst diff --git a/Doc/library/hashlib.rst b/Doc/library/hashlib.rst index 269e8a834d58d..aa24131f8bf44 100644 --- a/Doc/library/hashlib.rst +++ b/Doc/library/hashlib.rst @@ -251,15 +251,17 @@ include a `salt `_. The number of *iterations* should be chosen based on the hash algorithm and computing power. As of 2022, hundreds of thousands of iterations of SHA-256 are suggested. For rationale as to why and how to choose what is best for - your application, read *Appendix A.2.2* of NIST-SP-800-132_. + your application, read *Appendix A.2.2* of NIST-SP-800-132_. The answers + on the `stackexchange pbkdf2 iterations question`_ explain in detail. *dklen* is the length of the derived key. If *dklen* is ``None`` then the digest size of the hash algorithm *hash_name* is used, e.g. 64 for SHA-512. - >>> import hashlib - >>> dk = hashlib.pbkdf2_hmac('sha256', b'password', b'salt', 100000) + >>> from hashlib import pbkdf2_hmac + >>> our_app_iters = 500_000 # Application specific, read above. + >>> dk = pbkdf2_hmac('sha256', b'password', b'bad salt'*2, our_app_iters) >>> dk.hex() - '0394a2ede332c9a13eb82e9b24631604c31df978b4e2f0fbd2c549944f9d79a5' + '15530bba69924174860db778f2c6f8104d3aaf9d26241840c8c4a641c8d000a9' .. versionadded:: 3.4 @@ -733,7 +735,7 @@ Domain Dedication 1.0 Universal: .. _ChaCha: https://cr.yp.to/chacha.html .. _pyblake2: https://pythonhosted.org/pyblake2/ .. _NIST-SP-800-132: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf - +.. _stackexchange pbkdf2 iterations question: https://security.stackexchange.com/questions/3959/recommended-of-iterations-when-using-pbkdf2-sha256/ .. seealso:: From webhook-mailer at python.org Tue Mar 1 16:30:23 2022 From: webhook-mailer at python.org (ericsnowcurrently) Date: Tue, 01 Mar 2022 21:30:23 -0000 Subject: [Python-checkins] bpo-46712: Let generate_global_objects.py Run on Earlier Python Versions (gh-31637) Message-ID: https://github.com/python/cpython/commit/21099fc064c61d59c936a2f6a0db3e07cd5c8de5 commit: 21099fc064c61d59c936a2f6a0db3e07cd5c8de5 branch: main author: Eric Snow committer: ericsnowcurrently date: 2022-03-01T14:29:54-07:00 summary: bpo-46712: Let generate_global_objects.py Run on Earlier Python Versions (gh-31637) https://bugs.python.org/issue46712 files: M Makefile.pre.in M Tools/scripts/generate_global_objects.py diff --git a/Makefile.pre.in b/Makefile.pre.in index 0383853901df1..7b6f54a9ae0a7 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1176,7 +1176,7 @@ regen-importlib: regen-frozen # Global objects .PHONY: regen-global-objects -regen-global-objects: $(srcdir)/Tools/scripts/generate_global_objects.py +regen-global-objects: regen-deepfreeze $(srcdir)/Tools/scripts/generate_global_objects.py $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_global_objects.py ############################################################################ diff --git a/Tools/scripts/generate_global_objects.py b/Tools/scripts/generate_global_objects.py index 639d8fa91c68b..867358cda8919 100644 --- a/Tools/scripts/generate_global_objects.py +++ b/Tools/scripts/generate_global_objects.py @@ -259,7 +259,7 @@ def generate_runtime_init(identifiers, strings): printer.write(after) -def get_identifiers_and_strings() -> tuple[set[str], dict[str, str]]: +def get_identifiers_and_strings() -> 'tuple[set[str], dict[str, str]]': identifiers = set(IDENTIFIERS) strings = dict(STRING_LITERALS) for name, string, *_ in iter_global_strings(): From webhook-mailer at python.org Tue Mar 1 18:09:33 2022 From: webhook-mailer at python.org (methane) Date: Tue, 01 Mar 2022 23:09:33 -0000 Subject: [Python-checkins] bpo-46845: Reduce dict size when all keys are Unicode (GH-31564) Message-ID: https://github.com/python/cpython/commit/9833bb91e4d5c2606421d9ec2085f5c2dfb6f72c commit: 9833bb91e4d5c2606421d9ec2085f5c2dfb6f72c branch: main author: Inada Naoki committer: methane date: 2022-03-02T08:09:28+09:00 summary: bpo-46845: Reduce dict size when all keys are Unicode (GH-31564) files: A Misc/NEWS.d/next/Core and Builtins/2022-02-25-14-57-21.bpo-46845.TUvaMG.rst M Doc/whatsnew/3.11.rst M Include/internal/pycore_dict.h M Lib/test/test_sys.py M Objects/call.c M Objects/dictnotes.txt M Objects/dictobject.c M Python/ceval.c M Tools/gdb/libpython.py diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 8ebe1cb8cc4ca..fbfe02ccfc2c0 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -404,6 +404,11 @@ Optimizations larger *k*). (Contributed by Serhiy Storchaka in :issue:`37295`.) +* Dict don't store hash value when all inserted keys are Unicode objects. + This reduces dict size. For example, ``sys.getsizeof(dict.fromkeys("abcdefg"))`` + becomes 272 bytes from 352 bytes on 64bit platform. + (Contributed by Inada Naoki in :issue:`46845`.) + CPython bytecode changes ======================== diff --git a/Include/internal/pycore_dict.h b/Include/internal/pycore_dict.h index 68f6663dc6445..24d2a711878ce 100644 --- a/Include/internal/pycore_dict.h +++ b/Include/internal/pycore_dict.h @@ -43,6 +43,11 @@ typedef struct { PyObject *me_value; /* This field is only meaningful for combined tables */ } PyDictKeyEntry; +typedef struct { + PyObject *me_key; /* The key must be Unicode and have hash. */ + PyObject *me_value; /* This field is only meaningful for combined tables */ +} PyDictUnicodeEntry; + extern PyDictKeysObject *_PyDict_NewKeysForClass(void); extern PyObject *_PyDict_FromKeys(PyObject *, PyObject *, PyObject *); @@ -70,6 +75,7 @@ extern PyObject *_PyDict_Pop_KnownHash(PyObject *, PyObject *, Py_hash_t, PyObje #define DKIX_EMPTY (-1) #define DKIX_DUMMY (-2) /* Used internally */ #define DKIX_ERROR (-3) +#define DKIX_KEY_CHANGED (-4) /* Used internally */ typedef enum { DICT_KEYS_GENERAL = 0, @@ -114,7 +120,7 @@ struct _dictkeysobject { Dynamically sized, SIZEOF_VOID_P is minimum. */ char dk_indices[]; /* char is required to avoid strict aliasing. */ - /* "PyDictKeyEntry dk_entries[dk_usable];" array follows: + /* "PyDictKeyEntry or PyDictUnicodeEntry dk_entries[USABLE_FRACTION(DK_SIZE(dk))];" array follows: see the DK_ENTRIES() macro */ }; @@ -148,13 +154,20 @@ struct _dictvalues { 2 : sizeof(int32_t)) #endif #define DK_ENTRIES(dk) \ - ((PyDictKeyEntry*)(&((int8_t*)((dk)->dk_indices))[(size_t)1 << (dk)->dk_log2_index_bytes])) + (assert(dk->dk_kind == DICT_KEYS_GENERAL), (PyDictKeyEntry*)(&((int8_t*)((dk)->dk_indices))[(size_t)1 << (dk)->dk_log2_index_bytes])) +#define DK_UNICODE_ENTRIES(dk) \ + (assert(dk->dk_kind != DICT_KEYS_GENERAL), (PyDictUnicodeEntry*)(&((int8_t*)((dk)->dk_indices))[(size_t)1 << (dk)->dk_log2_index_bytes])) +#define DK_IS_UNICODE(dk) ((dk)->dk_kind != DICT_KEYS_GENERAL) extern uint64_t _pydict_global_version; #define DICT_NEXT_VERSION() (++_pydict_global_version) extern PyObject *_PyObject_MakeDictFromInstanceAttributes(PyObject *obj, PyDictValues *values); +extern PyObject *_PyDict_FromItems( + PyObject *const *keys, Py_ssize_t keys_offset, + PyObject *const *values, Py_ssize_t values_offset, + Py_ssize_t length); static inline void _PyDictValues_AddToInsertionOrder(PyDictValues *values, Py_ssize_t ix) diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 70768f56fa9f1..f4deb1763b95f 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -1346,8 +1346,12 @@ def inner(): check({}.__iter__, size('2P')) # empty dict check({}, size('nQ2P')) - # dict - check({"a": 1}, size('nQ2P') + calcsize(DICT_KEY_STRUCT_FORMAT) + 8 + (8*2//3)*calcsize('n2P')) + # dict (string key) + check({"a": 1}, size('nQ2P') + calcsize(DICT_KEY_STRUCT_FORMAT) + 8 + (8*2//3)*calcsize('2P')) + longdict = {str(i): i for i in range(8)} + check(longdict, size('nQ2P') + calcsize(DICT_KEY_STRUCT_FORMAT) + 16 + (16*2//3)*calcsize('2P')) + # dict (non-string key) + check({1: 1}, size('nQ2P') + calcsize(DICT_KEY_STRUCT_FORMAT) + 8 + (8*2//3)*calcsize('n2P')) longdict = {1:1, 2:2, 3:3, 4:4, 5:5, 6:6, 7:7, 8:8} check(longdict, size('nQ2P') + calcsize(DICT_KEY_STRUCT_FORMAT) + 16 + (16*2//3)*calcsize('n2P')) # dictionary-keyview @@ -1506,14 +1510,14 @@ def delx(self): del self.__x ) class newstyleclass(object): pass # Separate block for PyDictKeysObject with 8 keys and 5 entries - check(newstyleclass, s + calcsize(DICT_KEY_STRUCT_FORMAT) + 64 + 42*calcsize("n2P")) + check(newstyleclass, s + calcsize(DICT_KEY_STRUCT_FORMAT) + 64 + 42*calcsize("2P")) # dict with shared keys [newstyleclass() for _ in range(100)] check(newstyleclass().__dict__, size('nQ2P') + self.P) o = newstyleclass() o.a = o.b = o.c = o.d = o.e = o.f = o.g = o.h = 1 # Separate block for PyDictKeysObject with 16 keys and 10 entries - check(newstyleclass, s + calcsize(DICT_KEY_STRUCT_FORMAT) + 64 + 42*calcsize("n2P")) + check(newstyleclass, s + calcsize(DICT_KEY_STRUCT_FORMAT) + 64 + 42*calcsize("2P")) # dict with shared keys check(newstyleclass().__dict__, size('nQ2P') + self.P) # unicode diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-25-14-57-21.bpo-46845.TUvaMG.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-25-14-57-21.bpo-46845.TUvaMG.rst new file mode 100644 index 0000000000000..518a67c4dd527 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-02-25-14-57-21.bpo-46845.TUvaMG.rst @@ -0,0 +1,3 @@ +Reduces dict size by removing hash value from hash table when all inserted +keys are Unicode. For example, ``sys.getsizeof(dict.fromkeys("abcdefg"))`` +becomes 272 bytes from 352 bytes on 64bit platform. diff --git a/Objects/call.c b/Objects/call.c index 9646ad2d77507..cf8fa1eeffe1c 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -934,26 +934,11 @@ PyObject * _PyStack_AsDict(PyObject *const *values, PyObject *kwnames) { Py_ssize_t nkwargs; - PyObject *kwdict; - Py_ssize_t i; assert(kwnames != NULL); nkwargs = PyTuple_GET_SIZE(kwnames); - kwdict = _PyDict_NewPresized(nkwargs); - if (kwdict == NULL) { - return NULL; - } - - for (i = 0; i < nkwargs; i++) { - PyObject *key = PyTuple_GET_ITEM(kwnames, i); - PyObject *value = *values++; - /* If key already exists, replace it with the new value */ - if (PyDict_SetItem(kwdict, key, value)) { - Py_DECREF(kwdict); - return NULL; - } - } - return kwdict; + return _PyDict_FromItems(&PyTuple_GET_ITEM(kwnames, 0), 1, + values, 1, nkwargs); } diff --git a/Objects/dictnotes.txt b/Objects/dictnotes.txt index f89720c9f604e..db6a3cf1d634b 100644 --- a/Objects/dictnotes.txt +++ b/Objects/dictnotes.txt @@ -70,8 +70,8 @@ A values array Tunable Dictionary Parameters ----------------------------- -See comments for PyDict_MINSIZE_SPLIT, PyDict_MINSIZE_COMBINED, -USABLE_FRACTION and GROWTH_RATE in dictobject.c +See comments for PyDict_MINSIZE, USABLE_FRACTION and GROWTH_RATE in +dictobject.c Tune-ups should be measured across a broad range of applications and use cases. A change to any parameter will help in some situations and diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 68b79f2515682..20d7edab93ab1 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -40,8 +40,8 @@ Size of indices is dk_size. Type of each index in indices is vary on dk_size: * int32 for 2**16 <= dk_size <= 2**31 * int64 for 2**32 <= dk_size -dk_entries is array of PyDictKeyEntry. Its size is USABLE_FRACTION(dk_size). -DK_ENTRIES(dk) can be used to get pointer to entries. +dk_entries is array of PyDictKeyEntry when dk_kind == DICT_KEYS_GENERAL or +PyDictUnicodeEntry otherwise. Its length is USABLE_FRACTION(dk_size). NOTE: Since negative value is used for DKIX_EMPTY and DKIX_DUMMY, type of dk_indices entry is signed integer and int16 is used for table which @@ -123,6 +123,8 @@ As a consequence of this, split keys have a maximum size of 16. #include "pycore_pystate.h" // _PyThreadState_GET() #include "stringlib/eq.h" // unicode_eq() +#include + /*[clinic input] class dict "PyDictObject *" "&PyDict_Type" [clinic start generated code]*/ @@ -230,7 +232,7 @@ equally good collision statistics, needed less code & used less memory. */ -static int dictresize(PyDictObject *mp, uint8_t log_newsize); +static int dictresize(PyDictObject *mp, uint8_t log_newsize, int unicode); static PyObject* dict_iter(PyDictObject *dict); @@ -280,6 +282,12 @@ _PyDict_Fini(PyInterpreterState *interp) #endif } +static inline Py_hash_t +unicode_get_hash(PyObject *o) +{ + assert(PyUnicode_CheckExact(o)); + return ((PyASCIIObject*)o)->hash; +} /* Print summary info about the state of the optimized allocator */ void @@ -467,7 +475,7 @@ struct { #define Py_EMPTY_KEYS &empty_keys_struct /* Uncomment to check the dict content in _PyDict_CheckConsistency() */ -/* #define DEBUG_PYDICT */ +// #define DEBUG_PYDICT #ifdef DEBUG_PYDICT # define ASSERT_CONSISTENT(op) assert(_PyDict_CheckConsistency((PyObject *)(op), 1)) @@ -483,6 +491,24 @@ get_index_from_order(PyDictObject *mp, Py_ssize_t i) return ((char *)mp->ma_values)[-3-i]; } +#ifdef DEBUG_PYDICT +static void +dump_entries(PyDictKeysObject *dk) +{ + int kind = dk->dk_kind; + for (Py_ssize_t i = 0; i < dk->dk_nentries; i++) { + if (DK_IS_UNICODE(dk)) { + PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(dk)[i]; + printf("key=%p value=%p\n", ep->me_key, ep->me_value); + } + else { + PyDictKeyEntry *ep = &DK_ENTRIES(dk)[i]; + printf("key=%p hash=%lx value=%p\n", ep->me_key, ep->me_hash, ep->me_value); + } + } +} +#endif + int _PyDict_CheckConsistency(PyObject *op, int check_content) { @@ -504,41 +530,56 @@ _PyDict_CheckConsistency(PyObject *op, int check_content) if (!splitted) { /* combined table */ + CHECK(keys->dk_kind != DICT_KEYS_SPLIT); CHECK(keys->dk_refcnt == 1); } else { + CHECK(keys->dk_kind == DICT_KEYS_SPLIT); CHECK(mp->ma_used <= SHARED_KEYS_MAX_SIZE); } if (check_content) { - PyDictKeyEntry *entries = DK_ENTRIES(keys); - for (Py_ssize_t i=0; i < DK_SIZE(keys); i++) { Py_ssize_t ix = dictkeys_get_index(keys, i); CHECK(DKIX_DUMMY <= ix && ix <= usable); } - for (Py_ssize_t i=0; i < usable; i++) { - PyDictKeyEntry *entry = &entries[i]; - PyObject *key = entry->me_key; + if (keys->dk_kind == DICT_KEYS_GENERAL) { + PyDictKeyEntry *entries = DK_ENTRIES(keys); + for (Py_ssize_t i=0; i < usable; i++) { + PyDictKeyEntry *entry = &entries[i]; + PyObject *key = entry->me_key; - if (key != NULL) { - if (PyUnicode_CheckExact(key)) { - Py_hash_t hash = ((PyASCIIObject *)key)->hash; - CHECK(hash != -1); - CHECK(entry->me_hash == hash); - } - else { + if (key != NULL) { /* test_dict fails if PyObject_Hash() is called again */ CHECK(entry->me_hash != -1); - } - if (!splitted) { CHECK(entry->me_value != NULL); + + if (PyUnicode_CheckExact(key)) { + Py_hash_t hash = unicode_get_hash(key); + CHECK(entry->me_hash == hash); + } } } + } + else { + PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(keys); + for (Py_ssize_t i=0; i < usable; i++) { + PyDictUnicodeEntry *entry = &entries[i]; + PyObject *key = entry->me_key; + + if (key != NULL) { + CHECK(PyUnicode_CheckExact(key)); + Py_hash_t hash = unicode_get_hash(key); + CHECK(hash != -1); + if (!splitted) { + CHECK(entry->me_value != NULL); + } + } - if (splitted) { - CHECK(entry->me_value == NULL); + if (splitted) { + CHECK(entry->me_value == NULL); + } } } @@ -561,11 +602,12 @@ _PyDict_CheckConsistency(PyObject *op, int check_content) static PyDictKeysObject* -new_keys_object(uint8_t log2_size) +new_keys_object(uint8_t log2_size, bool unicode) { PyDictKeysObject *dk; Py_ssize_t usable; int log2_bytes; + size_t entry_size = unicode ? sizeof(PyDictUnicodeEntry) : sizeof(PyDictKeyEntry); assert(log2_size >= PyDict_LOG_MINSIZE); @@ -591,7 +633,7 @@ new_keys_object(uint8_t log2_size) // new_keys_object() must not be called after _PyDict_Fini() assert(state->keys_numfree != -1); #endif - if (log2_size == PyDict_LOG_MINSIZE && state->keys_numfree > 0) { + if (log2_size == PyDict_LOG_MINSIZE && unicode && state->keys_numfree > 0) { dk = state->keys_free_list[--state->keys_numfree]; } else @@ -599,7 +641,7 @@ new_keys_object(uint8_t log2_size) { dk = PyObject_Malloc(sizeof(PyDictKeysObject) + ((size_t)1 << log2_bytes) - + sizeof(PyDictKeyEntry) * usable); + + entry_size * usable); if (dk == NULL) { PyErr_NoMemory(); return NULL; @@ -611,23 +653,34 @@ new_keys_object(uint8_t log2_size) dk->dk_refcnt = 1; dk->dk_log2_size = log2_size; dk->dk_log2_index_bytes = log2_bytes; - dk->dk_kind = DICT_KEYS_UNICODE; + dk->dk_kind = unicode ? DICT_KEYS_UNICODE : DICT_KEYS_GENERAL; dk->dk_nentries = 0; dk->dk_usable = usable; dk->dk_version = 0; memset(&dk->dk_indices[0], 0xff, ((size_t)1 << log2_bytes)); - memset(DK_ENTRIES(dk), 0, sizeof(PyDictKeyEntry) * usable); + memset(&dk->dk_indices[(size_t)1 << log2_bytes], 0, entry_size * usable); return dk; } static void free_keys_object(PyDictKeysObject *keys) { - PyDictKeyEntry *entries = DK_ENTRIES(keys); - Py_ssize_t i, n; - for (i = 0, n = keys->dk_nentries; i < n; i++) { - Py_XDECREF(entries[i].me_key); - Py_XDECREF(entries[i].me_value); + assert(keys != Py_EMPTY_KEYS); + if (DK_IS_UNICODE(keys)) { + PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(keys); + Py_ssize_t i, n; + for (i = 0, n = keys->dk_nentries; i < n; i++) { + Py_XDECREF(entries[i].me_key); + Py_XDECREF(entries[i].me_value); + } + } + else { + PyDictKeyEntry *entries = DK_ENTRIES(keys); + Py_ssize_t i, n; + for (i = 0, n = keys->dk_nentries; i < n; i++) { + Py_XDECREF(entries[i].me_key); + Py_XDECREF(entries[i].me_value); + } } #if PyDict_MAXFREELIST > 0 struct _Py_dict_state *state = get_dict_state(); @@ -635,7 +688,8 @@ free_keys_object(PyDictKeysObject *keys) // free_keys_object() must not be called after _PyDict_Fini() assert(state->keys_numfree != -1); #endif - if (DK_LOG_SIZE(keys) == PyDict_LOG_MINSIZE && state->keys_numfree < PyDict_MAXFREELIST) { + if (DK_LOG_SIZE(keys) == PyDict_LOG_MINSIZE && state->keys_numfree < PyDict_MAXFREELIST + && DK_IS_UNICODE(keys)) { state->keys_free_list[state->keys_numfree++] = keys; return; } @@ -751,15 +805,30 @@ clone_combined_dict_keys(PyDictObject *orig) /* After copying key/value pairs, we need to incref all keys and values and they are about to be co-owned by a new dict object. */ - PyDictKeyEntry *ep0 = DK_ENTRIES(keys); + PyObject **pkey, **pvalue; + size_t offs; + if (DK_IS_UNICODE(orig->ma_keys)) { + PyDictUnicodeEntry *ep0 = DK_UNICODE_ENTRIES(keys); + pkey = &ep0->me_key; + pvalue = &ep0->me_value; + offs = sizeof(PyDictUnicodeEntry) / sizeof(PyObject*); + } + else { + PyDictKeyEntry *ep0 = DK_ENTRIES(keys); + pkey = &ep0->me_key; + pvalue = &ep0->me_value; + offs = sizeof(PyDictKeyEntry) / sizeof(PyObject*); + } + Py_ssize_t n = keys->dk_nentries; for (Py_ssize_t i = 0; i < n; i++) { - PyDictKeyEntry *entry = &ep0[i]; - PyObject *value = entry->me_value; + PyObject *value = *pvalue; if (value != NULL) { Py_INCREF(value); - Py_INCREF(entry->me_key); + Py_INCREF(*pkey); } + pvalue += offs; + pkey += offs; } /* Since we copied the keys table we now have an extra reference @@ -801,10 +870,11 @@ lookdict_index(PyDictKeysObject *k, Py_hash_t hash, Py_ssize_t index) Py_UNREACHABLE(); } +// Search non-Unicode key from Unicode table static Py_ssize_t -dictkeys_stringlookup(PyDictKeysObject* dk, PyObject *key, Py_hash_t hash) +unicodekeys_lookup_generic(PyDictObject *mp, PyDictKeysObject* dk, PyObject *key, Py_hash_t hash) { - PyDictKeyEntry *ep0 = DK_ENTRIES(dk); + PyDictUnicodeEntry *ep0 = DK_UNICODE_ENTRIES(dk); size_t mask = DK_MASK(dk); size_t perturb = hash; size_t i = (size_t)hash & mask; @@ -812,11 +882,57 @@ dictkeys_stringlookup(PyDictKeysObject* dk, PyObject *key, Py_hash_t hash) for (;;) { ix = dictkeys_get_index(dk, i); if (ix >= 0) { - PyDictKeyEntry *ep = &ep0[ix]; + PyDictUnicodeEntry *ep = &ep0[ix]; + assert(ep->me_key != NULL); + assert(PyUnicode_CheckExact(ep->me_key)); + if (ep->me_key == key) { + return ix; + } + if (unicode_get_hash(ep->me_key) == hash) { + PyObject *startkey = ep->me_key; + Py_INCREF(startkey); + int cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); + Py_DECREF(startkey); + if (cmp < 0) { + return DKIX_ERROR; + } + if (dk == mp->ma_keys && ep->me_key == startkey) { + if (cmp > 0) { + return ix; + } + } + else { + /* The dict was mutated, restart */ + return DKIX_KEY_CHANGED; + } + } + } + else if (ix == DKIX_EMPTY) { + return DKIX_EMPTY; + } + perturb >>= PERTURB_SHIFT; + i = mask & (i*5 + perturb + 1); + } + Py_UNREACHABLE(); +} + +// Search Unicode key from Unicode table. +static Py_ssize_t _Py_HOT_FUNCTION +unicodekeys_lookup_unicode(PyDictKeysObject* dk, PyObject *key, Py_hash_t hash) +{ + PyDictUnicodeEntry *ep0 = DK_UNICODE_ENTRIES(dk); + size_t mask = DK_MASK(dk); + size_t perturb = hash; + size_t i = (size_t)hash & mask; + Py_ssize_t ix; + for (;;) { + ix = dictkeys_get_index(dk, i); + if (ix >= 0) { + PyDictUnicodeEntry *ep = &ep0[ix]; assert(ep->me_key != NULL); assert(PyUnicode_CheckExact(ep->me_key)); if (ep->me_key == key || - (ep->me_hash == hash && unicode_eq(ep->me_key, key))) { + (unicode_get_hash(ep->me_key) == hash && unicode_eq(ep->me_key, key))) { return ix; } } @@ -827,11 +943,11 @@ dictkeys_stringlookup(PyDictKeysObject* dk, PyObject *key, Py_hash_t hash) i = mask & (i*5 + perturb + 1); ix = dictkeys_get_index(dk, i); if (ix >= 0) { - PyDictKeyEntry *ep = &ep0[ix]; + PyDictUnicodeEntry *ep = &ep0[ix]; assert(ep->me_key != NULL); assert(PyUnicode_CheckExact(ep->me_key)); if (ep->me_key == key || - (ep->me_hash == hash && unicode_eq(ep->me_key, key))) { + (unicode_get_hash(ep->me_key) == hash && unicode_eq(ep->me_key, key))) { return ix; } } @@ -844,6 +960,51 @@ dictkeys_stringlookup(PyDictKeysObject* dk, PyObject *key, Py_hash_t hash) Py_UNREACHABLE(); } +// Search key from Generic table. +static Py_ssize_t +dictkeys_generic_lookup(PyDictObject *mp, PyDictKeysObject* dk, PyObject *key, Py_hash_t hash) +{ + PyDictKeyEntry *ep0 = DK_ENTRIES(dk); + size_t mask = DK_MASK(dk); + size_t perturb = hash; + size_t i = (size_t)hash & mask; + Py_ssize_t ix; + for (;;) { + ix = dictkeys_get_index(dk, i); + if (ix >= 0) { + PyDictKeyEntry *ep = &ep0[ix]; + assert(ep->me_key != NULL); + if (ep->me_key == key) { + return ix; + } + if (ep->me_hash == hash) { + PyObject *startkey = ep->me_key; + Py_INCREF(startkey); + int cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); + Py_DECREF(startkey); + if (cmp < 0) { + return DKIX_ERROR; + } + if (dk == mp->ma_keys && ep->me_key == startkey) { + if (cmp > 0) { + return ix; + } + } + else { + /* The dict was mutated, restart */ + return DKIX_KEY_CHANGED; + } + } + } + else if (ix == DKIX_EMPTY) { + return DKIX_EMPTY; + } + perturb >>= PERTURB_SHIFT; + i = mask & (i*5 + perturb + 1); + } + Py_UNREACHABLE(); +} + /* Lookup a string in a (all unicode) dict keys. * Returns DKIX_ERROR if key is not a string, * or if the dict keys is not all strings. @@ -857,7 +1018,7 @@ _PyDictKeys_StringLookup(PyDictKeysObject* dk, PyObject *key) if (!PyUnicode_CheckExact(key) || kind == DICT_KEYS_GENERAL) { return DKIX_ERROR; } - Py_hash_t hash = ((PyASCIIObject *)key)->hash; + Py_hash_t hash = unicode_get_hash(key); if (hash == -1) { hash = PyUnicode_Type.tp_hash(key); if (hash == -1) { @@ -865,7 +1026,7 @@ _PyDictKeys_StringLookup(PyDictKeysObject* dk, PyObject *key) return DKIX_ERROR; } } - return dictkeys_stringlookup(dk, key, hash); + return unicodekeys_lookup_unicode(dk, key, hash); } /* @@ -883,74 +1044,53 @@ _Py_dict_lookup() is general-purpose, and may return DKIX_ERROR if (and only if) comparison raises an exception. When the key isn't found a DKIX_EMPTY is returned. */ -Py_ssize_t _Py_HOT_FUNCTION +Py_ssize_t _Py_dict_lookup(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject **value_addr) { PyDictKeysObject *dk; + DictKeysKind kind; + Py_ssize_t ix; + start: dk = mp->ma_keys; - DictKeysKind kind = dk->dk_kind; - if (PyUnicode_CheckExact(key) && kind != DICT_KEYS_GENERAL) { - Py_ssize_t ix = dictkeys_stringlookup(dk, key, hash); - if (ix == DKIX_EMPTY) { - *value_addr = NULL; - } - else if (kind == DICT_KEYS_SPLIT) { - *value_addr = mp->ma_values->values[ix]; + kind = dk->dk_kind; + + if (kind != DICT_KEYS_GENERAL) { + if (PyUnicode_CheckExact(key)) { + ix = unicodekeys_lookup_unicode(dk, key, hash); } else { - *value_addr = DK_ENTRIES(dk)[ix].me_value; - } - return ix; - } - PyDictKeyEntry *ep0 = DK_ENTRIES(dk); - size_t mask = DK_MASK(dk); - size_t perturb = hash; - size_t i = (size_t)hash & mask; - Py_ssize_t ix; - for (;;) { - ix = dictkeys_get_index(dk, i); - if (ix == DKIX_EMPTY) { - *value_addr = NULL; - return ix; + ix = unicodekeys_lookup_generic(mp, dk, key, hash); + if (ix == DKIX_KEY_CHANGED) { + goto start; + } } + if (ix >= 0) { - PyDictKeyEntry *ep = &ep0[ix]; - assert(ep->me_key != NULL); - if (ep->me_key == key) { - goto found; + if (kind == DICT_KEYS_SPLIT) { + *value_addr = mp->ma_values->values[ix]; } - if (ep->me_hash == hash) { - PyObject *startkey = ep->me_key; - Py_INCREF(startkey); - int cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); - Py_DECREF(startkey); - if (cmp < 0) { - *value_addr = NULL; - return DKIX_ERROR; - } - if (dk == mp->ma_keys && ep->me_key == startkey) { - if (cmp > 0) { - goto found; - } - } - else { - /* The dict was mutated, restart */ - goto start; - } + else { + *value_addr = DK_UNICODE_ENTRIES(dk)[ix].me_value; } } - perturb >>= PERTURB_SHIFT; - i = (i*5 + perturb + 1) & mask; - } - Py_UNREACHABLE(); -found: - if (dk->dk_kind == DICT_KEYS_SPLIT) { - *value_addr = mp->ma_values->values[ix]; + else { + *value_addr = NULL; + } } else { - *value_addr = ep0[ix].me_value; + ix = dictkeys_generic_lookup(mp, dk, key, hash); + if (ix == DKIX_KEY_CHANGED) { + goto start; + } + if (ix >= 0) { + *value_addr = DK_ENTRIES(dk)[ix].me_value; + } + else { + *value_addr = NULL; + } } + return ix; } @@ -985,31 +1125,40 @@ _PyDict_MaybeUntrack(PyObject *op) PyDictObject *mp; PyObject *value; Py_ssize_t i, numentries; - PyDictKeyEntry *ep0; if (!PyDict_CheckExact(op) || !_PyObject_GC_IS_TRACKED(op)) return; mp = (PyDictObject *) op; - ep0 = DK_ENTRIES(mp->ma_keys); numentries = mp->ma_keys->dk_nentries; if (_PyDict_HasSplitTable(mp)) { for (i = 0; i < numentries; i++) { if ((value = mp->ma_values->values[i]) == NULL) continue; if (_PyObject_GC_MAY_BE_TRACKED(value)) { - assert(!_PyObject_GC_MAY_BE_TRACKED(ep0[i].me_key)); return; } } } else { - for (i = 0; i < numentries; i++) { - if ((value = ep0[i].me_value) == NULL) - continue; - if (_PyObject_GC_MAY_BE_TRACKED(value) || - _PyObject_GC_MAY_BE_TRACKED(ep0[i].me_key)) - return; + if (DK_IS_UNICODE(mp->ma_keys)) { + PyDictUnicodeEntry *ep0 = DK_UNICODE_ENTRIES(mp->ma_keys); + for (i = 0; i < numentries; i++) { + if ((value = ep0[i].me_value) == NULL) + continue; + if (_PyObject_GC_MAY_BE_TRACKED(value)) + return; + } + } + else { + PyDictKeyEntry *ep0 = DK_ENTRIES(mp->ma_keys); + for (i = 0; i < numentries; i++) { + if ((value = ep0[i].me_value) == NULL) + continue; + if (_PyObject_GC_MAY_BE_TRACKED(value) || + _PyObject_GC_MAY_BE_TRACKED(ep0[i].me_key)) + return; + } } } _PyObject_GC_UNTRACK(op); @@ -1036,16 +1185,16 @@ find_empty_slot(PyDictKeysObject *keys, Py_hash_t hash) } static int -insertion_resize(PyDictObject *mp) +insertion_resize(PyDictObject *mp, int unicode) { - return dictresize(mp, calculate_log2_keysize(GROWTH_RATE(mp))); + return dictresize(mp, calculate_log2_keysize(GROWTH_RATE(mp)), unicode); } static Py_ssize_t insert_into_dictkeys(PyDictKeysObject *keys, PyObject *name) { assert(PyUnicode_CheckExact(name)); - Py_hash_t hash = ((PyASCIIObject *)name)->hash; + Py_hash_t hash = unicode_get_hash(name); if (hash == -1) { hash = PyUnicode_Type.tp_hash(name); if (hash == -1) { @@ -1053,7 +1202,7 @@ insert_into_dictkeys(PyDictKeysObject *keys, PyObject *name) return DKIX_EMPTY; } } - Py_ssize_t ix = dictkeys_stringlookup(keys, name, hash); + Py_ssize_t ix = unicodekeys_lookup_unicode(keys, name, hash); if (ix == DKIX_EMPTY) { if (keys->dk_usable <= 0) { return DKIX_EMPTY; @@ -1063,11 +1212,10 @@ insert_into_dictkeys(PyDictKeysObject *keys, PyObject *name) keys->dk_version = 0; Py_ssize_t hashpos = find_empty_slot(keys, hash); ix = keys->dk_nentries; - PyDictKeyEntry *ep = &DK_ENTRIES(keys)[ix]; + PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(keys)[ix]; dictkeys_set_index(keys, hashpos, ix); assert(ep->me_key == NULL); ep->me_key = name; - ep->me_hash = hash; keys->dk_usable--; keys->dk_nentries++; } @@ -1085,11 +1233,11 @@ static int insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) { PyObject *old_value; - PyDictKeyEntry *ep; - if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) { - if (insertion_resize(mp) < 0) + if (DK_IS_UNICODE(mp->ma_keys) && !PyUnicode_CheckExact(key)) { + if (insertion_resize(mp, 0) < 0) goto Fail; + assert(mp->ma_keys->dk_kind == DICT_KEYS_GENERAL); } Py_ssize_t ix = _Py_dict_lookup(mp, key, hash, &old_value); @@ -1104,24 +1252,32 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) assert(old_value == NULL); if (mp->ma_keys->dk_usable <= 0) { /* Need to resize. */ - if (insertion_resize(mp) < 0) + if (insertion_resize(mp, 1) < 0) goto Fail; } - if (!PyUnicode_CheckExact(key) && mp->ma_keys->dk_kind != DICT_KEYS_GENERAL) { - mp->ma_keys->dk_kind = DICT_KEYS_GENERAL; - } + Py_ssize_t hashpos = find_empty_slot(mp->ma_keys, hash); - ep = &DK_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries]; dictkeys_set_index(mp->ma_keys, hashpos, mp->ma_keys->dk_nentries); - ep->me_key = key; - ep->me_hash = hash; - if (mp->ma_values) { - Py_ssize_t index = mp->ma_keys->dk_nentries; - _PyDictValues_AddToInsertionOrder(mp->ma_values, index); - assert (mp->ma_values->values[index] == NULL); - mp->ma_values->values[index] = value; + + if (DK_IS_UNICODE(mp->ma_keys)) { + PyDictUnicodeEntry *ep; + ep = &DK_UNICODE_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries]; + ep->me_key = key; + if (mp->ma_values) { + Py_ssize_t index = mp->ma_keys->dk_nentries; + _PyDictValues_AddToInsertionOrder(mp->ma_values, index); + assert (mp->ma_values->values[index] == NULL); + mp->ma_values->values[index] = value; + } + else { + ep->me_value = value; + } } else { + PyDictKeyEntry *ep; + ep = &DK_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries]; + ep->me_key = key; + ep->me_hash = hash; ep->me_value = value; } mp->ma_used++; @@ -1143,7 +1299,12 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) } else { assert(old_value != NULL); - DK_ENTRIES(mp->ma_keys)[ix].me_value = value; + if (DK_IS_UNICODE(mp->ma_keys)) { + DK_UNICODE_ENTRIES(mp->ma_keys)[ix].me_value = value; + } + else { + DK_ENTRIES(mp->ma_keys)[ix].me_value = value; + } } mp->ma_version_tag = DICT_NEXT_VERSION(); } @@ -1166,15 +1327,13 @@ insert_to_emptydict(PyDictObject *mp, PyObject *key, Py_hash_t hash, { assert(mp->ma_keys == Py_EMPTY_KEYS); - PyDictKeysObject *newkeys = new_keys_object(PyDict_LOG_MINSIZE); + int unicode = PyUnicode_CheckExact(key); + PyDictKeysObject *newkeys = new_keys_object(PyDict_LOG_MINSIZE, unicode); if (newkeys == NULL) { Py_DECREF(key); Py_DECREF(value); return -1; } - if (!PyUnicode_CheckExact(key)) { - newkeys->dk_kind = DICT_KEYS_GENERAL; - } dictkeys_decref(Py_EMPTY_KEYS); mp->ma_keys = newkeys; mp->ma_values = NULL; @@ -1182,11 +1341,18 @@ insert_to_emptydict(PyDictObject *mp, PyObject *key, Py_hash_t hash, MAINTAIN_TRACKING(mp, key, value); size_t hashpos = (size_t)hash & (PyDict_MINSIZE-1); - PyDictKeyEntry *ep = DK_ENTRIES(mp->ma_keys); dictkeys_set_index(mp->ma_keys, hashpos, 0); - ep->me_key = key; - ep->me_hash = hash; - ep->me_value = value; + if (unicode) { + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(mp->ma_keys); + ep->me_key = key; + ep->me_value = value; + } + else { + PyDictKeyEntry *ep = DK_ENTRIES(mp->ma_keys); + ep->me_key = key; + ep->me_hash = hash; + ep->me_value = value; + } mp->ma_used++; mp->ma_version_tag = DICT_NEXT_VERSION(); mp->ma_keys->dk_usable--; @@ -1198,7 +1364,7 @@ insert_to_emptydict(PyDictObject *mp, PyObject *key, Py_hash_t hash, Internal routine used by dictresize() to build a hashtable of entries. */ static void -build_indices(PyDictKeysObject *keys, PyDictKeyEntry *ep, Py_ssize_t n) +build_indices_generic(PyDictKeysObject *keys, PyDictKeyEntry *ep, Py_ssize_t n) { size_t mask = DK_MASK(keys); for (Py_ssize_t ix = 0; ix != n; ix++, ep++) { @@ -1212,6 +1378,22 @@ build_indices(PyDictKeysObject *keys, PyDictKeyEntry *ep, Py_ssize_t n) } } +static void +build_indices_unicode(PyDictKeysObject *keys, PyDictUnicodeEntry *ep, Py_ssize_t n) +{ + size_t mask = DK_MASK(keys); + for (Py_ssize_t ix = 0; ix != n; ix++, ep++) { + Py_hash_t hash = unicode_get_hash(ep->me_key); + assert(hash != -1); + size_t i = hash & mask; + for (size_t perturb = hash; dictkeys_get_index(keys, i) != DKIX_EMPTY;) { + perturb >>= PERTURB_SHIFT; + i = mask & (i*5 + perturb + 1); + } + dictkeys_set_index(keys, i, ix); + } +} + /* Restructure the table by allocating a new table and reinserting all items again. When entries have been deleted, the new table may @@ -1220,14 +1402,17 @@ If a table is split (its keys and hashes are shared, its values are not), then the values are temporarily copied into the table, it is resized as a combined table, then the me_value slots in the old table are NULLed out. After resizing a table is always combined. + +This function supports: + - Unicode split -> Unicode combined or Generic + - Unicode combined -> Unicode combined or Generic + - Generic -> Generic */ static int -dictresize(PyDictObject *mp, uint8_t log2_newsize) +dictresize(PyDictObject *mp, uint8_t log2_newsize, int unicode) { - Py_ssize_t numentries; PyDictKeysObject *oldkeys; PyDictValues *oldvalues; - PyDictKeyEntry *oldentries, *newentries; if (log2_newsize >= SIZEOF_SIZE_T*8) { PyErr_NoMemory(); @@ -1236,6 +1421,11 @@ dictresize(PyDictObject *mp, uint8_t log2_newsize) assert(log2_newsize >= PyDict_LOG_MINSIZE); oldkeys = mp->ma_keys; + oldvalues = mp->ma_values; + + if (!DK_IS_UNICODE(oldkeys)) { + unicode = 0; + } /* NOTE: Current odict checks mp->ma_keys to detect resize happen. * So we can't reuse oldkeys even if oldkeys->dk_size == newsize. @@ -1243,32 +1433,48 @@ dictresize(PyDictObject *mp, uint8_t log2_newsize) */ /* Allocate a new table. */ - mp->ma_keys = new_keys_object(log2_newsize); + mp->ma_keys = new_keys_object(log2_newsize, unicode); if (mp->ma_keys == NULL) { mp->ma_keys = oldkeys; return -1; } // New table must be large enough. assert(mp->ma_keys->dk_usable >= mp->ma_used); - if (oldkeys->dk_kind == DICT_KEYS_GENERAL) - mp->ma_keys->dk_kind = DICT_KEYS_GENERAL; - numentries = mp->ma_used; - oldentries = DK_ENTRIES(oldkeys); - newentries = DK_ENTRIES(mp->ma_keys); - oldvalues = mp->ma_values; + Py_ssize_t numentries = mp->ma_used; + if (oldvalues != NULL) { + PyDictUnicodeEntry *oldentries = DK_UNICODE_ENTRIES(oldkeys); /* Convert split table into new combined table. * We must incref keys; we can transfer values. */ - for (Py_ssize_t i = 0; i < numentries; i++) { - int index = get_index_from_order(mp, i); - PyDictKeyEntry *ep = &oldentries[index]; - assert(oldvalues->values[index] != NULL); - Py_INCREF(ep->me_key); - newentries[i].me_key = ep->me_key; - newentries[i].me_hash = ep->me_hash; - newentries[i].me_value = oldvalues->values[index]; + if (mp->ma_keys->dk_kind == DICT_KEYS_GENERAL) { + // split -> generic + PyDictKeyEntry *newentries = DK_ENTRIES(mp->ma_keys); + + for (Py_ssize_t i = 0; i < numentries; i++) { + int index = get_index_from_order(mp, i); + PyDictUnicodeEntry *ep = &oldentries[index]; + assert(oldvalues->values[index] != NULL); + Py_INCREF(ep->me_key); + newentries[i].me_key = ep->me_key; + newentries[i].me_hash = unicode_get_hash(ep->me_key); + newentries[i].me_value = oldvalues->values[index]; + } + build_indices_generic(mp->ma_keys, newentries, numentries); + } + else { // split -> combined unicode + PyDictUnicodeEntry *newentries = DK_UNICODE_ENTRIES(mp->ma_keys); + + for (Py_ssize_t i = 0; i < numentries; i++) { + int index = get_index_from_order(mp, i); + PyDictUnicodeEntry *ep = &oldentries[index]; + assert(oldvalues->values[index] != NULL); + Py_INCREF(ep->me_key); + newentries[i].me_key = ep->me_key; + newentries[i].me_value = oldvalues->values[index]; + } + build_indices_unicode(mp->ma_keys, newentries, numentries); } dictkeys_decref(oldkeys); mp->ma_values = NULL; @@ -1276,16 +1482,54 @@ dictresize(PyDictObject *mp, uint8_t log2_newsize) free_values(oldvalues); } } - else { // combined table. - if (oldkeys->dk_nentries == numentries) { - memcpy(newentries, oldentries, numentries * sizeof(PyDictKeyEntry)); + else { // oldkeys is combined. + if (oldkeys->dk_kind == DICT_KEYS_GENERAL) { + // generic -> generic + assert(mp->ma_keys->dk_kind == DICT_KEYS_GENERAL); + PyDictKeyEntry *oldentries = DK_ENTRIES(oldkeys); + PyDictKeyEntry *newentries = DK_ENTRIES(mp->ma_keys); + if (oldkeys->dk_nentries == numentries) { + memcpy(newentries, oldentries, numentries * sizeof(PyDictKeyEntry)); + } + else { + PyDictKeyEntry *ep = oldentries; + for (Py_ssize_t i = 0; i < numentries; i++) { + while (ep->me_value == NULL) + ep++; + newentries[i] = *ep++; + } + } + build_indices_generic(mp->ma_keys, newentries, numentries); } - else { - PyDictKeyEntry *ep = oldentries; - for (Py_ssize_t i = 0; i < numentries; i++) { - while (ep->me_value == NULL) + else { // oldkeys is combined unicode + PyDictUnicodeEntry *oldentries = DK_UNICODE_ENTRIES(oldkeys); + if (unicode) { // combined unicode -> combined unicode + PyDictUnicodeEntry *newentries = DK_UNICODE_ENTRIES(mp->ma_keys); + if (oldkeys->dk_nentries == numentries && mp->ma_keys->dk_kind == DICT_KEYS_UNICODE) { + memcpy(newentries, oldentries, numentries * sizeof(PyDictUnicodeEntry)); + } + else { + PyDictUnicodeEntry *ep = oldentries; + for (Py_ssize_t i = 0; i < numentries; i++) { + while (ep->me_value == NULL) + ep++; + newentries[i] = *ep++; + } + } + build_indices_unicode(mp->ma_keys, newentries, numentries); + } + else { // combined unicode -> generic + PyDictKeyEntry *newentries = DK_ENTRIES(mp->ma_keys); + PyDictUnicodeEntry *ep = oldentries; + for (Py_ssize_t i = 0; i < numentries; i++) { + while (ep->me_value == NULL) + ep++; + newentries[i].me_key = ep->me_key; + newentries[i].me_hash = unicode_get_hash(ep->me_key); + newentries[i].me_value = ep->me_value; ep++; - newentries[i] = *ep++; + } + build_indices_generic(mp->ma_keys, newentries, numentries); } } @@ -1301,6 +1545,7 @@ dictresize(PyDictObject *mp, uint8_t log2_newsize) assert(state->keys_numfree != -1); #endif if (DK_LOG_SIZE(oldkeys) == PyDict_LOG_MINSIZE && + DK_IS_UNICODE(oldkeys) && state->keys_numfree < PyDict_MAXFREELIST) { state->keys_free_list[state->keys_numfree++] = oldkeys; @@ -1312,15 +1557,14 @@ dictresize(PyDictObject *mp, uint8_t log2_newsize) } } - build_indices(mp->ma_keys, newentries, numentries); mp->ma_keys->dk_usable -= numentries; mp->ma_keys->dk_nentries = numentries; ASSERT_CONSISTENT(mp); return 0; } -PyObject * -_PyDict_NewPresized(Py_ssize_t minused) +static PyObject * +dict_new_presized(Py_ssize_t minused, bool unicode) { const uint8_t log2_max_presize = 17; const Py_ssize_t max_presize = ((Py_ssize_t)1) << log2_max_presize; @@ -1341,12 +1585,56 @@ _PyDict_NewPresized(Py_ssize_t minused) log2_newsize = estimate_log2_keysize(minused); } - new_keys = new_keys_object(log2_newsize); + new_keys = new_keys_object(log2_newsize, unicode); if (new_keys == NULL) return NULL; return new_dict(new_keys, NULL, 0, 0); } +PyObject * +_PyDict_NewPresized(Py_ssize_t minused) +{ + return dict_new_presized(minused, false); +} + +PyObject * +_PyDict_FromItems(PyObject *const *keys, Py_ssize_t keys_offset, + PyObject *const *values, Py_ssize_t values_offset, + Py_ssize_t length) +{ + bool unicode = true; + PyObject *const *ks = keys; + + for (Py_ssize_t i = 0; i < length; i++) { + if (!PyUnicode_CheckExact(*ks)) { + unicode = false; + break; + } + ks += keys_offset; + } + + PyObject *dict = dict_new_presized(length, unicode); + if (dict == NULL) { + return NULL; + } + + ks = keys; + PyObject *const *vs = values; + + for (Py_ssize_t i = 0; i < length; i++) { + PyObject *key = *ks; + PyObject *value = *vs; + if (PyDict_SetItem(dict, key, value) < 0) { + Py_DECREF(dict); + return NULL; + } + ks += keys_offset; + vs += values_offset; + } + + return dict; +} + /* Note that, for historical reasons, PyDict_GetItem() suppresses all errors * that may occur (originally dicts supported only string keys, and exceptions * weren't possible). So, while the original intent was that a NULL return @@ -1366,9 +1654,7 @@ PyDict_GetItem(PyObject *op, PyObject *key) PyDictObject *mp = (PyDictObject *)op; Py_hash_t hash; - if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) - { + if (!PyUnicode_CheckExact(key) || (hash = unicode_get_hash(key)) == -1) { hash = PyObject_Hash(key); if (hash == -1) { PyErr_Clear(); @@ -1410,23 +1696,41 @@ _PyDict_GetItemHint(PyDictObject *mp, PyObject *key, if (hint >= 0 && hint < mp->ma_keys->dk_nentries) { PyObject *res = NULL; - PyDictKeyEntry *ep = DK_ENTRIES(mp->ma_keys) + (size_t)hint; - if (ep->me_key == key) { - if (mp->ma_keys->dk_kind == DICT_KEYS_SPLIT) { - assert(mp->ma_values != NULL); - res = mp->ma_values->values[(size_t)hint]; - } - else { - res = ep->me_value; + if (DK_IS_UNICODE(mp->ma_keys)) { + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(mp->ma_keys) + (size_t)hint; + if (ep->me_key == key) { + if (mp->ma_keys->dk_kind == DICT_KEYS_SPLIT) { + assert(mp->ma_values != NULL); + res = mp->ma_values->values[(size_t)hint]; + } + else { + res = ep->me_value; + } + if (res != NULL) { + *value = res; + return hint; + } } - if (res != NULL) { - *value = res; - return hint; + } + else { + PyDictKeyEntry *ep = DK_ENTRIES(mp->ma_keys) + (size_t)hint; + if (ep->me_key == key) { + if (mp->ma_keys->dk_kind == DICT_KEYS_SPLIT) { + assert(mp->ma_values != NULL); + res = mp->ma_values->values[(size_t)hint]; + } + else { + res = ep->me_value; + } + if (res != NULL) { + *value = res; + return hint; + } } } } - Py_hash_t hash = ((PyASCIIObject *) key)->hash; + Py_hash_t hash = unicode_get_hash(key); if (hash == -1) { hash = PyObject_Hash(key); if (hash == -1) { @@ -1474,8 +1778,7 @@ PyDict_GetItemWithError(PyObject *op, PyObject *key) PyErr_BadInternalCall(); return NULL; } - if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) + if (!PyUnicode_CheckExact(key) || (hash = unicode_get_hash(key)) == -1) { hash = PyObject_Hash(key); if (hash == -1) { @@ -1506,7 +1809,7 @@ _PyDict_GetItemIdWithError(PyObject *dp, _Py_Identifier *key) kv = _PyUnicode_FromId(key); /* borrowed */ if (kv == NULL) return NULL; - Py_hash_t hash = ((PyASCIIObject *) kv)->hash; + Py_hash_t hash = unicode_get_hash(kv); assert (hash != -1); /* interned strings have their hash value initialised */ return _PyDict_GetItem_KnownHash(dp, kv, hash); } @@ -1652,14 +1955,12 @@ delitem_common(PyDictObject *mp, Py_hash_t hash, Py_ssize_t ix, PyObject *old_value) { PyObject *old_key; - PyDictKeyEntry *ep; Py_ssize_t hashpos = lookdict_index(mp->ma_keys, hash, ix); assert(hashpos >= 0); mp->ma_used--; mp->ma_version_tag = DICT_NEXT_VERSION(); - ep = &DK_ENTRIES(mp->ma_keys)[ix]; if (mp->ma_values) { assert(old_value == mp->ma_values->values[ix]); mp->ma_values->values[ix] = NULL; @@ -1671,9 +1972,19 @@ delitem_common(PyDictObject *mp, Py_hash_t hash, Py_ssize_t ix, else { mp->ma_keys->dk_version = 0; dictkeys_set_index(mp->ma_keys, hashpos, DKIX_DUMMY); - old_key = ep->me_key; - ep->me_key = NULL; - ep->me_value = NULL; + if (DK_IS_UNICODE(mp->ma_keys)) { + PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(mp->ma_keys)[ix]; + old_key = ep->me_key; + ep->me_key = NULL; + ep->me_value = NULL; + } + else { + PyDictKeyEntry *ep = &DK_ENTRIES(mp->ma_keys)[ix]; + old_key = ep->me_key; + ep->me_key = NULL; + ep->me_value = NULL; + ep->me_hash = 0; + } Py_DECREF(old_key); } Py_DECREF(old_value); @@ -1814,8 +2125,8 @@ _PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, { Py_ssize_t i; PyDictObject *mp; - PyDictKeyEntry *entry_ptr; - PyObject *value; + PyObject *key, *value; + Py_hash_t hash; if (!PyDict_Check(op)) return 0; @@ -1826,30 +2137,48 @@ _PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, if (i < 0 || i >= mp->ma_used) return 0; int index = get_index_from_order(mp, i); - entry_ptr = &DK_ENTRIES(mp->ma_keys)[index]; value = mp->ma_values->values[index]; + + key = DK_UNICODE_ENTRIES(mp->ma_keys)[index].me_key; + hash = unicode_get_hash(key); assert(value != NULL); } else { Py_ssize_t n = mp->ma_keys->dk_nentries; if (i < 0 || i >= n) return 0; - entry_ptr = &DK_ENTRIES(mp->ma_keys)[i]; - while (i < n && entry_ptr->me_value == NULL) { - entry_ptr++; - i++; + if (DK_IS_UNICODE(mp->ma_keys)) { + PyDictUnicodeEntry *entry_ptr = &DK_UNICODE_ENTRIES(mp->ma_keys)[i]; + while (i < n && entry_ptr->me_value == NULL) { + entry_ptr++; + i++; + } + if (i >= n) + return 0; + key = entry_ptr->me_key; + hash = unicode_get_hash(entry_ptr->me_key); + value = entry_ptr->me_value; + } + else { + PyDictKeyEntry *entry_ptr = &DK_ENTRIES(mp->ma_keys)[i]; + while (i < n && entry_ptr->me_value == NULL) { + entry_ptr++; + i++; + } + if (i >= n) + return 0; + key = entry_ptr->me_key; + hash = entry_ptr->me_hash; + value = entry_ptr->me_value; } - if (i >= n) - return 0; - value = entry_ptr->me_value; } *ppos = i+1; if (pkey) - *pkey = entry_ptr->me_key; - if (phash) - *phash = entry_ptr->me_hash; + *pkey = key; if (pvalue) *pvalue = value; + if (phash) + *phash = hash; return 1; } @@ -1958,7 +2287,8 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) PyObject *key; Py_hash_t hash; - if (dictresize(mp, estimate_log2_keysize(PyDict_GET_SIZE(iterable)))) { + int unicode = DK_IS_UNICODE(((PyDictObject*)iterable)->ma_keys); + if (dictresize(mp, estimate_log2_keysize(PyDict_GET_SIZE(iterable)), unicode)) { Py_DECREF(d); return NULL; } @@ -1979,7 +2309,7 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) PyObject *key; Py_hash_t hash; - if (dictresize(mp, estimate_log2_keysize(PySet_GET_SIZE(iterable)))) { + if (dictresize(mp, estimate_log2_keysize(PySet_GET_SIZE(iterable)), 0)) { Py_DECREF(d); return NULL; } @@ -2217,10 +2547,7 @@ static PyObject * dict_keys(PyDictObject *mp) { PyObject *v; - Py_ssize_t i, j; - PyDictKeyEntry *ep; - Py_ssize_t n, offset; - PyObject **value_ptr; + Py_ssize_t n; again: n = mp->ma_used; @@ -2234,23 +2561,15 @@ dict_keys(PyDictObject *mp) Py_DECREF(v); goto again; } - ep = DK_ENTRIES(mp->ma_keys); - if (mp->ma_values) { - value_ptr = mp->ma_values->values; - offset = sizeof(PyObject *); - } - else { - value_ptr = &ep[0].me_value; - offset = sizeof(PyDictKeyEntry); - } - for (i = 0, j = 0; j < n; i++) { - if (*value_ptr != NULL) { - PyObject *key = ep[i].me_key; - Py_INCREF(key); - PyList_SET_ITEM(v, j, key); - j++; - } - value_ptr = (PyObject **)(((char *)value_ptr) + offset); + + /* Nothing we do below makes any function calls. */ + Py_ssize_t j = 0, pos = 0; + PyObject *key; + while (_PyDict_Next((PyObject*)mp, &pos, &key, NULL, NULL)) { + assert(j < n); + Py_INCREF(key); + PyList_SET_ITEM(v, j, key); + j++; } assert(j == n); return v; @@ -2260,10 +2579,7 @@ static PyObject * dict_values(PyDictObject *mp) { PyObject *v; - Py_ssize_t i, j; - PyDictKeyEntry *ep; - Py_ssize_t n, offset; - PyObject **value_ptr; + Py_ssize_t n; again: n = mp->ma_used; @@ -2277,23 +2593,15 @@ dict_values(PyDictObject *mp) Py_DECREF(v); goto again; } - ep = DK_ENTRIES(mp->ma_keys); - if (mp->ma_values) { - value_ptr = mp->ma_values->values; - offset = sizeof(PyObject *); - } - else { - value_ptr = &ep[0].me_value; - offset = sizeof(PyDictKeyEntry); - } - for (i = 0, j = 0; j < n; i++) { - PyObject *value = *value_ptr; - value_ptr = (PyObject **)(((char *)value_ptr) + offset); - if (value != NULL) { - Py_INCREF(value); - PyList_SET_ITEM(v, j, value); - j++; - } + + /* Nothing we do below makes any function calls. */ + Py_ssize_t j = 0, pos = 0; + PyObject *value; + while (_PyDict_Next((PyObject*)mp, &pos, NULL, &value, NULL)) { + assert(j < n); + Py_INCREF(value); + PyList_SET_ITEM(v, j, value); + j++; } assert(j == n); return v; @@ -2303,11 +2611,8 @@ static PyObject * dict_items(PyDictObject *mp) { PyObject *v; - Py_ssize_t i, j, n; - Py_ssize_t offset; - PyObject *item, *key; - PyDictKeyEntry *ep; - PyObject **value_ptr; + Py_ssize_t i, n; + PyObject *item; /* Preallocate the list of tuples, to avoid allocations during * the loop over the items, which could trigger GC, which @@ -2333,28 +2638,18 @@ dict_items(PyDictObject *mp) Py_DECREF(v); goto again; } + /* Nothing we do below makes any function calls. */ - ep = DK_ENTRIES(mp->ma_keys); - if (mp->ma_values) { - value_ptr = mp->ma_values->values; - offset = sizeof(PyObject *); - } - else { - value_ptr = &ep[0].me_value; - offset = sizeof(PyDictKeyEntry); - } - for (i = 0, j = 0; j < n; i++) { - PyObject *value = *value_ptr; - value_ptr = (PyObject **)(((char *)value_ptr) + offset); - if (value != NULL) { - key = ep[i].me_key; - item = PyList_GET_ITEM(v, j); - Py_INCREF(key); - PyTuple_SET_ITEM(item, 0, key); - Py_INCREF(value); - PyTuple_SET_ITEM(item, 1, value); - j++; - } + Py_ssize_t j = 0, pos = 0; + PyObject *key, *value; + while (_PyDict_Next((PyObject*)mp, &pos, &key, &value, NULL)) { + assert(j < n); + PyObject *item = PyList_GET_ITEM(v, j); + Py_INCREF(key); + PyTuple_SET_ITEM(item, 0, key); + Py_INCREF(value); + PyTuple_SET_ITEM(item, 1, value); + j++; } assert(j == n); return v; @@ -2528,8 +2823,6 @@ static int dict_merge(PyObject *a, PyObject *b, int override) { PyDictObject *mp, *other; - Py_ssize_t i, n; - PyDictKeyEntry *entry, *ep0; assert(0 <= override && override <= 2); @@ -2592,58 +2885,52 @@ dict_merge(PyObject *a, PyObject *b, int override) * that there will be no (or few) overlapping keys. */ if (USABLE_FRACTION(DK_SIZE(mp->ma_keys)) < other->ma_used) { - if (dictresize(mp, estimate_log2_keysize(mp->ma_used + other->ma_used))) { + int unicode = DK_IS_UNICODE(other->ma_keys); + if (dictresize(mp, estimate_log2_keysize(mp->ma_used + other->ma_used), unicode)) { return -1; } } - ep0 = DK_ENTRIES(other->ma_keys); - for (i = 0, n = other->ma_keys->dk_nentries; i < n; i++) { - PyObject *key, *value; - Py_hash_t hash; - entry = &ep0[i]; - key = entry->me_key; - hash = entry->me_hash; - if (other->ma_values) - value = other->ma_values->values[i]; - else - value = entry->me_value; - if (value != NULL) { - int err = 0; + Py_ssize_t orig_size = other->ma_keys->dk_nentries; + Py_ssize_t pos = 0; + Py_hash_t hash; + PyObject *key, *value; + + while (_PyDict_Next((PyObject*)other, &pos, &key, &value, &hash)) { + int err = 0; + Py_INCREF(key); + Py_INCREF(value); + if (override == 1) { Py_INCREF(key); Py_INCREF(value); - if (override == 1) { + err = insertdict(mp, key, hash, value); + } + else { + err = _PyDict_Contains_KnownHash(a, key, hash); + if (err == 0) { Py_INCREF(key); Py_INCREF(value); err = insertdict(mp, key, hash, value); } - else { - err = _PyDict_Contains_KnownHash(a, key, hash); - if (err == 0) { - Py_INCREF(key); - Py_INCREF(value); - err = insertdict(mp, key, hash, value); - } - else if (err > 0) { - if (override != 0) { - _PyErr_SetKeyError(key); - Py_DECREF(value); - Py_DECREF(key); - return -1; - } - err = 0; + else if (err > 0) { + if (override != 0) { + _PyErr_SetKeyError(key); + Py_DECREF(value); + Py_DECREF(key); + return -1; } + err = 0; } - Py_DECREF(value); - Py_DECREF(key); - if (err != 0) - return -1; + } + Py_DECREF(value); + Py_DECREF(key); + if (err != 0) + return -1; - if (n != other->ma_keys->dk_nentries) { - PyErr_SetString(PyExc_RuntimeError, - "dict mutated during update"); - return -1; - } + if (orig_size != other->ma_keys->dk_nentries) { + PyErr_SetString(PyExc_RuntimeError, + "dict mutated during update"); + return -1; } } } @@ -2880,23 +3167,36 @@ dict_equal(PyDictObject *a, PyDictObject *b) return 0; /* Same # of entries -- check all of 'em. Exit early on any diff. */ for (i = 0; i < a->ma_keys->dk_nentries; i++) { - PyDictKeyEntry *ep = &DK_ENTRIES(a->ma_keys)[i]; - PyObject *aval; - if (a->ma_values) - aval = a->ma_values->values[i]; - else + PyObject *key, *aval; + Py_hash_t hash; + if (DK_IS_UNICODE(a->ma_keys)) { + PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(a->ma_keys)[i]; + key = ep->me_key; + if (key == NULL) { + continue; + } + hash = unicode_get_hash(key); + if (a->ma_values) + aval = a->ma_values->values[i]; + else + aval = ep->me_value; + } + else { + PyDictKeyEntry *ep = &DK_ENTRIES(a->ma_keys)[i]; + key = ep->me_key; aval = ep->me_value; + hash = ep->me_hash; + } if (aval != NULL) { int cmp; PyObject *bval; - PyObject *key = ep->me_key; /* temporarily bump aval's refcount to ensure it stays alive until we're done with it */ Py_INCREF(aval); /* ditto for key */ Py_INCREF(key); /* reuse the known hash value */ - _Py_dict_lookup(b, key, ep->me_hash, &bval); + _Py_dict_lookup(b, key, hash, &bval); if (bval == NULL) { Py_DECREF(key); Py_DECREF(aval); @@ -3033,9 +3333,10 @@ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj) return defaultobj; } - if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) { - if (insertion_resize(mp) < 0) + if (!PyUnicode_CheckExact(key) && DK_IS_UNICODE(mp->ma_keys)) { + if (insertion_resize(mp, 0) < 0) { return NULL; + } } Py_ssize_t ix = _Py_dict_lookup(mp, key, hash, &value); @@ -3044,35 +3345,38 @@ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj) if (ix == DKIX_EMPTY) { mp->ma_keys->dk_version = 0; - PyDictKeyEntry *ep, *ep0; value = defaultobj; if (mp->ma_keys->dk_usable <= 0) { - if (insertion_resize(mp) < 0) { + if (insertion_resize(mp, 1) < 0) { return NULL; } } - if (!PyUnicode_CheckExact(key) && mp->ma_keys->dk_kind != DICT_KEYS_GENERAL) { - mp->ma_keys->dk_kind = DICT_KEYS_GENERAL; - } Py_ssize_t hashpos = find_empty_slot(mp->ma_keys, hash); - ep0 = DK_ENTRIES(mp->ma_keys); - ep = &ep0[mp->ma_keys->dk_nentries]; dictkeys_set_index(mp->ma_keys, hashpos, mp->ma_keys->dk_nentries); - Py_INCREF(key); - Py_INCREF(value); - MAINTAIN_TRACKING(mp, key, value); - ep->me_key = key; - ep->me_hash = hash; - if (_PyDict_HasSplitTable(mp)) { - Py_ssize_t index = (int)mp->ma_keys->dk_nentries; - assert(index < SHARED_KEYS_MAX_SIZE); - assert(mp->ma_values->values[index] == NULL); - mp->ma_values->values[index] = value; - _PyDictValues_AddToInsertionOrder(mp->ma_values, index); + if (DK_IS_UNICODE(mp->ma_keys)) { + assert(PyUnicode_CheckExact(key)); + PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries]; + ep->me_key = key; + if (_PyDict_HasSplitTable(mp)) { + Py_ssize_t index = (int)mp->ma_keys->dk_nentries; + assert(index < SHARED_KEYS_MAX_SIZE); + assert(mp->ma_values->values[index] == NULL); + mp->ma_values->values[index] = value; + _PyDictValues_AddToInsertionOrder(mp->ma_values, index); + } + else { + ep->me_value = value; + } } else { + PyDictKeyEntry *ep = &DK_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries]; + ep->me_key = key; + ep->me_hash = hash; ep->me_value = value; } + Py_INCREF(key); + Py_INCREF(value); + MAINTAIN_TRACKING(mp, key, value); mp->ma_used++; mp->ma_version_tag = DICT_NEXT_VERSION(); mp->ma_keys->dk_usable--; @@ -3160,7 +3464,6 @@ dict_popitem_impl(PyDictObject *self) /*[clinic end generated code: output=e65fcb04420d230d input=1c38a49f21f64941]*/ { Py_ssize_t i, j; - PyDictKeyEntry *ep0, *ep; PyObject *res; /* Allocate the result tuple before checking the size. Believe it @@ -3182,7 +3485,7 @@ dict_popitem_impl(PyDictObject *self) } /* Convert split table to combined table */ if (self->ma_keys->dk_kind == DICT_KEYS_SPLIT) { - if (dictresize(self, DK_LOG_SIZE(self->ma_keys))) { + if (dictresize(self, DK_LOG_SIZE(self->ma_keys), 1)) { Py_DECREF(res); return NULL; } @@ -3190,23 +3493,45 @@ dict_popitem_impl(PyDictObject *self) self->ma_keys->dk_version = 0; /* Pop last item */ - ep0 = DK_ENTRIES(self->ma_keys); - i = self->ma_keys->dk_nentries - 1; - while (i >= 0 && ep0[i].me_value == NULL) { - i--; + PyObject *key, *value; + Py_hash_t hash; + if (DK_IS_UNICODE(self->ma_keys)) { + PyDictUnicodeEntry *ep0 = DK_UNICODE_ENTRIES(self->ma_keys); + i = self->ma_keys->dk_nentries - 1; + while (i >= 0 && ep0[i].me_value == NULL) { + i--; + } + assert(i >= 0); + + key = ep0[i].me_key; + hash = unicode_get_hash(key); + value = ep0[i].me_value; + ep0[i].me_key = NULL; + ep0[i].me_value = NULL; } - assert(i >= 0); + else { + PyDictKeyEntry *ep0 = DK_ENTRIES(self->ma_keys); + i = self->ma_keys->dk_nentries - 1; + while (i >= 0 && ep0[i].me_value == NULL) { + i--; + } + assert(i >= 0); - ep = &ep0[i]; - j = lookdict_index(self->ma_keys, ep->me_hash, i); + key = ep0[i].me_key; + hash = ep0[i].me_hash; + value = ep0[i].me_value; + ep0[i].me_key = NULL; + ep0[i].me_hash = -1; + ep0[i].me_value = NULL; + } + + j = lookdict_index(self->ma_keys, hash, i); assert(j >= 0); assert(dictkeys_get_index(self->ma_keys, j) == i); dictkeys_set_index(self->ma_keys, j, DKIX_DUMMY); - PyTuple_SET_ITEM(res, 0, ep->me_key); - PyTuple_SET_ITEM(res, 1, ep->me_value); - ep->me_key = NULL; - ep->me_value = NULL; + PyTuple_SET_ITEM(res, 0, key); + PyTuple_SET_ITEM(res, 1, value); /* We can't dk_usable++ since there is DKIX_DUMMY in indices */ self->ma_keys->dk_nentries = i; self->ma_used--; @@ -3220,29 +3545,30 @@ dict_traverse(PyObject *op, visitproc visit, void *arg) { PyDictObject *mp = (PyDictObject *)op; PyDictKeysObject *keys = mp->ma_keys; - PyDictKeyEntry *entries = DK_ENTRIES(keys); Py_ssize_t i, n = keys->dk_nentries; - if (keys->dk_kind == DICT_KEYS_GENERAL) { - for (i = 0; i < n; i++) { - if (entries[i].me_value != NULL) { - Py_VISIT(entries[i].me_value); - Py_VISIT(entries[i].me_key); - } - } - } - else { + if (DK_IS_UNICODE(keys)) { if (mp->ma_values != NULL) { for (i = 0; i < n; i++) { Py_VISIT(mp->ma_values->values[i]); } } else { + PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(keys); for (i = 0; i < n; i++) { Py_VISIT(entries[i].me_value); } } } + else { + PyDictKeyEntry *entries = DK_ENTRIES(keys); + for (i = 0; i < n; i++) { + if (entries[i].me_value != NULL) { + Py_VISIT(entries[i].me_value); + Py_VISIT(entries[i].me_key); + } + } + } return 0; } @@ -3258,9 +3584,7 @@ static PyObject *dictiter_new(PyDictObject *, PyTypeObject *); Py_ssize_t _PyDict_SizeOf(PyDictObject *mp) { - Py_ssize_t size, res; - - size = DK_SIZE(mp->ma_keys); + Py_ssize_t res; res = _PyObject_SIZE(Py_TYPE(mp)); if (mp->ma_values) { @@ -3269,10 +3593,7 @@ _PyDict_SizeOf(PyDictObject *mp) /* If the dictionary is split, the keys portion is accounted-for in the type object. */ if (mp->ma_keys->dk_refcnt == 1) { - Py_ssize_t usable = USABLE_FRACTION(size); - res += (sizeof(PyDictKeysObject) - + DK_IXSIZE(mp->ma_keys) * size - + sizeof(PyDictKeyEntry) * usable); + res += _PyDict_KeysSize(mp->ma_keys); } return res; } @@ -3280,9 +3601,11 @@ _PyDict_SizeOf(PyDictObject *mp) Py_ssize_t _PyDict_KeysSize(PyDictKeysObject *keys) { + size_t es = keys->dk_kind == DICT_KEYS_GENERAL + ? sizeof(PyDictKeyEntry) : sizeof(PyDictUnicodeEntry); return (sizeof(PyDictKeysObject) - + DK_IXSIZE(keys) * DK_SIZE(keys) - + USABLE_FRACTION(DK_SIZE(keys)) * sizeof(PyDictKeyEntry)); + + ((size_t)1 << keys->dk_log2_index_bytes) + + USABLE_FRACTION(DK_SIZE(keys)) * es); } static PyObject * @@ -3754,19 +4077,31 @@ dictiter_iternextkey(dictiterobject *di) if (i >= d->ma_used) goto fail; int index = get_index_from_order(d, i); - key = DK_ENTRIES(k)[index].me_key; + key = DK_UNICODE_ENTRIES(k)[index].me_key; assert(d->ma_values->values[index] != NULL); } else { Py_ssize_t n = k->dk_nentries; - PyDictKeyEntry *entry_ptr = &DK_ENTRIES(k)[i]; - while (i < n && entry_ptr->me_value == NULL) { - entry_ptr++; - i++; + if (DK_IS_UNICODE(k)) { + PyDictUnicodeEntry *entry_ptr = &DK_UNICODE_ENTRIES(k)[i]; + while (i < n && entry_ptr->me_value == NULL) { + entry_ptr++; + i++; + } + if (i >= n) + goto fail; + key = entry_ptr->me_key; + } + else { + PyDictKeyEntry *entry_ptr = &DK_ENTRIES(k)[i]; + while (i < n && entry_ptr->me_value == NULL) { + entry_ptr++; + i++; + } + if (i >= n) + goto fail; + key = entry_ptr->me_key; } - if (i >= n) - goto fail; - key = entry_ptr->me_key; } // We found an element (key), but did not expect it if (di->len == 0) { @@ -3847,14 +4182,26 @@ dictiter_iternextvalue(dictiterobject *di) } else { Py_ssize_t n = d->ma_keys->dk_nentries; - PyDictKeyEntry *entry_ptr = &DK_ENTRIES(d->ma_keys)[i]; - while (i < n && entry_ptr->me_value == NULL) { - entry_ptr++; - i++; + if (DK_IS_UNICODE(d->ma_keys)) { + PyDictUnicodeEntry *entry_ptr = &DK_UNICODE_ENTRIES(d->ma_keys)[i]; + while (i < n && entry_ptr->me_value == NULL) { + entry_ptr++; + i++; + } + if (i >= n) + goto fail; + value = entry_ptr->me_value; + } + else { + PyDictKeyEntry *entry_ptr = &DK_ENTRIES(d->ma_keys)[i]; + while (i < n && entry_ptr->me_value == NULL) { + entry_ptr++; + i++; + } + if (i >= n) + goto fail; + value = entry_ptr->me_value; } - if (i >= n) - goto fail; - value = entry_ptr->me_value; } // We found an element, but did not expect it if (di->len == 0) { @@ -3930,21 +4277,34 @@ dictiter_iternextitem(dictiterobject *di) if (i >= d->ma_used) goto fail; int index = get_index_from_order(d, i); - key = DK_ENTRIES(d->ma_keys)[index].me_key; + key = DK_UNICODE_ENTRIES(d->ma_keys)[index].me_key; value = d->ma_values->values[index]; assert(value != NULL); } else { Py_ssize_t n = d->ma_keys->dk_nentries; - PyDictKeyEntry *entry_ptr = &DK_ENTRIES(d->ma_keys)[i]; - while (i < n && entry_ptr->me_value == NULL) { - entry_ptr++; - i++; + if (DK_IS_UNICODE(d->ma_keys)) { + PyDictUnicodeEntry *entry_ptr = &DK_UNICODE_ENTRIES(d->ma_keys)[i]; + while (i < n && entry_ptr->me_value == NULL) { + entry_ptr++; + i++; + } + if (i >= n) + goto fail; + key = entry_ptr->me_key; + value = entry_ptr->me_value; + } + else { + PyDictKeyEntry *entry_ptr = &DK_ENTRIES(d->ma_keys)[i]; + while (i < n && entry_ptr->me_value == NULL) { + entry_ptr++; + i++; + } + if (i >= n) + goto fail; + key = entry_ptr->me_key; + value = entry_ptr->me_value; } - if (i >= n) - goto fail; - key = entry_ptr->me_key; - value = entry_ptr->me_value; } // We found an element, but did not expect it if (di->len == 0) { @@ -4048,20 +4408,33 @@ dictreviter_iternext(dictiterobject *di) } if (d->ma_values) { int index = get_index_from_order(d, i); - key = DK_ENTRIES(k)[index].me_key; + key = DK_UNICODE_ENTRIES(k)[index].me_key; value = d->ma_values->values[index]; assert (value != NULL); } else { - PyDictKeyEntry *entry_ptr = &DK_ENTRIES(k)[i]; - while (entry_ptr->me_value == NULL) { - if (--i < 0) { - goto fail; + if (DK_IS_UNICODE(k)) { + PyDictUnicodeEntry *entry_ptr = &DK_UNICODE_ENTRIES(k)[i]; + while (entry_ptr->me_value == NULL) { + if (--i < 0) { + goto fail; + } + entry_ptr--; + } + key = entry_ptr->me_key; + value = entry_ptr->me_value; + } + else { + PyDictKeyEntry *entry_ptr = &DK_ENTRIES(k)[i]; + while (entry_ptr->me_value == NULL) { + if (--i < 0) { + goto fail; + } + entry_ptr--; } - entry_ptr--; + key = entry_ptr->me_key; + value = entry_ptr->me_value; } - key = entry_ptr->me_key; - value = entry_ptr->me_value; } di->di_pos = i-1; di->len--; @@ -4970,7 +5343,7 @@ dictvalues_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored)) PyDictKeysObject * _PyDict_NewKeysForClass(void) { - PyDictKeysObject *keys = new_keys_object(NEXT_LOG2_SHARED_KEYS_MAX_SIZE); + PyDictKeysObject *keys = new_keys_object(NEXT_LOG2_SHARED_KEYS_MAX_SIZE, 1); if (keys == NULL) { PyErr_Clear(); } diff --git a/Python/ceval.c b/Python/ceval.c index b3673d7d04ab2..e47e0521ea941 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1457,7 +1457,7 @@ eval_frame_handle_pending(PyThreadState *tstate) LOAD_##attr_or_method); \ assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE); \ assert(cache0->index < dict->ma_keys->dk_nentries); \ - PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + cache0->index; \ + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + cache0->index; \ res = ep->me_value; \ DEOPT_IF(res == NULL, LOAD_##attr_or_method); \ STAT_INC(LOAD_##attr_or_method, hit); \ @@ -1595,6 +1595,19 @@ is_method(PyObject **stack_pointer, int args) { return PEEK(args+2) != NULL; } +static PyObject* +dictkeys_get_value_by_index(PyDictKeysObject *dk, int index) +{ + if (DK_IS_UNICODE(dk)) { + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dk) + index; + return ep->me_value; + } + else { + PyDictKeyEntry *ep = DK_ENTRIES(dk) + index; + return ep->me_value; + } +} + #define KWNAMES_LEN() \ (call_shape.kwnames == NULL ? 0 : ((int)PyTuple_GET_SIZE(call_shape.kwnames))) @@ -3030,8 +3043,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; uint32_t version = read32(&cache->module_keys_version); DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); - PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + cache->index; - PyObject *res = ep->me_value; + PyObject *res = dictkeys_get_value_by_index(dict->ma_keys, cache->index); DEOPT_IF(res == NULL, LOAD_GLOBAL); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); STAT_INC(LOAD_GLOBAL, hit); @@ -3051,8 +3063,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int uint16_t bltn_version = cache->builtin_keys_version; DEOPT_IF(mdict->ma_keys->dk_version != mod_version, LOAD_GLOBAL); DEOPT_IF(bdict->ma_keys->dk_version != bltn_version, LOAD_GLOBAL); - PyDictKeyEntry *ep = DK_ENTRIES(bdict->ma_keys) + cache->index; - PyObject *res = ep->me_value; + PyObject *res = dictkeys_get_value_by_index(bdict->ma_keys, cache->index); DEOPT_IF(res == NULL, LOAD_GLOBAL); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); STAT_INC(LOAD_GLOBAL, hit); @@ -3272,20 +3283,12 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } TARGET(BUILD_MAP) { - Py_ssize_t i; - PyObject *map = _PyDict_NewPresized((Py_ssize_t)oparg); + PyObject *map = _PyDict_FromItems( + &PEEK(2*oparg), 2, + &PEEK(2*oparg - 1), 2, + oparg); if (map == NULL) goto error; - for (i = oparg; i > 0; i--) { - int err; - PyObject *key = PEEK(2*i); - PyObject *value = PEEK(2*i - 1); - err = PyDict_SetItem(map, key, value); - if (err != 0) { - Py_DECREF(map); - goto error; - } - } while (oparg--) { Py_DECREF(POP()); @@ -3351,7 +3354,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } TARGET(BUILD_CONST_KEY_MAP) { - Py_ssize_t i; PyObject *map; PyObject *keys = TOP(); if (!PyTuple_CheckExact(keys) || @@ -3360,20 +3362,12 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int "bad BUILD_CONST_KEY_MAP keys argument"); goto error; } - map = _PyDict_NewPresized((Py_ssize_t)oparg); + map = _PyDict_FromItems( + &PyTuple_GET_ITEM(keys, 0), 1, + &PEEK(oparg + 1), 1, oparg); if (map == NULL) { goto error; } - for (i = oparg; i > 0; i--) { - int err; - PyObject *key = PyTuple_GET_ITEM(keys, oparg - i); - PyObject *value = PEEK(i + 1); - err = PyDict_SetItem(map, key, value); - if (err != 0) { - Py_DECREF(map); - goto error; - } - } Py_DECREF(POP()); while (oparg--) { @@ -3538,9 +3532,16 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int PyObject *name = GETITEM(names, cache0->original_oparg); uint16_t hint = cache0->index; DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, LOAD_ATTR); - PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint; - DEOPT_IF(ep->me_key != name, LOAD_ATTR); - res = ep->me_value; + if (DK_IS_UNICODE(dict->ma_keys)) { + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint; + DEOPT_IF(ep->me_key != name, LOAD_ATTR); + res = ep->me_value; + } + else { + PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint; + DEOPT_IF(ep->me_key != name, LOAD_ATTR); + res = ep->me_value; + } DEOPT_IF(res == NULL, LOAD_ATTR); STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); @@ -3630,15 +3631,27 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int PyObject *name = GETITEM(names, cache0->original_oparg); uint16_t hint = cache0->index; DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, STORE_ATTR); - PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint; - DEOPT_IF(ep->me_key != name, STORE_ATTR); - PyObject *old_value = ep->me_value; - DEOPT_IF(old_value == NULL, STORE_ATTR); - STAT_INC(STORE_ATTR, hit); - STACK_SHRINK(1); - PyObject *value = POP(); - ep->me_value = value; + PyObject *value, *old_value; + if (DK_IS_UNICODE(dict->ma_keys)) { + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint; + DEOPT_IF(ep->me_key != name, STORE_ATTR); + old_value = ep->me_value; + DEOPT_IF(old_value == NULL, STORE_ATTR); + STACK_SHRINK(1); + value = POP(); + ep->me_value = value; + } + else { + PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint; + DEOPT_IF(ep->me_key != name, STORE_ATTR); + old_value = ep->me_value; + DEOPT_IF(old_value == NULL, STORE_ATTR); + STACK_SHRINK(1); + value = POP(); + ep->me_value = value; + } Py_DECREF(old_value); + STAT_INC(STORE_ATTR, hit); /* Ensure dict is GC tracked if it needs to be */ if (!_PyObject_GC_IS_TRACKED(dict) && _PyObject_GC_MAY_BE_TRACKED(value)) { _PyObject_GC_TRACK(dict); diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index e3d73bce6cfe5..8b227e61082be 100755 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -787,12 +787,6 @@ def write_repr(self, out, visited): def _get_entries(keys): dk_nentries = int(keys['dk_nentries']) dk_size = 1<= Python 3.6 - pass if dk_size <= 0xFF: offset = dk_size @@ -805,7 +799,10 @@ def _get_entries(keys): ent_addr = keys['dk_indices'].address ent_addr = ent_addr.cast(_type_unsigned_char_ptr()) + offset - ent_ptr_t = gdb.lookup_type('PyDictKeyEntry').pointer() + if int(keys['dk_kind']) == 0: # DICT_KEYS_GENERAL + ent_ptr_t = gdb.lookup_type('PyDictKeyEntry').pointer() + else: + ent_ptr_t = gdb.lookup_type('PyDictUnicodeEntry').pointer() ent_addr = ent_addr.cast(ent_ptr_t) return ent_addr, dk_nentries From webhook-mailer at python.org Tue Mar 1 23:46:03 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Wed, 02 Mar 2022 04:46:03 -0000 Subject: [Python-checkins] [3.9] Minor fixes to C API docs (GH-31501) (GH-31526) Message-ID: https://github.com/python/cpython/commit/7190617b562eae44e961dd6cc8c3c139b48af303 commit: 7190617b562eae44e961dd6cc8c3c139b48af303 branch: 3.9 author: Jelle Zijlstra committer: JelleZijlstra date: 2022-03-01T20:45:54-08:00 summary: [3.9] Minor fixes to C API docs (GH-31501) (GH-31526) * C API docs: move PyErr_SetImportErrorSubclass docs It was in the section about warnings, but it makes more sense to put it with PyErr_SetImportError. * C API docs: document closeit argument to PyRun_AnyFileExFlags It was already documented for PyRun_SimpleFileExFlags. * textual fixes to unicode docs * Move paragraph about tp_dealloc into tp_dealloc section * __aiter__ returns an async iterator, not an awaitable. (cherry picked from commit 43cf44ddcce6b225f959ea2a53e4817244ca6054) files: M Doc/c-api/exceptions.rst M Doc/c-api/typeobj.rst M Doc/c-api/unicode.rst M Doc/c-api/veryhigh.rst diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index 614eb24525541..df38ba43ec431 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -253,6 +253,14 @@ For convenience, some of these functions will always return a .. versionadded:: 3.3 +.. c:function:: PyObject* PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, PyObject *name, PyObject *path) + + Much like :c:func:`PyErr_SetImportError` but this function allows for + specifying a subclass of :exc:`ImportError` to raise. + + .. versionadded:: 3.6 + + .. c:function:: void PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset) Set file, line, and offset information for the current exception. If the @@ -320,13 +328,6 @@ an error value). :mod:`warnings` module and the :option:`-W` option in the command line documentation. There is no C API for warning control. -.. c:function:: PyObject* PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, PyObject *name, PyObject *path) - - Much like :c:func:`PyErr_SetImportError` but this function allows for - specifying a subclass of :exc:`ImportError` to raise. - - .. versionadded:: 3.6 - .. c:function:: int PyErr_WarnExplicitObject(PyObject *category, PyObject *message, PyObject *filename, int lineno, PyObject *module, PyObject *registry) diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index a800616730b9d..d58a53b1d69fb 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -474,7 +474,7 @@ PyObject Slots -------------- The type object structure extends the :c:type:`PyVarObject` structure. The -:attr:`ob_size` field is used for dynamic types (created by :func:`type_new`, +:attr:`ob_size` field is used for dynamic types (created by :func:`type_new`, usually called from a class statement). Note that :c:data:`PyType_Type` (the metatype) initializes :c:member:`~PyTypeObject.tp_itemsize`, which means that its instances (i.e. type objects) *must* have the :attr:`ob_size` field. @@ -1909,6 +1909,17 @@ and :c:type:`PyType_Type` effectively act as defaults.) For this field to be taken into account (even through inheritance), you must also set the :const:`Py_TPFLAGS_HAVE_FINALIZE` flags bit. + Also, note that, in a garbage collected Python, + :c:member:`~PyTypeObject.tp_dealloc` may be called from + any Python thread, not just the thread which created the object (if the object + becomes part of a refcount cycle, that cycle might be collected by a garbage + collection on any thread). This is not a problem for Python API calls, since + the thread on which tp_dealloc is called will own the Global Interpreter Lock + (GIL). However, if the object being destroyed in turn destroys objects from some + other C or C++ library, care should be taken to ensure that destroying those + objects on the thread which called tp_dealloc will not violate any assumptions + of the library. + **Inheritance:** This field is inherited by subtypes. @@ -1933,17 +1944,6 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. versionadded:: 3.9 (the field exists since 3.8 but it's only used since 3.9) -Also, note that, in a garbage collected Python, :c:member:`~PyTypeObject.tp_dealloc` may be called from -any Python thread, not just the thread which created the object (if the object -becomes part of a refcount cycle, that cycle might be collected by a garbage -collection on any thread). This is not a problem for Python API calls, since -the thread on which tp_dealloc is called will own the Global Interpreter Lock -(GIL). However, if the object being destroyed in turn destroys objects from some -other C or C++ library, care should be taken to ensure that destroying those -objects on the thread which called tp_dealloc will not violate any assumptions -of the library. - - .. _heap-types: Heap Types @@ -2340,7 +2340,8 @@ Async Object Structures PyObject *am_aiter(PyObject *self); - Must return an :term:`awaitable` object. See :meth:`__anext__` for details. + Must return an :term:`asynchronous iterator` object. + See :meth:`__anext__` for details. This slot may be set to ``NULL`` if an object does not implement asynchronous iteration protocol. diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst index 0d13d949e38c7..a6ae8ba13657d 100644 --- a/Doc/c-api/unicode.rst +++ b/Doc/c-api/unicode.rst @@ -1025,7 +1025,7 @@ Error handling is set by errors which may also be set to ``NULL`` meaning to use the default handling defined for the codec. Default error handling for all built-in codecs is "strict" (:exc:`ValueError` is raised). -The codecs all use a similar interface. Only deviation from the following +The codecs all use a similar interface. Only deviations from the following generic ones are documented for simplicity. @@ -1239,7 +1239,7 @@ These are the UTF-16 codec APIs: ``1``, any byte order mark is copied to the output (where it will result in either a ``\ufeff`` or a ``\ufffe`` character). - After completion, *\*byteorder* is set to the current byte order at the end + After completion, ``*byteorder`` is set to the current byte order at the end of input data. If *byteorder* is ``NULL``, the codec starts in native order mode. @@ -1457,7 +1457,7 @@ Character Map Codecs This codec is special in that it can be used to implement many different codecs (and this is in fact what was done to obtain most of the standard codecs -included in the :mod:`encodings` package). The codec uses mapping to encode and +included in the :mod:`encodings` package). The codec uses mappings to encode and decode characters. The mapping objects provided must support the :meth:`__getitem__` mapping interface; dictionaries and sequences work well. @@ -1619,7 +1619,7 @@ They all return ``NULL`` or ``-1`` if an exception occurs. .. c:function:: PyObject* PyUnicode_Splitlines(PyObject *s, int keepend) Split a Unicode string at line breaks, returning a list of Unicode strings. - CRLF is considered to be one line break. If *keepend* is ``0``, the Line break + CRLF is considered to be one line break. If *keepend* is ``0``, the line break characters are not included in the resulting strings. diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst index 551846ea6d720..3595a7b995626 100644 --- a/Doc/c-api/veryhigh.rst +++ b/Doc/c-api/veryhigh.rst @@ -75,6 +75,8 @@ the same library that the Python runtime is using. :c:func:`PyRun_SimpleFile`. *filename* is decoded from the filesystem encoding (:func:`sys.getfilesystemencoding`). If *filename* is ``NULL``, this function uses ``"???"`` as the filename. + If *closeit* is true, the file is closed before + ``PyRun_SimpleFileExFlags()`` returns. .. c:function:: int PyRun_SimpleString(const char *command) From webhook-mailer at python.org Tue Mar 1 23:46:20 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 02 Mar 2022 04:46:20 -0000 Subject: [Python-checkins] [3.9] bpo-43853: Expand test suite for SQLite UDF's (GH-27642) (GH-31030) (GH-31586) Message-ID: https://github.com/python/cpython/commit/3ea2a8f425d26e81d914c54d477e9d56eb27ac98 commit: 3ea2a8f425d26e81d914c54d477e9d56eb27ac98 branch: 3.9 author: Erlend Egeberg Aasland committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-01T20:46:16-08:00 summary: [3.9] bpo-43853: Expand test suite for SQLite UDF's (GH-27642) (GH-31030) (GH-31586) (cherry picked from commit 3eb3b4f270757f66c7fb6dcf5afa416ee1582a4b) files: M Lib/sqlite3/test/userfunctions.py M Modules/_sqlite/connection.c M Modules/_sqlite/statement.c diff --git a/Lib/sqlite3/test/userfunctions.py b/Lib/sqlite3/test/userfunctions.py index 1bceefe8e69d9..8fc8b4c3abb5a 100644 --- a/Lib/sqlite3/test/userfunctions.py +++ b/Lib/sqlite3/test/userfunctions.py @@ -44,22 +44,6 @@ def func_returnlonglong(): def func_raiseexception(): 5/0 -def func_isstring(v): - return type(v) is str -def func_isint(v): - return type(v) is int -def func_isfloat(v): - return type(v) is float -def func_isnone(v): - return type(v) is type(None) -def func_isblob(v): - return isinstance(v, (bytes, memoryview)) -def func_islonglong(v): - return isinstance(v, int) and v >= 1<<31 - -def func(*args): - return len(args) - class AggrNoStep: def __init__(self): pass @@ -160,15 +144,13 @@ def setUp(self): self.con.create_function("returnnull", 0, func_returnnull) self.con.create_function("returnblob", 0, func_returnblob) self.con.create_function("returnlonglong", 0, func_returnlonglong) + self.con.create_function("returnnan", 0, lambda: float("nan")) + self.con.create_function("returntoolargeint", 0, lambda: 1 << 65) self.con.create_function("raiseexception", 0, func_raiseexception) - self.con.create_function("isstring", 1, func_isstring) - self.con.create_function("isint", 1, func_isint) - self.con.create_function("isfloat", 1, func_isfloat) - self.con.create_function("isnone", 1, func_isnone) - self.con.create_function("isblob", 1, func_isblob) - self.con.create_function("islonglong", 1, func_islonglong) - self.con.create_function("spam", -1, func) + self.con.create_function("isblob", 1, lambda x: isinstance(x, bytes)) + self.con.create_function("isnone", 1, lambda x: x is None) + self.con.create_function("spam", -1, lambda *x: len(x)) self.con.execute("create table test(t text)") def tearDown(self): @@ -245,6 +227,16 @@ def CheckFuncReturnLongLong(self): val = cur.fetchone()[0] self.assertEqual(val, 1<<31) + def CheckFuncReturnNaN(self): + cur = self.con.cursor() + cur.execute("select returnnan()") + self.assertIsNone(cur.fetchone()[0]) + + def CheckFuncReturnTooLargeInt(self): + cur = self.con.cursor() + with self.assertRaises(sqlite.OperationalError): + self.con.execute("select returntoolargeint()") + def CheckFuncException(self): cur = self.con.cursor() with self.assertRaises(sqlite.OperationalError) as cm: @@ -252,50 +244,62 @@ def CheckFuncException(self): cur.fetchone() self.assertEqual(str(cm.exception), 'user-defined function raised exception') - def CheckParamString(self): - cur = self.con.cursor() - for text in ["foo", str()]: - with self.subTest(text=text): - cur.execute("select isstring(?)", (text,)) - val = cur.fetchone()[0] - self.assertEqual(val, 1) - - def CheckParamInt(self): - cur = self.con.cursor() - cur.execute("select isint(?)", (42,)) - val = cur.fetchone()[0] - self.assertEqual(val, 1) - - def CheckParamFloat(self): - cur = self.con.cursor() - cur.execute("select isfloat(?)", (3.14,)) - val = cur.fetchone()[0] - self.assertEqual(val, 1) - - def CheckParamNone(self): - cur = self.con.cursor() - cur.execute("select isnone(?)", (None,)) - val = cur.fetchone()[0] - self.assertEqual(val, 1) - - def CheckParamBlob(self): - cur = self.con.cursor() - cur.execute("select isblob(?)", (memoryview(b"blob"),)) - val = cur.fetchone()[0] - self.assertEqual(val, 1) - - def CheckParamLongLong(self): - cur = self.con.cursor() - cur.execute("select islonglong(?)", (1<<42,)) - val = cur.fetchone()[0] - self.assertEqual(val, 1) - def CheckAnyArguments(self): cur = self.con.cursor() cur.execute("select spam(?, ?)", (1, 2)) val = cur.fetchone()[0] self.assertEqual(val, 2) + def CheckEmptyBlob(self): + cur = self.con.execute("select isblob(x'')") + self.assertTrue(cur.fetchone()[0]) + + def CheckNaNFloat(self): + cur = self.con.execute("select isnone(?)", (float("nan"),)) + # SQLite has no concept of nan; it is converted to NULL + self.assertTrue(cur.fetchone()[0]) + + def CheckTooLargeInt(self): + err = "Python int too large to convert to SQLite INTEGER" + self.assertRaisesRegex(OverflowError, err, self.con.execute, + "select spam(?)", (1 << 65,)) + + def CheckNonContiguousBlob(self): + self.assertRaisesRegex(ValueError, "could not convert BLOB to buffer", + self.con.execute, "select spam(?)", + (memoryview(b"blob")[::2],)) + + def CheckParamSurrogates(self): + self.assertRaisesRegex(UnicodeEncodeError, "surrogates not allowed", + self.con.execute, "select spam(?)", + ("\ud803\ude6d",)) + + def CheckFuncParams(self): + results = [] + def append_result(arg): + results.append((arg, type(arg))) + self.con.create_function("test_params", 1, append_result) + + dataset = [ + (42, int), + (-1, int), + (1234567890123456789, int), + (4611686018427387905, int), # 63-bit int with non-zero low bits + (3.14, float), + (float('inf'), float), + ("text", str), + ("1\x002", str), + ("\u02e2q\u02e1\u2071\u1d57\u1d49", str), + (b"blob", bytes), + (bytearray(range(2)), bytes), + (memoryview(b"blob"), bytes), + (None, type(None)), + ] + for val, _ in dataset: + cur = self.con.execute("select test_params(?)", (val,)) + cur.fetchone() + self.assertEqual(dataset, results) + # Regarding deterministic functions: # # Between 3.8.3 and 3.15.0, deterministic functions were only used to diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 30e333a4b86d8..90327376cc0d4 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -518,7 +518,11 @@ _pysqlite_set_result(sqlite3_context* context, PyObject* py_val) return -1; sqlite3_result_int64(context, value); } else if (PyFloat_Check(py_val)) { - sqlite3_result_double(context, PyFloat_AsDouble(py_val)); + double value = PyFloat_AsDouble(py_val); + if (value == -1 && PyErr_Occurred()) { + return -1; + } + sqlite3_result_double(context, value); } else if (PyUnicode_Check(py_val)) { Py_ssize_t sz; const char *str = PyUnicode_AsUTF8AndSize(py_val, &sz); diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index 23c204e7521f0..0272ce11207f1 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -152,9 +152,16 @@ int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObjec rc = sqlite3_bind_int64(self->st, pos, value); break; } - case TYPE_FLOAT: - rc = sqlite3_bind_double(self->st, pos, PyFloat_AsDouble(parameter)); + case TYPE_FLOAT: { + double value = PyFloat_AsDouble(parameter); + if (value == -1 && PyErr_Occurred()) { + rc = -1; + } + else { + rc = sqlite3_bind_double(self->st, pos, value); + } break; + } case TYPE_UNICODE: string = PyUnicode_AsUTF8AndSize(parameter, &buflen); if (string == NULL) From webhook-mailer at python.org Tue Mar 1 23:46:34 2022 From: webhook-mailer at python.org (sweeneyde) Date: Wed, 02 Mar 2022 04:46:34 -0000 Subject: [Python-checkins] bpo-46848: Use stringlib/fastsearch in mmap (GH-31625) Message-ID: https://github.com/python/cpython/commit/6ddb09f35b922a3bbb59e408a3ca7636a6938468 commit: 6ddb09f35b922a3bbb59e408a3ca7636a6938468 branch: main author: Dennis Sweeney <36520290+sweeneyde at users.noreply.github.com> committer: sweeneyde <36520290+sweeneyde at users.noreply.github.com> date: 2022-03-01T23:46:30-05:00 summary: bpo-46848: Use stringlib/fastsearch in mmap (GH-31625) Speed up mmap.find(). Add _PyBytes_Find() and _PyBytes_ReverseFind(). files: A Misc/NEWS.d/next/Library/2022-03-01-01-16-13.bpo-46848.BB01Fr.rst M Include/cpython/bytesobject.h M Modules/mmapmodule.c M Objects/bytesobject.c diff --git a/Include/cpython/bytesobject.h b/Include/cpython/bytesobject.h index 6b3f55224fc55..38a0fe0af660f 100644 --- a/Include/cpython/bytesobject.h +++ b/Include/cpython/bytesobject.h @@ -116,3 +116,22 @@ PyAPI_FUNC(void*) _PyBytesWriter_WriteBytes(_PyBytesWriter *writer, void *str, const void *bytes, Py_ssize_t size); + +/* Substring Search. + + Returns the index of the first occurence of + a substring ("needle") in a larger text ("haystack"). + If the needle is not found, return -1. + If the needle is found, add offset to the index. +*/ + +PyAPI_FUNC(Py_ssize_t) +_PyBytes_Find(const char *haystack, Py_ssize_t len_haystack, + const char *needle, Py_ssize_t len_needle, + Py_ssize_t offset); + +/* Same as above, but search right-to-left */ +PyAPI_FUNC(Py_ssize_t) +_PyBytes_ReverseFind(const char *haystack, Py_ssize_t len_haystack, + const char *needle, Py_ssize_t len_needle, + Py_ssize_t offset); diff --git a/Misc/NEWS.d/next/Library/2022-03-01-01-16-13.bpo-46848.BB01Fr.rst b/Misc/NEWS.d/next/Library/2022-03-01-01-16-13.bpo-46848.BB01Fr.rst new file mode 100644 index 0000000000000..bd20a843ab6ce --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-01-01-16-13.bpo-46848.BB01Fr.rst @@ -0,0 +1,3 @@ +For performance, use the optimized string-searching implementations +from :meth:`~bytes.find` and :meth:`~bytes.rfind` +for :meth:`~mmap.find` and :meth:`~mmap.rfind`. diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index 26cedf1b9006d..6a038e72f93cf 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -315,12 +315,8 @@ mmap_gfind(mmap_object *self, if (!PyArg_ParseTuple(args, reverse ? "y*|nn:rfind" : "y*|nn:find", &view, &start, &end)) { return NULL; - } else { - const char *p, *start_p, *end_p; - int sign = reverse ? -1 : 1; - const char *needle = view.buf; - Py_ssize_t len = view.len; - + } + else { if (start < 0) start += self->size; if (start < 0) @@ -335,21 +331,19 @@ mmap_gfind(mmap_object *self, else if (end > self->size) end = self->size; - start_p = self->data + start; - end_p = self->data + end; - - for (p = (reverse ? end_p - len : start_p); - (p >= start_p) && (p + len <= end_p); p += sign) { - Py_ssize_t i; - for (i = 0; i < len && needle[i] == p[i]; ++i) - /* nothing */; - if (i == len) { - PyBuffer_Release(&view); - return PyLong_FromSsize_t(p - self->data); - } + Py_ssize_t res; + if (reverse) { + res = _PyBytes_ReverseFind( + self->data + start, end - start, + view.buf, view.len, start); + } + else { + res = _PyBytes_Find( + self->data + start, end - start, + view.buf, view.len, start); } PyBuffer_Release(&view); - return PyLong_FromLong(-1); + return PyLong_FromSsize_t(res); } } diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 3d8a21696d1c8..4c67b8f7af213 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -1247,6 +1247,24 @@ PyBytes_AsStringAndSize(PyObject *obj, #undef STRINGLIB_GET_EMPTY +Py_ssize_t +_PyBytes_Find(const char *haystack, Py_ssize_t len_haystack, + const char *needle, Py_ssize_t len_needle, + Py_ssize_t offset) +{ + return stringlib_find(haystack, len_haystack, + needle, len_needle, offset); +} + +Py_ssize_t +_PyBytes_ReverseFind(const char *haystack, Py_ssize_t len_haystack, + const char *needle, Py_ssize_t len_needle, + Py_ssize_t offset) +{ + return stringlib_rfind(haystack, len_haystack, + needle, len_needle, offset); +} + PyObject * PyBytes_Repr(PyObject *obj, int smartquotes) { From webhook-mailer at python.org Wed Mar 2 00:30:28 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Wed, 02 Mar 2022 05:30:28 -0000 Subject: [Python-checkins] bpo-46195: Do not add `Optional` in `get_type_hints` (GH-30304) Message-ID: https://github.com/python/cpython/commit/20a1c8ee4bcb1c421b7cca1f3f5d6ad7ce30a9c9 commit: 20a1c8ee4bcb1c421b7cca1f3f5d6ad7ce30a9c9 branch: main author: Nikita Sobolev committer: JelleZijlstra date: 2022-03-01T21:29:46-08:00 summary: bpo-46195: Do not add `Optional` in `get_type_hints` (GH-30304) Co-authored-by: Ken Jin <28750310+Fidget-Spinner at users.noreply.github.com> Co-authored-by: Jelle Zijlstra files: A Misc/NEWS.d/next/Library/2021-12-30-21-38-51.bpo-46195.jFKGq_.rst M Doc/library/typing.rst M Lib/test/test_typing.py M Lib/typing.py diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index a02ad244d9fbb..bfcbeb8c7e680 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -2185,9 +2185,7 @@ Introspection helpers This is often the same as ``obj.__annotations__``. In addition, forward references encoded as string literals are handled by evaluating - them in ``globals`` and ``locals`` namespaces. If necessary, - ``Optional[t]`` is added for function and method annotations if a default - value equal to ``None`` is set. For a class ``C``, return + them in ``globals`` and ``locals`` namespaces. For a class ``C``, return a dictionary constructed by merging all the ``__annotations__`` along ``C.__mro__`` in reverse order. @@ -2214,6 +2212,11 @@ Introspection helpers .. versionchanged:: 3.9 Added ``include_extras`` parameter as part of :pep:`593`. + .. versionchanged:: 3.11 + Previously, ``Optional[t]`` was added for function and method annotations + if a default value equal to ``None`` was set. + Now the annotation is returned unchanged. + .. function:: get_args(tp) .. function:: get_origin(tp) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index dc1514d63b777..8fcc24c25eb95 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -2828,16 +2828,15 @@ def add_right(self, node: 'Node[T]' = None): t = Node[int] both_hints = get_type_hints(t.add_both, globals(), locals()) self.assertEqual(both_hints['left'], Optional[Node[T]]) - self.assertEqual(both_hints['right'], Optional[Node[T]]) - self.assertEqual(both_hints['left'], both_hints['right']) - self.assertEqual(both_hints['stuff'], Optional[int]) + self.assertEqual(both_hints['right'], Node[T]) + self.assertEqual(both_hints['stuff'], int) self.assertNotIn('blah', both_hints) left_hints = get_type_hints(t.add_left, globals(), locals()) self.assertEqual(left_hints['node'], Optional[Node[T]]) right_hints = get_type_hints(t.add_right, globals(), locals()) - self.assertEqual(right_hints['node'], Optional[Node[T]]) + self.assertEqual(right_hints['node'], Node[T]) def test_forwardref_instance_type_error(self): fr = typing.ForwardRef('int') @@ -3630,6 +3629,18 @@ def __iand__(self, other: Const["MySet[T]"]) -> "MySet[T]": {'other': MySet[T], 'return': MySet[T]} ) + def test_get_type_hints_annotated_with_none_default(self): + # See: https://bugs.python.org/issue46195 + def annotated_with_none_default(x: Annotated[int, 'data'] = None): ... + self.assertEqual( + get_type_hints(annotated_with_none_default), + {'x': int}, + ) + self.assertEqual( + get_type_hints(annotated_with_none_default, include_extras=True), + {'x': Annotated[int, 'data']}, + ) + def test_get_type_hints_classes_str_annotations(self): class Foo: y = str diff --git a/Lib/typing.py b/Lib/typing.py index ad1435ed23d27..9d668b3cf4a2a 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1879,26 +1879,6 @@ def cast(typ, val): return val -def _get_defaults(func): - """Internal helper to extract the default arguments, by name.""" - try: - code = func.__code__ - except AttributeError: - # Some built-in functions don't have __code__, __defaults__, etc. - return {} - pos_count = code.co_argcount - arg_names = code.co_varnames - arg_names = arg_names[:pos_count] - defaults = func.__defaults__ or () - kwdefaults = func.__kwdefaults__ - res = dict(kwdefaults) if kwdefaults else {} - pos_offset = pos_count - len(defaults) - for name, value in zip(arg_names[pos_offset:], defaults): - assert name not in res - res[name] = value - return res - - _allowed_types = (types.FunctionType, types.BuiltinFunctionType, types.MethodType, types.ModuleType, WrapperDescriptorType, MethodWrapperType, MethodDescriptorType) @@ -1908,8 +1888,7 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False): """Return type hints for an object. This is often the same as obj.__annotations__, but it handles - forward references encoded as string literals, adds Optional[t] if a - default value equal to None is set and recursively replaces all + forward references encoded as string literals and recursively replaces all 'Annotated[T, ...]' with 'T' (unless 'include_extras=True'). The argument may be a module, class, method, or function. The annotations @@ -1989,7 +1968,6 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False): else: raise TypeError('{!r} is not a module, class, method, ' 'or function.'.format(obj)) - defaults = _get_defaults(obj) hints = dict(hints) for name, value in hints.items(): if value is None: @@ -2002,10 +1980,7 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False): is_argument=not isinstance(obj, types.ModuleType), is_class=False, ) - value = _eval_type(value, globalns, localns) - if name in defaults and defaults[name] is None: - value = Optional[value] - hints[name] = value + hints[name] = _eval_type(value, globalns, localns) return hints if include_extras else {k: _strip_annotations(t) for k, t in hints.items()} diff --git a/Misc/NEWS.d/next/Library/2021-12-30-21-38-51.bpo-46195.jFKGq_.rst b/Misc/NEWS.d/next/Library/2021-12-30-21-38-51.bpo-46195.jFKGq_.rst new file mode 100644 index 0000000000000..03ea46c3a83f1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-12-30-21-38-51.bpo-46195.jFKGq_.rst @@ -0,0 +1,3 @@ +:func:`typing.get_type_hints` no longer adds ``Optional`` to parameters with +``None`` as a default. This aligns to changes to PEP 484 in +https://github.com/python/peps/pull/689 From webhook-mailer at python.org Wed Mar 2 04:19:51 2022 From: webhook-mailer at python.org (ambv) Date: Wed, 02 Mar 2022 09:19:51 -0000 Subject: [Python-checkins] bpo-46794: Bump up the libexpat version into 2.4.6 (GH-31487) (GH-31520) Message-ID: https://github.com/python/cpython/commit/eb6c840a2414dc057ffcfbb5ad68d6253c8dd57c commit: eb6c840a2414dc057ffcfbb5ad68d6253c8dd57c branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv date: 2022-03-02T10:19:33+01:00 summary: bpo-46794: Bump up the libexpat version into 2.4.6 (GH-31487) (GH-31520) (cherry picked from commit 1935e1cc284942bec8006287c939e295e1a7bf13) Co-authored-by: Dong-hee Na files: A Misc/NEWS.d/next/Core and Builtins/2022-02-22-12-07-53.bpo-46794.6WvJ9o.rst M Modules/expat/expat.h M Modules/expat/xmlparse.c M Modules/expat/xmlrole.c M Modules/expat/xmltok.c M Modules/expat/xmltok_impl.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-22-12-07-53.bpo-46794.6WvJ9o.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-22-12-07-53.bpo-46794.6WvJ9o.rst new file mode 100644 index 0000000000000..127387d32cb7a --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-02-22-12-07-53.bpo-46794.6WvJ9o.rst @@ -0,0 +1 @@ +Bump up the libexpat version into 2.4.6 diff --git a/Modules/expat/expat.h b/Modules/expat/expat.h index 4c5704fd9336b..46a0e1bcd22de 100644 --- a/Modules/expat/expat.h +++ b/Modules/expat/expat.h @@ -1041,7 +1041,7 @@ XML_SetBillionLaughsAttackProtectionActivationThreshold( */ #define XML_MAJOR_VERSION 2 #define XML_MINOR_VERSION 4 -#define XML_MICRO_VERSION 4 +#define XML_MICRO_VERSION 6 #ifdef __cplusplus } diff --git a/Modules/expat/xmlparse.c b/Modules/expat/xmlparse.c index 4b43e61321691..7db28d07acbcd 100644 --- a/Modules/expat/xmlparse.c +++ b/Modules/expat/xmlparse.c @@ -1,4 +1,4 @@ -/* 2e2c8ce5f11a473d65ec313ab20ceee6afefb355f5405afc06e7204e2e41c8c0 (2.4.4+) +/* a30d2613dcfdef81475a9d1a349134d2d42722172fdaa7d5bb12ed2aa74b9596 (2.4.6+) __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| @@ -11,7 +11,7 @@ Copyright (c) 2000-2006 Fred L. Drake, Jr. Copyright (c) 2001-2002 Greg Stein Copyright (c) 2002-2016 Karl Waclawek - Copyright (c) 2005-2009 Steven Solie + Copyright (c) 2005-2009 Steven Solie Copyright (c) 2016 Eric Rahm Copyright (c) 2016-2022 Sebastian Pipping Copyright (c) 2016 Gaurav @@ -718,8 +718,7 @@ XML_ParserCreate(const XML_Char *encodingName) { XML_Parser XMLCALL XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) { - XML_Char tmp[2]; - *tmp = nsSep; + XML_Char tmp[2] = {nsSep, 0}; return XML_ParserCreate_MM(encodingName, NULL, tmp); } @@ -1344,8 +1343,7 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context, would be otherwise. */ if (parser->m_ns) { - XML_Char tmp[2]; - *tmp = parser->m_namespaceSeparator; + XML_Char tmp[2] = {parser->m_namespaceSeparator, 0}; parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd); } else { parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd); @@ -2563,6 +2561,7 @@ storeRawNames(XML_Parser parser) { while (tag) { int bufSize; int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1); + size_t rawNameLen; char *rawNameBuf = tag->buf + nameLen; /* Stop if already stored. Since m_tagStack is a stack, we can stop at the first entry that has already been copied; everything @@ -2574,7 +2573,11 @@ storeRawNames(XML_Parser parser) { /* For re-use purposes we need to ensure that the size of tag->buf is a multiple of sizeof(XML_Char). */ - bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)); + rawNameLen = ROUND_UP(tag->rawNameLength, sizeof(XML_Char)); + /* Detect and prevent integer overflow. */ + if (rawNameLen > (size_t)INT_MAX - nameLen) + return XML_FALSE; + bufSize = nameLen + (int)rawNameLen; if (bufSize > tag->bufEnd - tag->buf) { char *temp = (char *)REALLOC(parser, tag->buf, bufSize); if (temp == NULL) @@ -3756,6 +3759,17 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, if (! mustBeXML && isXMLNS && (len > xmlnsLen || uri[len] != xmlnsNamespace[len])) isXMLNS = XML_FALSE; + + // NOTE: While Expat does not validate namespace URIs against RFC 3986, + // we have to at least make sure that the XML processor on top of + // Expat (that is splitting tag names by namespace separator into + // 2- or 3-tuples (uri-local or uri-local-prefix)) cannot be confused + // by an attacker putting additional namespace separator characters + // into namespace declarations. That would be ambiguous and not to + // be expected. + if (parser->m_ns && (uri[len] == parser->m_namespaceSeparator)) { + return XML_ERROR_SYNTAX; + } } isXML = isXML && len == xmlLen; isXMLNS = isXMLNS && len == xmlnsLen; @@ -7317,44 +7331,15 @@ nextScaffoldPart(XML_Parser parser) { return next; } -static void -build_node(XML_Parser parser, int src_node, XML_Content *dest, - XML_Content **contpos, XML_Char **strpos) { - DTD *const dtd = parser->m_dtd; /* save one level of indirection */ - dest->type = dtd->scaffold[src_node].type; - dest->quant = dtd->scaffold[src_node].quant; - if (dest->type == XML_CTYPE_NAME) { - const XML_Char *src; - dest->name = *strpos; - src = dtd->scaffold[src_node].name; - for (;;) { - *(*strpos)++ = *src; - if (! *src) - break; - src++; - } - dest->numchildren = 0; - dest->children = NULL; - } else { - unsigned int i; - int cn; - dest->numchildren = dtd->scaffold[src_node].childcnt; - dest->children = *contpos; - *contpos += dest->numchildren; - for (i = 0, cn = dtd->scaffold[src_node].firstchild; i < dest->numchildren; - i++, cn = dtd->scaffold[cn].nextsib) { - build_node(parser, cn, &(dest->children[i]), contpos, strpos); - } - dest->name = NULL; - } -} - static XML_Content * build_model(XML_Parser parser) { + /* Function build_model transforms the existing parser->m_dtd->scaffold + * array of CONTENT_SCAFFOLD tree nodes into a new array of + * XML_Content tree nodes followed by a gapless list of zero-terminated + * strings. */ DTD *const dtd = parser->m_dtd; /* save one level of indirection */ XML_Content *ret; - XML_Content *cpos; - XML_Char *str; + XML_Char *str; /* the current string writing location */ /* Detect and prevent integer overflow. * The preprocessor guard addresses the "always false" warning @@ -7380,10 +7365,96 @@ build_model(XML_Parser parser) { if (! ret) return NULL; - str = (XML_Char *)(&ret[dtd->scaffCount]); - cpos = &ret[1]; + /* What follows is an iterative implementation (of what was previously done + * recursively in a dedicated function called "build_node". The old recursive + * build_node could be forced into stack exhaustion from input as small as a + * few megabyte, and so that was a security issue. Hence, a function call + * stack is avoided now by resolving recursion.) + * + * The iterative approach works as follows: + * + * - We have two writing pointers, both walking up the result array; one does + * the work, the other creates "jobs" for its colleague to do, and leads + * the way: + * + * - The faster one, pointer jobDest, always leads and writes "what job + * to do" by the other, once they reach that place in the + * array: leader "jobDest" stores the source node array index (relative + * to array dtd->scaffold) in field "numchildren". + * + * - The slower one, pointer dest, looks at the value stored in the + * "numchildren" field (which actually holds a source node array index + * at that time) and puts the real data from dtd->scaffold in. + * + * - Before the loop starts, jobDest writes source array index 0 + * (where the root node is located) so that dest will have something to do + * when it starts operation. + * + * - Whenever nodes with children are encountered, jobDest appends + * them as new jobs, in order. As a result, tree node siblings are + * adjacent in the resulting array, for example: + * + * [0] root, has two children + * [1] first child of 0, has three children + * [3] first child of 1, does not have children + * [4] second child of 1, does not have children + * [5] third child of 1, does not have children + * [2] second child of 0, does not have children + * + * Or (the same data) presented in flat array view: + * + * [0] root, has two children + * + * [1] first child of 0, has three children + * [2] second child of 0, does not have children + * + * [3] first child of 1, does not have children + * [4] second child of 1, does not have children + * [5] third child of 1, does not have children + * + * - The algorithm repeats until all target array indices have been processed. + */ + XML_Content *dest = ret; /* tree node writing location, moves upwards */ + XML_Content *const destLimit = &ret[dtd->scaffCount]; + XML_Content *jobDest = ret; /* next free writing location in target array */ + str = (XML_Char *)&ret[dtd->scaffCount]; + + /* Add the starting job, the root node (index 0) of the source tree */ + (jobDest++)->numchildren = 0; + + for (; dest < destLimit; dest++) { + /* Retrieve source tree array index from job storage */ + const int src_node = (int)dest->numchildren; + + /* Convert item */ + dest->type = dtd->scaffold[src_node].type; + dest->quant = dtd->scaffold[src_node].quant; + if (dest->type == XML_CTYPE_NAME) { + const XML_Char *src; + dest->name = str; + src = dtd->scaffold[src_node].name; + for (;;) { + *str++ = *src; + if (! *src) + break; + src++; + } + dest->numchildren = 0; + dest->children = NULL; + } else { + unsigned int i; + int cn; + dest->name = NULL; + dest->numchildren = dtd->scaffold[src_node].childcnt; + dest->children = jobDest; + + /* Append scaffold indices of children to array */ + for (i = 0, cn = dtd->scaffold[src_node].firstchild; + i < dest->numchildren; i++, cn = dtd->scaffold[cn].nextsib) + (jobDest++)->numchildren = (unsigned int)cn; + } + } - build_node(parser, 0, ret, &cpos, &str); return ret; } @@ -7412,7 +7483,7 @@ getElementType(XML_Parser parser, const ENCODING *enc, const char *ptr, static XML_Char * copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) { - int charsRequired = 0; + size_t charsRequired = 0; XML_Char *result; /* First determine how long the string is */ diff --git a/Modules/expat/xmlrole.c b/Modules/expat/xmlrole.c index 77746ee42d10a..3f0f5c150c627 100644 --- a/Modules/expat/xmlrole.c +++ b/Modules/expat/xmlrole.c @@ -11,7 +11,7 @@ Copyright (c) 2002 Greg Stein Copyright (c) 2002-2006 Karl Waclawek Copyright (c) 2002-2003 Fred L. Drake, Jr. - Copyright (c) 2005-2009 Steven Solie + Copyright (c) 2005-2009 Steven Solie Copyright (c) 2016-2021 Sebastian Pipping Copyright (c) 2017 Rhodri James Copyright (c) 2019 David Loffredo diff --git a/Modules/expat/xmltok.c b/Modules/expat/xmltok.c index 502ca1adc33b9..c659983b4008b 100644 --- a/Modules/expat/xmltok.c +++ b/Modules/expat/xmltok.c @@ -11,8 +11,8 @@ Copyright (c) 2001-2003 Fred L. Drake, Jr. Copyright (c) 2002 Greg Stein Copyright (c) 2002-2016 Karl Waclawek - Copyright (c) 2005-2009 Steven Solie - Copyright (c) 2016-2021 Sebastian Pipping + Copyright (c) 2005-2009 Steven Solie + Copyright (c) 2016-2022 Sebastian Pipping Copyright (c) 2016 Pascal Cuoq Copyright (c) 2016 Don Lewis Copyright (c) 2017 Rhodri James @@ -98,11 +98,6 @@ + ((((byte)[1]) & 3) << 1) + ((((byte)[2]) >> 5) & 1)] \ & (1u << (((byte)[2]) & 0x1F))) -#define UTF8_GET_NAMING(pages, p, n) \ - ((n) == 2 \ - ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \ - : ((n) == 3 ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) : 0)) - /* Detection of invalid UTF-8 sequences is based on Table 3.1B of Unicode 3.2: http://www.unicode.org/unicode/reports/tr28/ with the additional restriction of not allowing the Unicode diff --git a/Modules/expat/xmltok_impl.c b/Modules/expat/xmltok_impl.c index 0430591b42636..4072b06497d1c 100644 --- a/Modules/expat/xmltok_impl.c +++ b/Modules/expat/xmltok_impl.c @@ -10,7 +10,7 @@ Copyright (c) 2000 Clark Cooper Copyright (c) 2002 Fred L. Drake, Jr. Copyright (c) 2002-2016 Karl Waclawek - Copyright (c) 2016-2021 Sebastian Pipping + Copyright (c) 2016-2022 Sebastian Pipping Copyright (c) 2017 Rhodri James Copyright (c) 2018 Benjamin Peterson Copyright (c) 2018 Anton Maklakov @@ -69,7 +69,7 @@ case BT_LEAD##n: \ if (end - ptr < n) \ return XML_TOK_PARTIAL_CHAR; \ - if (! IS_NAME_CHAR(enc, ptr, n)) { \ + if (IS_INVALID_CHAR(enc, ptr, n) || ! IS_NAME_CHAR(enc, ptr, n)) { \ *nextTokPtr = ptr; \ return XML_TOK_INVALID; \ } \ @@ -98,7 +98,7 @@ case BT_LEAD##n: \ if (end - ptr < n) \ return XML_TOK_PARTIAL_CHAR; \ - if (! IS_NMSTRT_CHAR(enc, ptr, n)) { \ + if (IS_INVALID_CHAR(enc, ptr, n) || ! IS_NMSTRT_CHAR(enc, ptr, n)) { \ *nextTokPtr = ptr; \ return XML_TOK_INVALID; \ } \ @@ -1142,6 +1142,10 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, case BT_LEAD##n: \ if (end - ptr < n) \ return XML_TOK_PARTIAL_CHAR; \ + if (IS_INVALID_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ if (IS_NMSTRT_CHAR(enc, ptr, n)) { \ ptr += n; \ tok = XML_TOK_NAME; \ @@ -1270,7 +1274,7 @@ PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end, switch (BYTE_TYPE(enc, ptr)) { # define LEAD_CASE(n) \ case BT_LEAD##n: \ - ptr += n; \ + ptr += n; /* NOTE: The encoding has already been validated. */ \ break; LEAD_CASE(2) LEAD_CASE(3) @@ -1339,7 +1343,7 @@ PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end, switch (BYTE_TYPE(enc, ptr)) { # define LEAD_CASE(n) \ case BT_LEAD##n: \ - ptr += n; \ + ptr += n; /* NOTE: The encoding has already been validated. */ \ break; LEAD_CASE(2) LEAD_CASE(3) @@ -1518,7 +1522,7 @@ PREFIX(getAtts)(const ENCODING *enc, const char *ptr, int attsMax, state = inName; \ } # define LEAD_CASE(n) \ - case BT_LEAD##n: \ + case BT_LEAD##n: /* NOTE: The encoding has already been validated. */ \ START_NAME ptr += (n - MINBPC(enc)); \ break; LEAD_CASE(2) @@ -1730,7 +1734,7 @@ PREFIX(nameLength)(const ENCODING *enc, const char *ptr) { switch (BYTE_TYPE(enc, ptr)) { # define LEAD_CASE(n) \ case BT_LEAD##n: \ - ptr += n; \ + ptr += n; /* NOTE: The encoding has already been validated. */ \ break; LEAD_CASE(2) LEAD_CASE(3) @@ -1775,7 +1779,7 @@ PREFIX(updatePosition)(const ENCODING *enc, const char *ptr, const char *end, switch (BYTE_TYPE(enc, ptr)) { # define LEAD_CASE(n) \ case BT_LEAD##n: \ - ptr += n; \ + ptr += n; /* NOTE: The encoding has already been validated. */ \ pos->columnNumber++; \ break; LEAD_CASE(2) From webhook-mailer at python.org Wed Mar 2 05:05:33 2022 From: webhook-mailer at python.org (methane) Date: Wed, 02 Mar 2022 10:05:33 -0000 Subject: [Python-checkins] dict: Internal cleanup (GH-31641) Message-ID: https://github.com/python/cpython/commit/03642df1a1cfddcd740b62e78bddfa3ea6863da4 commit: 03642df1a1cfddcd740b62e78bddfa3ea6863da4 branch: main author: Inada Naoki committer: methane date: 2022-03-02T19:05:12+09:00 summary: dict: Internal cleanup (GH-31641) * Make empty_key from split table to combined table. * Use unicode_get_hash() when possible. files: M Objects/dictobject.c diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 20d7edab93ab1..abe455e4ae034 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -454,7 +454,7 @@ static PyDictKeysObject empty_keys_struct = { 1, /* dk_refcnt */ 0, /* dk_log2_size */ 0, /* dk_log2_index_bytes */ - DICT_KEYS_SPLIT, /* dk_kind */ + DICT_KEYS_UNICODE, /* dk_kind */ 1, /* dk_version */ 0, /* dk_usable (immutable) */ 0, /* dk_nentries */ @@ -462,16 +462,6 @@ static PyDictKeysObject empty_keys_struct = { DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY}, /* dk_indices */ }; - -struct { - uint8_t prefix[sizeof(PyObject *)]; - PyDictValues values; -} empty_values_struct = { - { [sizeof(PyObject *)-1] = sizeof(PyObject *) }, - {{NULL}} -}; -#define empty_values (&empty_values_struct.values) - #define Py_EMPTY_KEYS &empty_keys_struct /* Uncomment to check the dict content in _PyDict_CheckConsistency() */ @@ -495,7 +485,6 @@ get_index_from_order(PyDictObject *mp, Py_ssize_t i) static void dump_entries(PyDictKeysObject *dk) { - int kind = dk->dk_kind; for (Py_ssize_t i = 0; i < dk->dk_nentries; i++) { if (DK_IS_UNICODE(dk)) { PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(dk)[i]; @@ -531,7 +520,7 @@ _PyDict_CheckConsistency(PyObject *op, int check_content) if (!splitted) { /* combined table */ CHECK(keys->dk_kind != DICT_KEYS_SPLIT); - CHECK(keys->dk_refcnt == 1); + CHECK(keys->dk_refcnt == 1 || keys == Py_EMPTY_KEYS); } else { CHECK(keys->dk_kind == DICT_KEYS_SPLIT); @@ -688,7 +677,8 @@ free_keys_object(PyDictKeysObject *keys) // free_keys_object() must not be called after _PyDict_Fini() assert(state->keys_numfree != -1); #endif - if (DK_LOG_SIZE(keys) == PyDict_LOG_MINSIZE && state->keys_numfree < PyDict_MAXFREELIST + if (DK_LOG_SIZE(keys) == PyDict_LOG_MINSIZE + && state->keys_numfree < PyDict_MAXFREELIST && DK_IS_UNICODE(keys)) { state->keys_free_list[state->keys_numfree++] = keys; return; @@ -845,7 +835,7 @@ PyObject * PyDict_New(void) { dictkeys_incref(Py_EMPTY_KEYS); - return new_dict(Py_EMPTY_KEYS, empty_values, 0, 0); + return new_dict(Py_EMPTY_KEYS, NULL, 0, 0); } /* Search index of hash table from offset of entry table */ @@ -1478,9 +1468,7 @@ dictresize(PyDictObject *mp, uint8_t log2_newsize, int unicode) } dictkeys_decref(oldkeys); mp->ma_values = NULL; - if (oldvalues != empty_values) { - free_values(oldvalues); - } + free_values(oldvalues); } else { // oldkeys is combined. if (oldkeys->dk_kind == DICT_KEYS_GENERAL) { @@ -1506,7 +1494,7 @@ dictresize(PyDictObject *mp, uint8_t log2_newsize, int unicode) if (unicode) { // combined unicode -> combined unicode PyDictUnicodeEntry *newentries = DK_UNICODE_ENTRIES(mp->ma_keys); if (oldkeys->dk_nentries == numentries && mp->ma_keys->dk_kind == DICT_KEYS_UNICODE) { - memcpy(newentries, oldentries, numentries * sizeof(PyDictUnicodeEntry)); + memcpy(newentries, oldentries, numentries * sizeof(PyDictUnicodeEntry)); } else { PyDictUnicodeEntry *ep = oldentries; @@ -1533,27 +1521,31 @@ dictresize(PyDictObject *mp, uint8_t log2_newsize, int unicode) } } - assert(oldkeys->dk_kind != DICT_KEYS_SPLIT); - assert(oldkeys->dk_refcnt == 1); + // We can not use free_keys_object here because key's reference + // are moved already. + if (oldkeys != Py_EMPTY_KEYS) { + assert(oldkeys->dk_kind != DICT_KEYS_SPLIT); + assert(oldkeys->dk_refcnt == 1); #ifdef Py_REF_DEBUG - _Py_RefTotal--; + _Py_RefTotal--; #endif #if PyDict_MAXFREELIST > 0 - struct _Py_dict_state *state = get_dict_state(); + struct _Py_dict_state *state = get_dict_state(); #ifdef Py_DEBUG - // dictresize() must not be called after _PyDict_Fini() - assert(state->keys_numfree != -1); + // dictresize() must not be called after _PyDict_Fini() + assert(state->keys_numfree != -1); #endif - if (DK_LOG_SIZE(oldkeys) == PyDict_LOG_MINSIZE && - DK_IS_UNICODE(oldkeys) && - state->keys_numfree < PyDict_MAXFREELIST) - { - state->keys_free_list[state->keys_numfree++] = oldkeys; - } - else + if (DK_LOG_SIZE(oldkeys) == PyDict_LOG_MINSIZE && + DK_IS_UNICODE(oldkeys) && + state->keys_numfree < PyDict_MAXFREELIST) + { + state->keys_free_list[state->keys_numfree++] = oldkeys; + } + else #endif - { - PyObject_Free(oldkeys); + { + PyObject_Free(oldkeys); + } } } @@ -1844,9 +1836,7 @@ _PyDict_LoadGlobal(PyDictObject *globals, PyDictObject *builtins, PyObject *key) Py_hash_t hash; PyObject *value; - if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) - { + if (!PyUnicode_CheckExact(key) || (hash = unicode_get_hash(key)) == -1) { hash = PyObject_Hash(key); if (hash == -1) return NULL; @@ -1873,9 +1863,7 @@ _PyDict_SetItem_Take2(PyDictObject *mp, PyObject *key, PyObject *value) assert(value); assert(PyDict_Check(mp)); Py_hash_t hash; - if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) - { + if (!PyUnicode_CheckExact(key) || (hash = unicode_get_hash(key)) == -1) { hash = PyObject_Hash(key); if (hash == -1) { Py_DECREF(key); @@ -1998,8 +1986,7 @@ PyDict_DelItem(PyObject *op, PyObject *key) { Py_hash_t hash; assert(key); - if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) { + if (!PyUnicode_CheckExact(key) || (hash = unicode_get_hash(key)) == -1) { hash = PyObject_Hash(key); if (hash == -1) return -1; @@ -2091,12 +2078,13 @@ PyDict_Clear(PyObject *op) mp = ((PyDictObject *)op); oldkeys = mp->ma_keys; oldvalues = mp->ma_values; - if (oldvalues == empty_values) + if (oldkeys == Py_EMPTY_KEYS) { return; + } /* Empty the dict... */ dictkeys_incref(Py_EMPTY_KEYS); mp->ma_keys = Py_EMPTY_KEYS; - mp->ma_values = empty_values; + mp->ma_values = NULL; mp->ma_used = 0; mp->ma_version_tag = DICT_NEXT_VERSION(); /* ...then clear the keys and values */ @@ -2257,8 +2245,7 @@ _PyDict_Pop(PyObject *dict, PyObject *key, PyObject *deflt) _PyErr_SetKeyError(key); return NULL; } - if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) { + if (!PyUnicode_CheckExact(key) || (hash = unicode_get_hash(key)) == -1) { hash = PyObject_Hash(key); if (hash == -1) return NULL; @@ -2372,16 +2359,14 @@ dict_dealloc(PyDictObject *mp) PyObject_GC_UnTrack(mp); Py_TRASHCAN_BEGIN(mp, dict_dealloc) if (values != NULL) { - if (values != empty_values) { - for (i = 0, n = mp->ma_keys->dk_nentries; i < n; i++) { - Py_XDECREF(values->values[i]); - } - free_values(values); + for (i = 0, n = mp->ma_keys->dk_nentries; i < n; i++) { + Py_XDECREF(values->values[i]); } + free_values(values); dictkeys_decref(keys); } else if (keys != NULL) { - assert(keys->dk_refcnt == 1); + assert(keys->dk_refcnt == 1 || keys == Py_EMPTY_KEYS); dictkeys_decref(keys); } #if PyDict_MAXFREELIST > 0 @@ -2498,8 +2483,7 @@ dict_subscript(PyDictObject *mp, PyObject *key) Py_hash_t hash; PyObject *value; - if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) { + if (!PyUnicode_CheckExact(key) || (hash = unicode_get_hash(key)) == -1) { hash = PyObject_Hash(key); if (hash == -1) return NULL; @@ -2862,9 +2846,7 @@ dict_merge(PyObject *a, PyObject *b, int override) dictkeys_decref(mp->ma_keys); mp->ma_keys = keys; if (mp->ma_values != NULL) { - if (mp->ma_values != empty_values) { - free_values(mp->ma_values); - } + free_values(mp->ma_values); mp->ma_values = NULL; } @@ -3257,8 +3239,7 @@ dict___contains__(PyDictObject *self, PyObject *key) Py_ssize_t ix; PyObject *value; - if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) { + if (!PyUnicode_CheckExact(key) || (hash = unicode_get_hash(key)) == -1) { hash = PyObject_Hash(key); if (hash == -1) return NULL; @@ -3289,8 +3270,7 @@ dict_get_impl(PyDictObject *self, PyObject *key, PyObject *default_value) Py_hash_t hash; Py_ssize_t ix; - if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) { + if (!PyUnicode_CheckExact(key) || (hash = unicode_get_hash(key)) == -1) { hash = PyObject_Hash(key); if (hash == -1) return NULL; @@ -3317,8 +3297,7 @@ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj) return NULL; } - if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) { + if (!PyUnicode_CheckExact(key) || (hash = unicode_get_hash(key)) == -1) { hash = PyObject_Hash(key); if (hash == -1) return NULL; @@ -3707,8 +3686,7 @@ PyDict_Contains(PyObject *op, PyObject *key) PyDictObject *mp = (PyDictObject *)op; PyObject *value; - if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) { + if (!PyUnicode_CheckExact(key) || (hash = unicode_get_hash(key)) == -1) { hash = PyObject_Hash(key); if (hash == -1) return -1; @@ -3780,7 +3758,7 @@ dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds) d->ma_version_tag = DICT_NEXT_VERSION(); dictkeys_incref(Py_EMPTY_KEYS); d->ma_keys = Py_EMPTY_KEYS; - d->ma_values = empty_values; + d->ma_values = NULL; ASSERT_CONSISTENT(d); if (type != &PyDict_Type) { From webhook-mailer at python.org Wed Mar 2 08:15:31 2022 From: webhook-mailer at python.org (vstinner) Date: Wed, 02 Mar 2022 13:15:31 -0000 Subject: [Python-checkins] bpo-46848: Move _PyBytes_Find() to internal C API (GH-31642) Message-ID: https://github.com/python/cpython/commit/b6b711a1aa233001c1874af1d920e459b6bf962c commit: b6b711a1aa233001c1874af1d920e459b6bf962c branch: main author: Victor Stinner committer: vstinner date: 2022-03-02T14:15:26+01:00 summary: bpo-46848: Move _PyBytes_Find() to internal C API (GH-31642) Move _PyBytes_Find() and _PyBytes_ReverseFind() functions to the internal C API. bytesobject.c now includes pycore_bytesobject.h. files: M Include/cpython/bytesobject.h M Include/internal/pycore_bytesobject.h M Modules/mmapmodule.c M Objects/bytesobject.c diff --git a/Include/cpython/bytesobject.h b/Include/cpython/bytesobject.h index 38a0fe0af660f..6b3f55224fc55 100644 --- a/Include/cpython/bytesobject.h +++ b/Include/cpython/bytesobject.h @@ -116,22 +116,3 @@ PyAPI_FUNC(void*) _PyBytesWriter_WriteBytes(_PyBytesWriter *writer, void *str, const void *bytes, Py_ssize_t size); - -/* Substring Search. - - Returns the index of the first occurence of - a substring ("needle") in a larger text ("haystack"). - If the needle is not found, return -1. - If the needle is found, add offset to the index. -*/ - -PyAPI_FUNC(Py_ssize_t) -_PyBytes_Find(const char *haystack, Py_ssize_t len_haystack, - const char *needle, Py_ssize_t len_needle, - Py_ssize_t offset); - -/* Same as above, but search right-to-left */ -PyAPI_FUNC(Py_ssize_t) -_PyBytes_ReverseFind(const char *haystack, Py_ssize_t len_haystack, - const char *needle, Py_ssize_t len_needle, - Py_ssize_t offset); diff --git a/Include/internal/pycore_bytesobject.h b/Include/internal/pycore_bytesobject.h index 18d9530aaf41e..8739a759ec36b 100644 --- a/Include/internal/pycore_bytesobject.h +++ b/Include/internal/pycore_bytesobject.h @@ -14,6 +14,25 @@ extern "C" { extern PyStatus _PyBytes_InitTypes(PyInterpreterState *); +/* Substring Search. + + Returns the index of the first occurence of + a substring ("needle") in a larger text ("haystack"). + If the needle is not found, return -1. + If the needle is found, add offset to the index. +*/ + +PyAPI_FUNC(Py_ssize_t) +_PyBytes_Find(const char *haystack, Py_ssize_t len_haystack, + const char *needle, Py_ssize_t len_needle, + Py_ssize_t offset); + +/* Same as above, but search right-to-left */ +PyAPI_FUNC(Py_ssize_t) +_PyBytes_ReverseFind(const char *haystack, Py_ssize_t len_haystack, + const char *needle, Py_ssize_t len_needle, + Py_ssize_t offset); + #ifdef __cplusplus } #endif diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index 6a038e72f93cf..ec36465728c3a 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -24,6 +24,7 @@ #define PY_SSIZE_T_CLEAN #include +#include "pycore_bytesobject.h" // _PyBytes_Find() #include "pycore_fileutils.h" // _Py_stat_struct #include "structmember.h" // PyMemberDef #include // offsetof() diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 4c67b8f7af213..c6160aad790be 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -4,6 +4,7 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() +#include "pycore_bytesobject.h" // _PyBytes_Find() #include "pycore_bytes_methods.h" // _Py_bytes_startswith() #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_format.h" // F_LJUST From webhook-mailer at python.org Wed Mar 2 08:50:43 2022 From: webhook-mailer at python.org (pablogsal) Date: Wed, 02 Mar 2022 13:50:43 -0000 Subject: [Python-checkins] bpo-46756: Fix authorization check in urllib.request (GH-31353) (GH-31572) Message-ID: https://github.com/python/cpython/commit/1c9701a3de0566c085e03dddc14a8508aaae349e commit: 1c9701a3de0566c085e03dddc14a8508aaae349e branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: pablogsal date: 2022-03-02T14:50:32+01:00 summary: bpo-46756: Fix authorization check in urllib.request (GH-31353) (GH-31572) Fix a bug in urllib.request.HTTPPasswordMgr.find_user_password() and urllib.request.HTTPPasswordMgrWithPriorAuth.is_authenticated() which allowed to bypass authorization. For example, access to URI "example.org/foobar" was allowed if the user was authorized for URI "example.org/foo". (cherry picked from commit e2e72567a1c94c548868f6ee5329363e6036057a) Co-authored-by: Serhiy Storchaka Co-authored-by: Serhiy Storchaka files: A Misc/NEWS.d/next/Library/2022-02-15-11-57-53.bpo-46756.AigSPi.rst M Lib/test/test_urllib2.py M Lib/urllib/request.py diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py index b77f90a6ccbf1..b61a40cfd3e8f 100644 --- a/Lib/test/test_urllib2.py +++ b/Lib/test/test_urllib2.py @@ -158,7 +158,6 @@ def test_password_manager(self): self.assertEqual(find_user_pass("Some Realm", "http://example.com/spam"), ('joe', 'password')) - self.assertEqual(find_user_pass("Some Realm", "http://example.com/spam/spam"), ('joe', 'password')) @@ -167,12 +166,29 @@ def test_password_manager(self): add("c", "http://example.com/foo", "foo", "ni") add("c", "http://example.com/bar", "bar", "nini") + add("c", "http://example.com/foo/bar", "foobar", "nibar") self.assertEqual(find_user_pass("c", "http://example.com/foo"), ('foo', 'ni')) - self.assertEqual(find_user_pass("c", "http://example.com/bar"), ('bar', 'nini')) + self.assertEqual(find_user_pass("c", "http://example.com/foo/"), + ('foo', 'ni')) + self.assertEqual(find_user_pass("c", "http://example.com/foo/bar"), + ('foo', 'ni')) + self.assertEqual(find_user_pass("c", "http://example.com/foo/baz"), + ('foo', 'ni')) + self.assertEqual(find_user_pass("c", "http://example.com/foobar"), + (None, None)) + + add("c", "http://example.com/baz/", "baz", "ninini") + + self.assertEqual(find_user_pass("c", "http://example.com/baz"), + (None, None)) + self.assertEqual(find_user_pass("c", "http://example.com/baz/"), + ('baz', 'ninini')) + self.assertEqual(find_user_pass("c", "http://example.com/baz/bar"), + ('baz', 'ninini')) # For the same path, newer password should be considered. @@ -1653,8 +1669,9 @@ def test_basic_prior_auth_auto_send(self): auth_prior_handler.add_password( None, request_url, user, password, is_authenticated=True) - is_auth = pwd_manager.is_authenticated(request_url) - self.assertTrue(is_auth) + self.assertTrue(pwd_manager.is_authenticated(request_url)) + self.assertTrue(pwd_manager.is_authenticated(request_url + '/nested')) + self.assertFalse(pwd_manager.is_authenticated(request_url + 'plain')) opener = OpenerDirector() opener.add_handler(auth_prior_handler) diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index 5f67077fb0a5c..8ff5e3e24a496 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -895,10 +895,10 @@ def is_suburi(self, base, test): return True if base[0] != test[0]: return False - common = posixpath.commonprefix((base[1], test[1])) - if len(common) == len(base[1]): - return True - return False + prefix = base[1] + if prefix[-1:] != '/': + prefix += '/' + return test[1].startswith(prefix) class HTTPPasswordMgrWithDefaultRealm(HTTPPasswordMgr): diff --git a/Misc/NEWS.d/next/Library/2022-02-15-11-57-53.bpo-46756.AigSPi.rst b/Misc/NEWS.d/next/Library/2022-02-15-11-57-53.bpo-46756.AigSPi.rst new file mode 100644 index 0000000000000..1660640c5d3fb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-02-15-11-57-53.bpo-46756.AigSPi.rst @@ -0,0 +1,5 @@ +Fix a bug in :meth:`urllib.request.HTTPPasswordMgr.find_user_password` and +:meth:`urllib.request.HTTPPasswordMgrWithPriorAuth.is_authenticated` which +allowed to bypass authorization. For example, access to URI +``example.org/foobar`` was allowed if the user was authorized for URI +``example.org/foo``. From webhook-mailer at python.org Wed Mar 2 11:05:29 2022 From: webhook-mailer at python.org (vstinner) Date: Wed, 02 Mar 2022 16:05:29 -0000 Subject: [Python-checkins] [3.10] bpo-46633: Skip tests on ASAN and/or MSAN builds (GH-31632) (GH-31634) Message-ID: https://github.com/python/cpython/commit/93264452d952d9ba604bacf2947c2df5dd477931 commit: 93264452d952d9ba604bacf2947c2df5dd477931 branch: 3.10 author: Victor Stinner committer: vstinner date: 2022-03-02T17:05:14+01:00 summary: [3.10] bpo-46633: Skip tests on ASAN and/or MSAN builds (GH-31632) (GH-31634) * Refactor sanitiser skip tests into test.support (GH-30889) * Refactor sanitizer skip tests into test.support (cherry picked from commit b1cb8430504931f7854eac5d32cba74770078a4e) * Add skips to crashing tests under sanitizers instead of manually skipping them (GH-30897) (cherry picked from commit a27505345e34d462139f5f8b6b5e7c9a59955150) * bpo-46633: Skip tests on ASAN and/or MSAN builds (GH-31632) Skip tests on ASAN and/or MSAN builds: * multiprocessing tests * test___all__ * test_concurrent_futures * test_decimal * test_peg_generator * test_tools (cherry picked from commit 9204bb72a2da5885facc747e63d2bd2d654606fe) Co-authored-by: Pablo Galindo Salgado files: M Lib/test/_test_multiprocessing.py M Lib/test/support/__init__.py M Lib/test/test___all__.py M Lib/test/test_concurrent_futures.py M Lib/test/test_crypt.py M Lib/test/test_decimal.py M Lib/test/test_faulthandler.py M Lib/test/test_idle.py M Lib/test/test_io.py M Lib/test/test_peg_generator/__init__.py M Lib/test/test_tix.py M Lib/test/test_tk.py M Lib/test/test_tools/__init__.py M Lib/test/test_ttk_guionly.py diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 3bc5b8f3d79b0..04657c08db92c 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -73,6 +73,12 @@ msvcrt = None +if support.check_sanitizer(address=True): + # bpo-45200: 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") + + def latin(s): return s.encode('latin') diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 44c5bd5820a75..ed6f1979732d3 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -41,7 +41,7 @@ "requires_IEEE_754", "requires_zlib", "anticipate_failure", "load_package_tests", "detect_api_mismatch", "check__all__", "skip_if_buggy_ucrt_strfptime", - "check_disallow_instantiation", + "check_disallow_instantiation", "check_sanitizer", "skip_if_sanitizer", # sys "is_jython", "is_android", "check_impl_detail", "unix_shell", "setswitchinterval", @@ -367,6 +367,41 @@ def wrapper(*args, **kw): return decorator +def check_sanitizer(*, address=False, memory=False, ub=False): + """Returns True if Python is compiled with sanitizer support""" + if not (address or memory or ub): + 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 '' + memory_sanitizer = ( + '-fsanitize=memory' in _cflags or + '--with-memory-sanitizer' in _config_args + ) + address_sanitizer = ( + '-fsanitize=address' in _cflags or + '--with-memory-sanitizer' in _config_args + ) + ub_sanitizer = ( + '-fsanitize=undefined' in _cflags or + '--with-undefined-behavior-sanitizer' in _config_args + ) + return ( + (memory and memory_sanitizer) or + (address and address_sanitizer) or + (ub and ub_sanitizer) + ) + + +def skip_if_sanitizer(reason=None, *, address=False, memory=False, ub=False): + """Decorator raising SkipTest if running with a sanitizer active.""" + if not reason: + reason = 'not working with sanitizers active' + skip = check_sanitizer(address=address, memory=memory, ub=ub) + return unittest.skipIf(skip, reason) + + def system_must_validate_cert(f): """Skip the test on TLS certificate validation failures.""" @functools.wraps(f) diff --git a/Lib/test/test___all__.py b/Lib/test/test___all__.py index 15f42d2d114a6..6368ef02253b6 100644 --- a/Lib/test/test___all__.py +++ b/Lib/test/test___all__.py @@ -5,6 +5,13 @@ import sys +if support.check_sanitizer(address=True, memory=True): + # bpo-46633: test___all__ is skipped because importing some modules + # directly can trigger known problems with ASAN (like tk or crypt). + raise unittest.SkipTest("workaround ASAN build issues on loading tests " + "like tk or crypt") + + class NoAll(RuntimeError): pass diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py index 29e041deeca57..50fa1f189b174 100644 --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -32,6 +32,12 @@ import multiprocessing.util +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 diff --git a/Lib/test/test_crypt.py b/Lib/test/test_crypt.py index 5dc83b4ecbfa0..877c575c5534a 100644 --- a/Lib/test/test_crypt.py +++ b/Lib/test/test_crypt.py @@ -1,8 +1,11 @@ import sys import unittest +from test.support import check_sanitizer try: + if check_sanitizer(address=True, memory=True): + raise unittest.SkipTest("The crypt module SEGFAULTs on ASAN/MSAN builds") import crypt IMPORT_ERROR = None except ImportError as ex: diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index b6173a5ffec96..310c105d9a0e8 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -34,7 +34,7 @@ import locale from test.support import (run_unittest, run_doctest, is_resource_enabled, requires_IEEE_754, requires_docstrings, - requires_legacy_unicode_capi) + requires_legacy_unicode_capi, check_sanitizer) from test.support import (TestFailed, run_with_locale, cpython_only, darwin_malloc_err_warning) @@ -43,17 +43,6 @@ import random import inspect import threading -import sysconfig -_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 -) - -ADDRESS_SANITIZER = ( - '-fsanitize=address' in _cflags -) if sys.platform == 'darwin': @@ -5511,7 +5500,8 @@ def __abs__(self): # Issue 41540: @unittest.skipIf(sys.platform.startswith("aix"), "AIX: default ulimit: test is flaky because of extreme over-allocation") - @unittest.skipIf(MEMORY_SANITIZER or ADDRESS_SANITIZER, "sanitizer defaults to crashing " + @unittest.skipIf(check_sanitizer(address=True, memory=True), + "ASAN/MSAN sanitizer defaults to crashing " "instead of returning NULL for malloc failure.") def test_maxcontext_exact_arith(self): diff --git a/Lib/test/test_faulthandler.py b/Lib/test/test_faulthandler.py index ee3f41a108a14..e0f09e821da0c 100644 --- a/Lib/test/test_faulthandler.py +++ b/Lib/test/test_faulthandler.py @@ -6,10 +6,10 @@ import signal import subprocess import sys -import sysconfig from test import support from test.support import os_helper from test.support import script_helper, is_android +from test.support import skip_if_sanitizer import tempfile import unittest from textwrap import dedent @@ -21,16 +21,6 @@ TIMEOUT = 0.5 MS_WINDOWS = (os.name == 'nt') -_cflags = sysconfig.get_config_var('CFLAGS') or '' -_config_args = sysconfig.get_config_var('CONFIG_ARGS') or '' -UB_SANITIZER = ( - '-fsanitize=undefined' in _cflags or - '--with-undefined-behavior-sanitizer' in _config_args -) -MEMORY_SANITIZER = ( - '-fsanitize=memory' in _cflags or - '--with-memory-sanitizer' in _config_args -) def expected_traceback(lineno1, lineno2, header, min_count=1): @@ -310,8 +300,8 @@ def test_gil_released(self): 3, 'Segmentation fault') - @unittest.skipIf(UB_SANITIZER or MEMORY_SANITIZER, - "sanitizer builds change crashing process output.") + @skip_if_sanitizer(memory=True, ub=True, reason="sanitizer " + "builds change crashing process output.") @skip_segfault_on_android def test_enable_file(self): with temporary_filename() as filename: @@ -327,8 +317,8 @@ def test_enable_file(self): @unittest.skipIf(sys.platform == "win32", "subprocess doesn't support pass_fds on Windows") - @unittest.skipIf(UB_SANITIZER or MEMORY_SANITIZER, - "sanitizer builds change crashing process output.") + @skip_if_sanitizer(memory=True, ub=True, reason="sanitizer " + "builds change crashing process output.") @skip_segfault_on_android def test_enable_fd(self): with tempfile.TemporaryFile('wb+') as fp: diff --git a/Lib/test/test_idle.py b/Lib/test/test_idle.py index 8756b766334e8..b94b18a541a70 100644 --- a/Lib/test/test_idle.py +++ b/Lib/test/test_idle.py @@ -1,5 +1,9 @@ import unittest from test.support.import_helper import import_module +from test.support import check_sanitizer + +if check_sanitizer(address=True, memory=True): + raise unittest.SkipTest("Tests involvin libX11 can SEGFAULT on ASAN/MSAN builds") # Skip test_idle if _tkinter wasn't built, if tkinter is missing, # if tcl/tk is not the 8.5+ needed for ttk widgets, diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 35013b6a090cb..fb83762cb6af4 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -28,7 +28,6 @@ import random import signal import sys -import sysconfig import textwrap import threading import time @@ -44,6 +43,7 @@ from test.support import os_helper from test.support import threading_helper from test.support import warnings_helper +from test.support import skip_if_sanitizer from test.support.os_helper import FakePath import codecs @@ -66,17 +66,6 @@ def byteslike(*pos, **kw): class EmptyStruct(ctypes.Structure): pass -_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 -) - -ADDRESS_SANITIZER = ( - '-fsanitize=address' in _cflags -) - # Does io.IOBase finalizer log the exception if the close() method fails? # The exception is ignored silently by default in release build. IOBASE_EMITS_UNRAISABLE = (hasattr(sys, "gettotalrefcount") or sys.flags.dev_mode) @@ -1550,8 +1539,8 @@ def test_truncate_on_read_only(self): class CBufferedReaderTest(BufferedReaderTest, SizeofTest): tp = io.BufferedReader - @unittest.skipIf(MEMORY_SANITIZER or ADDRESS_SANITIZER, "sanitizer defaults to crashing " - "instead of returning NULL for malloc failure.") + @skip_if_sanitizer(memory=True, address=True, reason= "sanitizer defaults to crashing " + "instead of returning NULL for malloc failure.") def test_constructor(self): BufferedReaderTest.test_constructor(self) # The allocation can succeed on 32-bit builds, e.g. with more @@ -1915,8 +1904,8 @@ def test_slow_close_from_thread(self): class CBufferedWriterTest(BufferedWriterTest, SizeofTest): tp = io.BufferedWriter - @unittest.skipIf(MEMORY_SANITIZER or ADDRESS_SANITIZER, "sanitizer defaults to crashing " - "instead of returning NULL for malloc failure.") + @skip_if_sanitizer(memory=True, address=True, reason= "sanitizer defaults to crashing " + "instead of returning NULL for malloc failure.") def test_constructor(self): BufferedWriterTest.test_constructor(self) # The allocation can succeed on 32-bit builds, e.g. with more @@ -2414,8 +2403,8 @@ def test_interleaved_readline_write(self): class CBufferedRandomTest(BufferedRandomTest, SizeofTest): tp = io.BufferedRandom - @unittest.skipIf(MEMORY_SANITIZER or ADDRESS_SANITIZER, "sanitizer defaults to crashing " - "instead of returning NULL for malloc failure.") + @skip_if_sanitizer(memory=True, address=True, reason= "sanitizer defaults to crashing " + "instead of returning NULL for malloc failure.") def test_constructor(self): BufferedRandomTest.test_constructor(self) # The allocation can succeed on 32-bit builds, e.g. with more diff --git a/Lib/test/test_peg_generator/__init__.py b/Lib/test/test_peg_generator/__init__.py index fa855f2104c58..77f72fcc7c6e3 100644 --- a/Lib/test/test_peg_generator/__init__.py +++ b/Lib/test/test_peg_generator/__init__.py @@ -1,7 +1,15 @@ -import os - +import os.path +import unittest +from test import support from test.support import load_package_tests + +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") + + # Load all tests in package def load_tests(*args): return load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_tix.py b/Lib/test/test_tix.py index 8a60c7c8e1fbd..454baeb38a934 100644 --- a/Lib/test/test_tix.py +++ b/Lib/test/test_tix.py @@ -2,6 +2,11 @@ import unittest from test import support from test.support import import_helper +from test.support import check_sanitizer + +if check_sanitizer(address=True, memory=True): + raise unittest.SkipTest("Tests involvin libX11 can SEGFAULT on ASAN/MSAN builds") + # Skip this test if the _tkinter module wasn't built. _tkinter = import_helper.import_module('_tkinter') diff --git a/Lib/test/test_tk.py b/Lib/test/test_tk.py index 69cc2322cd9aa..8f90cbaba9f7c 100644 --- a/Lib/test/test_tk.py +++ b/Lib/test/test_tk.py @@ -1,5 +1,11 @@ +import unittest from test import support from test.support import import_helper +from test.support import check_sanitizer + +if check_sanitizer(address=True, memory=True): + raise unittest.SkipTest("Tests involvin libX11 can SEGFAULT on ASAN/MSAN builds") + # Skip test if _tkinter wasn't built. import_helper.import_module('_tkinter') diff --git a/Lib/test/test_tools/__init__.py b/Lib/test/test_tools/__init__.py index 61af6578e0953..34b0d3b8fb3eb 100644 --- a/Lib/test/test_tools/__init__.py +++ b/Lib/test/test_tools/__init__.py @@ -6,6 +6,13 @@ from test import support from test.support import import_helper + +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") + + basepath = os.path.normpath( os.path.dirname( # os.path.dirname( # Lib diff --git a/Lib/test/test_ttk_guionly.py b/Lib/test/test_ttk_guionly.py index 8f59839d066e6..c4919045d75cb 100644 --- a/Lib/test/test_ttk_guionly.py +++ b/Lib/test/test_ttk_guionly.py @@ -1,6 +1,10 @@ import unittest from test import support from test.support import import_helper +from test.support import check_sanitizer + +if check_sanitizer(address=True, memory=True): + raise unittest.SkipTest("Tests involvin libX11 can SEGFAULT on ASAN/MSAN builds") # Skip this test if _tkinter wasn't built. import_helper.import_module('_tkinter') From webhook-mailer at python.org Wed Mar 2 12:12:55 2022 From: webhook-mailer at python.org (vstinner) Date: Wed, 02 Mar 2022 17:12:55 -0000 Subject: [Python-checkins] [3.10] bpo-46633: Skip tests on ASAN and/or MSAN builds (GH-31632) (GH-31634) (GH-31644) Message-ID: https://github.com/python/cpython/commit/359bc392ba2b8f2acca223426c8210bb74f724c6 commit: 359bc392ba2b8f2acca223426c8210bb74f724c6 branch: 3.9 author: Victor Stinner committer: vstinner date: 2022-03-02T18:12:26+01:00 summary: [3.10] bpo-46633: Skip tests on ASAN and/or MSAN builds (GH-31632) (GH-31634) (GH-31644) * Refactor sanitiser skip tests into test.support (GH-30889) * Refactor sanitizer skip tests into test.support (cherry picked from commit b1cb8430504931f7854eac5d32cba74770078a4e) * Add skips to crashing tests under sanitizers instead of manually skipping them (GH-30897) (cherry picked from commit a27505345e34d462139f5f8b6b5e7c9a59955150) * bpo-46633: Skip tests on ASAN and/or MSAN builds (GH-31632) Skip tests on ASAN and/or MSAN builds: * multiprocessing tests * test___all__ * test_concurrent_futures * test_decimal * test_peg_generator * test_tools (cherry picked from commit 9204bb72a2da5885facc747e63d2bd2d654606fe) Co-authored-by: Pablo Galindo Salgado (cherry picked from commit 93264452d952d9ba604bacf2947c2df5dd477931) files: M Lib/test/_test_multiprocessing.py M Lib/test/support/__init__.py M Lib/test/test___all__.py M Lib/test/test_concurrent_futures.py M Lib/test/test_crypt.py M Lib/test/test_decimal.py M Lib/test/test_faulthandler.py M Lib/test/test_idle.py M Lib/test/test_io.py M Lib/test/test_peg_generator/__init__.py M Lib/test/test_tix.py M Lib/test/test_tk.py M Lib/test/test_tools/__init__.py M Lib/test/test_ttk_guionly.py diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 3ae0cb976863d..bcbf5676b2e3a 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -69,6 +69,12 @@ msvcrt = None +if support.check_sanitizer(address=True): + # bpo-45200: 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") + + def latin(s): return s.encode('latin') diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 53804f13fc8a2..c4115a850b2e4 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -54,7 +54,7 @@ "requires_IEEE_754", "skip_unless_xattr", "requires_zlib", "anticipate_failure", "load_package_tests", "detect_api_mismatch", "check__all__", "skip_if_buggy_ucrt_strfptime", - "ignore_warnings", + "ignore_warnings", "check_sanitizer", "skip_if_sanitizer", # sys "is_jython", "is_android", "check_impl_detail", "unix_shell", "setswitchinterval", @@ -644,6 +644,41 @@ def wrapper(*args, **kw): return decorator +def check_sanitizer(*, address=False, memory=False, ub=False): + """Returns True if Python is compiled with sanitizer support""" + if not (address or memory or ub): + 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 '' + memory_sanitizer = ( + '-fsanitize=memory' in _cflags or + '--with-memory-sanitizer' in _config_args + ) + address_sanitizer = ( + '-fsanitize=address' in _cflags or + '--with-memory-sanitizer' in _config_args + ) + ub_sanitizer = ( + '-fsanitize=undefined' in _cflags or + '--with-undefined-behavior-sanitizer' in _config_args + ) + return ( + (memory and memory_sanitizer) or + (address and address_sanitizer) or + (ub and ub_sanitizer) + ) + + +def skip_if_sanitizer(reason=None, *, address=False, memory=False, ub=False): + """Decorator raising SkipTest if running with a sanitizer active.""" + if not reason: + reason = 'not working with sanitizers active' + skip = check_sanitizer(address=address, memory=memory, ub=ub) + return unittest.skipIf(skip, reason) + + def system_must_validate_cert(f): """Skip the test on TLS certificate validation failures.""" @functools.wraps(f) diff --git a/Lib/test/test___all__.py b/Lib/test/test___all__.py index 0ba243ee4e74e..7e1f80f251256 100644 --- a/Lib/test/test___all__.py +++ b/Lib/test/test___all__.py @@ -4,6 +4,13 @@ import sys +if support.check_sanitizer(address=True, memory=True): + # bpo-46633: test___all__ is skipped because importing some modules + # directly can trigger known problems with ASAN (like tk or crypt). + raise unittest.SkipTest("workaround ASAN build issues on loading tests " + "like tk or crypt") + + class NoAll(RuntimeError): pass diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py index d693fb4ee199b..d421b02754cf5 100644 --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -32,6 +32,12 @@ import multiprocessing.util +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 diff --git a/Lib/test/test_crypt.py b/Lib/test/test_crypt.py index 5dc83b4ecbfa0..877c575c5534a 100644 --- a/Lib/test/test_crypt.py +++ b/Lib/test/test_crypt.py @@ -1,8 +1,11 @@ import sys import unittest +from test.support import check_sanitizer try: + if check_sanitizer(address=True, memory=True): + raise unittest.SkipTest("The crypt module SEGFAULTs on ASAN/MSAN builds") import crypt IMPORT_ERROR = None except ImportError as ex: diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index 3f30a935d583c..58f4df3060169 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -33,24 +33,14 @@ import numbers import locale from test.support import (run_unittest, run_doctest, is_resource_enabled, - requires_IEEE_754, requires_docstrings) -from test.support import (import_fresh_module, TestFailed, + requires_IEEE_754, requires_docstrings, + import_fresh_module, TestFailed, run_with_locale, cpython_only, - darwin_malloc_err_warning) + darwin_malloc_err_warning, + check_sanitizer) import random import inspect import threading -import sysconfig -_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 -) - -ADDRESS_SANITIZER = ( - '-fsanitize=address' in _cflags -) if sys.platform == 'darwin': @@ -5497,7 +5487,8 @@ def __abs__(self): # Issue 41540: @unittest.skipIf(sys.platform.startswith("aix"), "AIX: default ulimit: test is flaky because of extreme over-allocation") - @unittest.skipIf(MEMORY_SANITIZER or ADDRESS_SANITIZER, "sanitizer defaults to crashing " + @unittest.skipIf(check_sanitizer(address=True, memory=True), + "ASAN/MSAN sanitizer defaults to crashing " "instead of returning NULL for malloc failure.") def test_maxcontext_exact_arith(self): diff --git a/Lib/test/test_faulthandler.py b/Lib/test/test_faulthandler.py index c64afe88c25d6..2f8f5eec475f1 100644 --- a/Lib/test/test_faulthandler.py +++ b/Lib/test/test_faulthandler.py @@ -5,9 +5,9 @@ import signal import subprocess import sys -import sysconfig from test import support from test.support import script_helper, is_android +from test.support import skip_if_sanitizer import tempfile import unittest from textwrap import dedent @@ -19,16 +19,6 @@ TIMEOUT = 0.5 MS_WINDOWS = (os.name == 'nt') -_cflags = sysconfig.get_config_var('CFLAGS') or '' -_config_args = sysconfig.get_config_var('CONFIG_ARGS') or '' -UB_SANITIZER = ( - '-fsanitize=undefined' in _cflags or - '--with-undefined-behavior-sanitizer' in _config_args -) -MEMORY_SANITIZER = ( - '-fsanitize=memory' in _cflags or - '--with-memory-sanitizer' in _config_args -) def expected_traceback(lineno1, lineno2, header, min_count=1): @@ -271,8 +261,8 @@ def test_gil_released(self): 3, 'Segmentation fault') - @unittest.skipIf(UB_SANITIZER or MEMORY_SANITIZER, - "sanitizer builds change crashing process output.") + @skip_if_sanitizer(memory=True, ub=True, reason="sanitizer " + "builds change crashing process output.") @skip_segfault_on_android def test_enable_file(self): with temporary_filename() as filename: @@ -288,8 +278,8 @@ def test_enable_file(self): @unittest.skipIf(sys.platform == "win32", "subprocess doesn't support pass_fds on Windows") - @unittest.skipIf(UB_SANITIZER or MEMORY_SANITIZER, - "sanitizer builds change crashing process output.") + @skip_if_sanitizer(memory=True, ub=True, reason="sanitizer " + "builds change crashing process output.") @skip_segfault_on_android def test_enable_fd(self): with tempfile.TemporaryFile('wb+') as fp: diff --git a/Lib/test/test_idle.py b/Lib/test/test_idle.py index 310b72c1d72e7..c747b02f64306 100644 --- a/Lib/test/test_idle.py +++ b/Lib/test/test_idle.py @@ -1,5 +1,9 @@ import unittest from test.support import import_module +from test.support import check_sanitizer + +if check_sanitizer(address=True, memory=True): + raise unittest.SkipTest("Tests involvin libX11 can SEGFAULT on ASAN/MSAN builds") # Skip test_idle if _tkinter wasn't built, if tkinter is missing, # if tcl/tk is not the 8.5+ needed for ttk widgets, diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 49463e54e3c72..feee861830e40 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -28,7 +28,6 @@ import random import signal import sys -import sysconfig import textwrap import threading import time @@ -40,7 +39,7 @@ from test import support from test.support.script_helper import ( assert_python_ok, assert_python_failure, run_python_until_end) -from test.support import FakePath +from test.support import FakePath, skip_if_sanitizer import codecs import io # C implementation of io @@ -62,17 +61,6 @@ def byteslike(*pos, **kw): class EmptyStruct(ctypes.Structure): pass -_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 -) - -ADDRESS_SANITIZER = ( - '-fsanitize=address' in _cflags -) - # Does io.IOBase finalizer log the exception if the close() method fails? # The exception is ignored silently by default in release build. IOBASE_EMITS_UNRAISABLE = (hasattr(sys, "gettotalrefcount") or sys.flags.dev_mode) @@ -1543,8 +1531,8 @@ def test_truncate_on_read_only(self): class CBufferedReaderTest(BufferedReaderTest, SizeofTest): tp = io.BufferedReader - @unittest.skipIf(MEMORY_SANITIZER or ADDRESS_SANITIZER, "sanitizer defaults to crashing " - "instead of returning NULL for malloc failure.") + @skip_if_sanitizer(memory=True, address=True, reason= "sanitizer defaults to crashing " + "instead of returning NULL for malloc failure.") def test_constructor(self): BufferedReaderTest.test_constructor(self) # The allocation can succeed on 32-bit builds, e.g. with more @@ -1892,8 +1880,8 @@ def test_slow_close_from_thread(self): class CBufferedWriterTest(BufferedWriterTest, SizeofTest): tp = io.BufferedWriter - @unittest.skipIf(MEMORY_SANITIZER or ADDRESS_SANITIZER, "sanitizer defaults to crashing " - "instead of returning NULL for malloc failure.") + @skip_if_sanitizer(memory=True, address=True, reason= "sanitizer defaults to crashing " + "instead of returning NULL for malloc failure.") def test_constructor(self): BufferedWriterTest.test_constructor(self) # The allocation can succeed on 32-bit builds, e.g. with more @@ -2391,8 +2379,8 @@ def test_interleaved_readline_write(self): class CBufferedRandomTest(BufferedRandomTest, SizeofTest): tp = io.BufferedRandom - @unittest.skipIf(MEMORY_SANITIZER or ADDRESS_SANITIZER, "sanitizer defaults to crashing " - "instead of returning NULL for malloc failure.") + @skip_if_sanitizer(memory=True, address=True, reason= "sanitizer defaults to crashing " + "instead of returning NULL for malloc failure.") def test_constructor(self): BufferedRandomTest.test_constructor(self) # The allocation can succeed on 32-bit builds, e.g. with more diff --git a/Lib/test/test_peg_generator/__init__.py b/Lib/test/test_peg_generator/__init__.py index fa855f2104c58..77f72fcc7c6e3 100644 --- a/Lib/test/test_peg_generator/__init__.py +++ b/Lib/test/test_peg_generator/__init__.py @@ -1,7 +1,15 @@ -import os - +import os.path +import unittest +from test import support from test.support import load_package_tests + +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") + + # Load all tests in package def load_tests(*args): return load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_tix.py b/Lib/test/test_tix.py index e6ea3d07444ce..9dbf9b240b4fc 100644 --- a/Lib/test/test_tix.py +++ b/Lib/test/test_tix.py @@ -1,7 +1,12 @@ import unittest from test import support +from test.support import check_sanitizer import sys +if check_sanitizer(address=True, memory=True): + raise unittest.SkipTest("Tests involvin libX11 can SEGFAULT on ASAN/MSAN builds") + + # Skip this test if the _tkinter module wasn't built. _tkinter = support.import_module('_tkinter') diff --git a/Lib/test/test_tk.py b/Lib/test/test_tk.py index d45acbfc6e1a8..577ed133ee907 100644 --- a/Lib/test/test_tk.py +++ b/Lib/test/test_tk.py @@ -1,4 +1,10 @@ +import unittest from test import support +from test.support import check_sanitizer + +if check_sanitizer(address=True, memory=True): + raise unittest.SkipTest("Tests involvin libX11 can SEGFAULT on ASAN/MSAN builds") + # Skip test if _tkinter wasn't built. support.import_module('_tkinter') diff --git a/Lib/test/test_tools/__init__.py b/Lib/test/test_tools/__init__.py index eb9acad677d58..3b5c5b2df5f1d 100644 --- a/Lib/test/test_tools/__init__.py +++ b/Lib/test/test_tools/__init__.py @@ -5,6 +5,13 @@ import unittest from test import support + +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") + + basepath = os.path.normpath( os.path.dirname( # os.path.dirname( # Lib diff --git a/Lib/test/test_ttk_guionly.py b/Lib/test/test_ttk_guionly.py index 0b57d5a0d6c25..e62636637c35f 100644 --- a/Lib/test/test_ttk_guionly.py +++ b/Lib/test/test_ttk_guionly.py @@ -1,5 +1,9 @@ import unittest from test import support +from test.support import check_sanitizer + +if check_sanitizer(address=True, memory=True): + raise unittest.SkipTest("Tests involvin libX11 can SEGFAULT on ASAN/MSAN builds") # Skip this test if _tkinter wasn't built. support.import_module('_tkinter') From webhook-mailer at python.org Wed Mar 2 14:03:47 2022 From: webhook-mailer at python.org (iritkatriel) Date: Wed, 02 Mar 2022 19:03:47 -0000 Subject: [Python-checkins] bpo-45492: Corrected documentation for co_names in inspect library doc (GH-31456) Message-ID: https://github.com/python/cpython/commit/3257d49d236e5f3453fe9d2fd8338bcdfe9756b7 commit: 3257d49d236e5f3453fe9d2fd8338bcdfe9756b7 branch: main author: slateny <46876382+slateny at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-03-02T19:03:38Z summary: bpo-45492: Corrected documentation for co_names in inspect library doc (GH-31456) files: M Doc/library/inspect.rst diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index 7a6dc9c0337d8..8ee2c070cccf5 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -191,8 +191,9 @@ attributes: | | | which this code object | | | | was defined | +-----------+-------------------+---------------------------+ -| | co_names | tuple of names of local | -| | | variables | +| | co_names | tuple of names other | +| | | than arguments and | +| | | function locals | +-----------+-------------------+---------------------------+ | | co_nlocals | number of local variables | +-----------+-------------------+---------------------------+ From webhook-mailer at python.org Wed Mar 2 14:37:30 2022 From: webhook-mailer at python.org (iritkatriel) Date: Wed, 02 Mar 2022 19:37:30 -0000 Subject: [Python-checkins] [3.10] bpo-45492: Corrected documentation for co_names in inspect library doc (GH-31456). (GH-31645) Message-ID: https://github.com/python/cpython/commit/eb65e46b9b28103767c115ccf71a97a9f4237d4c commit: eb65e46b9b28103767c115ccf71a97a9f4237d4c branch: 3.10 author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-03-02T19:37:17Z summary: [3.10] bpo-45492: Corrected documentation for co_names in inspect library doc (GH-31456). (GH-31645) (cherry picked from commit 3257d49d236e5f3453fe9d2fd8338bcdfe9756b7) Co-authored-by: slateny <46876382+slateny at users.noreply.github.com> Co-authored-by: slateny <46876382+slateny at users.noreply.github.com> files: M Doc/library/inspect.rst diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index ed33cbb8a61ab..d7ef2adf7281b 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -187,8 +187,9 @@ attributes: | | co_name | name with which this code | | | | object was defined | +-----------+-------------------+---------------------------+ -| | co_names | tuple of names of local | -| | | variables | +| | co_names | tuple of names other | +| | | than arguments and | +| | | function locals | +-----------+-------------------+---------------------------+ | | co_nlocals | number of local variables | +-----------+-------------------+---------------------------+ From webhook-mailer at python.org Wed Mar 2 17:24:18 2022 From: webhook-mailer at python.org (brettcannon) Date: Wed, 02 Mar 2022 22:24:18 -0000 Subject: [Python-checkins] bpo-46860: Respect `--with-suffix` on case-insensitive file systems (GH-31593) Message-ID: https://github.com/python/cpython/commit/50ec3453c50c490eca7e990103c79671bd08ab2e commit: 50ec3453c50c490eca7e990103c79671bd08ab2e branch: main author: Brett Cannon committer: brettcannon date: 2022-03-02T14:23:59-08:00 summary: bpo-46860: Respect `--with-suffix` on case-insensitive file systems (GH-31593) Previously, case-insensitive file systems were forced to use `.exe` as the file suffix no matter what `--with-suffix` was set to. files: A Misc/NEWS.d/next/Build/2022-02-25-16-19-40.bpo-46860.jfciLG.rst M configure M configure.ac diff --git a/Misc/NEWS.d/next/Build/2022-02-25-16-19-40.bpo-46860.jfciLG.rst b/Misc/NEWS.d/next/Build/2022-02-25-16-19-40.bpo-46860.jfciLG.rst new file mode 100644 index 0000000000000..7eab15db335e4 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2022-02-25-16-19-40.bpo-46860.jfciLG.rst @@ -0,0 +1 @@ +Respect `--with-suffix` when building on case-insensitive file systems. diff --git a/configure b/configure index 49d5abeac3024..07ecb804c1bd0 100755 --- a/configure +++ b/configure @@ -6296,7 +6296,7 @@ if test ! -d CaseSensitiveTestDir; then mkdir CaseSensitiveTestDir fi -if test -d casesensitivetestdir +if test -d casesensitivetestdir && test -z "$EXEEXT" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } diff --git a/configure.ac b/configure.ac index 83dd854248b42..fedec52f05a75 100644 --- a/configure.ac +++ b/configure.ac @@ -1112,7 +1112,7 @@ if test ! -d CaseSensitiveTestDir; then mkdir CaseSensitiveTestDir fi -if test -d casesensitivetestdir +if test -d casesensitivetestdir && test -z "$EXEEXT" then AC_MSG_RESULT(yes) BUILDEXEEXT=.exe From webhook-mailer at python.org Wed Mar 2 20:15:11 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Thu, 03 Mar 2022 01:15:11 -0000 Subject: [Python-checkins] bpo-46643: Fix stringized P.args/P.kwargs with get_type_hints (GH-31238) Message-ID: https://github.com/python/cpython/commit/75d2d945b4e28ca34506b2d4902367b61a8dff82 commit: 75d2d945b4e28ca34506b2d4902367b61a8dff82 branch: main author: Gregory Beauregard committer: JelleZijlstra date: 2022-03-02T17:14:52-08:00 summary: bpo-46643: Fix stringized P.args/P.kwargs with get_type_hints (GH-31238) files: A Misc/NEWS.d/next/Library/2022-02-09-22-40-11.bpo-46643.aBlIx1.rst M Lib/test/test_typing.py M Lib/typing.py diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 8fcc24c25eb95..bd9920436223c 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -5187,6 +5187,18 @@ def test_args_kwargs(self): self.assertEqual(repr(P.args), "P.args") self.assertEqual(repr(P.kwargs), "P.kwargs") + def test_stringized(self): + P = ParamSpec('P') + class C(Generic[P]): + func: Callable["P", int] + def foo(self, *args: "P.args", **kwargs: "P.kwargs"): + pass + + self.assertEqual(gth(C, globals(), locals()), {"func": Callable[P, int]}) + self.assertEqual( + gth(C.foo, globals(), locals()), {"args": P.args, "kwargs": P.kwargs} + ) + def test_user_generics(self): T = TypeVar("T") P = ParamSpec("P") diff --git a/Lib/typing.py b/Lib/typing.py index 9d668b3cf4a2a..6e0c68c842420 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -181,7 +181,8 @@ def _type_check(arg, msg, is_argument=True, module=None, *, allow_special_forms= return arg if isinstance(arg, _SpecialForm) or arg in (Generic, Protocol): raise TypeError(f"Plain {arg} is not valid as type argument") - if isinstance(arg, (type, TypeVar, ForwardRef, types.UnionType, ParamSpec)): + if isinstance(arg, (type, TypeVar, ForwardRef, types.UnionType, ParamSpec, + ParamSpecArgs, ParamSpecKwargs)): return arg if not callable(arg): raise TypeError(f"{msg} Got {arg!r:.100}.") diff --git a/Misc/NEWS.d/next/Library/2022-02-09-22-40-11.bpo-46643.aBlIx1.rst b/Misc/NEWS.d/next/Library/2022-02-09-22-40-11.bpo-46643.aBlIx1.rst new file mode 100644 index 0000000000000..e8b4d66e943f6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-02-09-22-40-11.bpo-46643.aBlIx1.rst @@ -0,0 +1 @@ +In :func:`typing.get_type_hints`, support evaluating stringified ``ParamSpecArgs`` and ``ParamSpecKwargs`` annotations. Patch by Gregory Beauregard. \ No newline at end of file From webhook-mailer at python.org Wed Mar 2 20:21:45 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Thu, 03 Mar 2022 01:21:45 -0000 Subject: [Python-checkins] bpo-21910: Clarify docs for codecs writelines method (GH-31245) Message-ID: https://github.com/python/cpython/commit/a8c87a239ee1414d6dd0b062fe9ec3e5b0c50cb8 commit: a8c87a239ee1414d6dd0b062fe9ec3e5b0c50cb8 branch: main author: slateny <46876382+slateny at users.noreply.github.com> committer: JelleZijlstra date: 2022-03-02T17:21:41-08:00 summary: bpo-21910: Clarify docs for codecs writelines method (GH-31245) Co-authored-by: Jelle Zijlstra files: M Doc/library/codecs.rst diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst index 949288b7c6d9b..76710974dd427 100644 --- a/Doc/library/codecs.rst +++ b/Doc/library/codecs.rst @@ -697,8 +697,9 @@ compatible with the Python codec registry. .. method:: writelines(list) - Writes the concatenated list of strings to the stream (possibly by reusing - the :meth:`write` method). The standard bytes-to-bytes codecs + Writes the concatenated iterable of strings to the stream (possibly by reusing + the :meth:`write` method). Infinite or + very large iterables are not supported. The standard bytes-to-bytes codecs do not support this method. From webhook-mailer at python.org Wed Mar 2 20:43:04 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 03 Mar 2022 01:43:04 -0000 Subject: [Python-checkins] bpo-21910: Clarify docs for codecs writelines method (GH-31245) Message-ID: https://github.com/python/cpython/commit/60b561c246da2073672a016340457e4534dfdf5b commit: 60b561c246da2073672a016340457e4534dfdf5b branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-02T17:43:00-08:00 summary: bpo-21910: Clarify docs for codecs writelines method (GH-31245) Co-authored-by: Jelle Zijlstra (cherry picked from commit a8c87a239ee1414d6dd0b062fe9ec3e5b0c50cb8) Co-authored-by: slateny <46876382+slateny at users.noreply.github.com> files: M Doc/library/codecs.rst diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst index ef71832bcef1d..1a1ce9237b010 100644 --- a/Doc/library/codecs.rst +++ b/Doc/library/codecs.rst @@ -694,8 +694,9 @@ compatible with the Python codec registry. .. method:: writelines(list) - Writes the concatenated list of strings to the stream (possibly by reusing - the :meth:`write` method). The standard bytes-to-bytes codecs + Writes the concatenated iterable of strings to the stream (possibly by reusing + the :meth:`write` method). Infinite or + very large iterables are not supported. The standard bytes-to-bytes codecs do not support this method. From webhook-mailer at python.org Wed Mar 2 20:45:51 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 03 Mar 2022 01:45:51 -0000 Subject: [Python-checkins] bpo-21910: Clarify docs for codecs writelines method (GH-31245) Message-ID: https://github.com/python/cpython/commit/cf8aff6319794807aa578215710e6caa4479516f commit: cf8aff6319794807aa578215710e6caa4479516f branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-02T17:45:36-08:00 summary: bpo-21910: Clarify docs for codecs writelines method (GH-31245) Co-authored-by: Jelle Zijlstra (cherry picked from commit a8c87a239ee1414d6dd0b062fe9ec3e5b0c50cb8) Co-authored-by: slateny <46876382+slateny at users.noreply.github.com> files: M Doc/library/codecs.rst diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst index 2f7497c0c4934..3386208d5ef5f 100644 --- a/Doc/library/codecs.rst +++ b/Doc/library/codecs.rst @@ -691,8 +691,9 @@ compatible with the Python codec registry. .. method:: writelines(list) - Writes the concatenated list of strings to the stream (possibly by reusing - the :meth:`write` method). The standard bytes-to-bytes codecs + Writes the concatenated iterable of strings to the stream (possibly by reusing + the :meth:`write` method). Infinite or + very large iterables are not supported. The standard bytes-to-bytes codecs do not support this method. From webhook-mailer at python.org Wed Mar 2 21:27:00 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 03 Mar 2022 02:27:00 -0000 Subject: [Python-checkins] bpo-46643: Fix stringized P.args/P.kwargs with get_type_hints (GH-31238) Message-ID: https://github.com/python/cpython/commit/257f5be7f7fad37d0db6c145e534e5b7289d8804 commit: 257f5be7f7fad37d0db6c145e534e5b7289d8804 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-02T18:26:50-08:00 summary: bpo-46643: Fix stringized P.args/P.kwargs with get_type_hints (GH-31238) (cherry picked from commit 75d2d945b4e28ca34506b2d4902367b61a8dff82) Co-authored-by: Gregory Beauregard files: A Misc/NEWS.d/next/Library/2022-02-09-22-40-11.bpo-46643.aBlIx1.rst M Lib/test/test_typing.py M Lib/typing.py diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 8ced27824205d..f3ebece4b4a7f 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -4865,6 +4865,18 @@ def test_args_kwargs(self): self.assertEqual(repr(P.args), "P.args") self.assertEqual(repr(P.kwargs), "P.kwargs") + def test_stringized(self): + P = ParamSpec('P') + class C(Generic[P]): + func: Callable["P", int] + def foo(self, *args: "P.args", **kwargs: "P.kwargs"): + pass + + self.assertEqual(gth(C, globals(), locals()), {"func": Callable[P, int]}) + self.assertEqual( + gth(C.foo, globals(), locals()), {"args": P.args, "kwargs": P.kwargs} + ) + def test_user_generics(self): T = TypeVar("T") P = ParamSpec("P") diff --git a/Lib/typing.py b/Lib/typing.py index 5d900dd6c33ab..4519cdbc951c9 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -169,7 +169,8 @@ def _type_check(arg, msg, is_argument=True, module=None, *, allow_special_forms= return arg if isinstance(arg, _SpecialForm) or arg in (Generic, Protocol): raise TypeError(f"Plain {arg} is not valid as type argument") - if isinstance(arg, (type, TypeVar, ForwardRef, types.UnionType, ParamSpec)): + if isinstance(arg, (type, TypeVar, ForwardRef, types.UnionType, ParamSpec, + ParamSpecArgs, ParamSpecKwargs)): return arg if not callable(arg): raise TypeError(f"{msg} Got {arg!r:.100}.") diff --git a/Misc/NEWS.d/next/Library/2022-02-09-22-40-11.bpo-46643.aBlIx1.rst b/Misc/NEWS.d/next/Library/2022-02-09-22-40-11.bpo-46643.aBlIx1.rst new file mode 100644 index 0000000000000..e8b4d66e943f6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-02-09-22-40-11.bpo-46643.aBlIx1.rst @@ -0,0 +1 @@ +In :func:`typing.get_type_hints`, support evaluating stringified ``ParamSpecArgs`` and ``ParamSpecKwargs`` annotations. Patch by Gregory Beauregard. \ No newline at end of file From webhook-mailer at python.org Wed Mar 2 23:06:41 2022 From: webhook-mailer at python.org (methane) Date: Thu, 03 Mar 2022 04:06:41 -0000 Subject: [Python-checkins] bpo-40116: dict: Add regression test for iteration order. (GH-31550) Message-ID: https://github.com/python/cpython/commit/4f74052b455a54ac736f38973693aeea2ec14116 commit: 4f74052b455a54ac736f38973693aeea2ec14116 branch: main author: Inada Naoki committer: methane date: 2022-03-03T13:06:29+09:00 summary: bpo-40116: dict: Add regression test for iteration order. (GH-31550) files: A Misc/NEWS.d/next/Core and Builtins/2022-02-24-16-34-17.bpo-40116.AeVGG2.rst M Lib/test/test_dict.py M Misc/NEWS.d/next/Library/2022-02-09-22-40-11.bpo-46643.aBlIx1.rst diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 66f5d56deeaaf..e60ae4309cbc1 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -1077,6 +1077,23 @@ def test_splittable_popitem(self): self.assertEqual(list(a), ['x', 'y']) self.assertEqual(list(b), ['x', 'y', 'z']) + @support.cpython_only + def test_splittable_update(self): + """dict.update(other) must preserve order in other.""" + class C: + def __init__(self, order): + if order: + self.a, self.b, self.c = 1, 2, 3 + else: + self.c, self.b, self.a = 1, 2, 3 + o = C(True) + o = C(False) # o.__dict__ has reversed order. + self.assertEqual(list(o.__dict__), ["c", "b", "a"]) + + d = {} + d.update(o.__dict__) + self.assertEqual(list(d), ["c", "b", "a"]) + def test_iterator_pickling(self): for proto in range(pickle.HIGHEST_PROTOCOL + 1): data = {1:"a", 2:"b", 3:"c"} diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-24-16-34-17.bpo-40116.AeVGG2.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-24-16-34-17.bpo-40116.AeVGG2.rst new file mode 100644 index 0000000000000..fb3f82e880d0a --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-02-24-16-34-17.bpo-40116.AeVGG2.rst @@ -0,0 +1,2 @@ +Fix regression that dict.update(other) may don't respect iterate order of +other when other is key sharing dict. diff --git a/Misc/NEWS.d/next/Library/2022-02-09-22-40-11.bpo-46643.aBlIx1.rst b/Misc/NEWS.d/next/Library/2022-02-09-22-40-11.bpo-46643.aBlIx1.rst index e8b4d66e943f6..82ff831e3887d 100644 --- a/Misc/NEWS.d/next/Library/2022-02-09-22-40-11.bpo-46643.aBlIx1.rst +++ b/Misc/NEWS.d/next/Library/2022-02-09-22-40-11.bpo-46643.aBlIx1.rst @@ -1 +1 @@ -In :func:`typing.get_type_hints`, support evaluating stringified ``ParamSpecArgs`` and ``ParamSpecKwargs`` annotations. Patch by Gregory Beauregard. \ No newline at end of file +In :func:`typing.get_type_hints`, support evaluating stringified ``ParamSpecArgs`` and ``ParamSpecKwargs`` annotations. Patch by Gregory Beauregard. From webhook-mailer at python.org Thu Mar 3 00:27:29 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Thu, 03 Mar 2022 05:27:29 -0000 Subject: [Python-checkins] bpo-46643: fix NEWS entry (GH-31651) Message-ID: https://github.com/python/cpython/commit/59e1ce95f1e6ea8a556212b8b10cbc122f1a1711 commit: 59e1ce95f1e6ea8a556212b8b10cbc122f1a1711 branch: main author: Jelle Zijlstra committer: JelleZijlstra date: 2022-03-02T21:27:11-08:00 summary: bpo-46643: fix NEWS entry (GH-31651) files: M Misc/NEWS.d/next/Library/2022-02-09-22-40-11.bpo-46643.aBlIx1.rst diff --git a/Misc/NEWS.d/next/Library/2022-02-09-22-40-11.bpo-46643.aBlIx1.rst b/Misc/NEWS.d/next/Library/2022-02-09-22-40-11.bpo-46643.aBlIx1.rst index 82ff831e3887d..6edcfdfd814fd 100644 --- a/Misc/NEWS.d/next/Library/2022-02-09-22-40-11.bpo-46643.aBlIx1.rst +++ b/Misc/NEWS.d/next/Library/2022-02-09-22-40-11.bpo-46643.aBlIx1.rst @@ -1 +1,3 @@ -In :func:`typing.get_type_hints`, support evaluating stringified ``ParamSpecArgs`` and ``ParamSpecKwargs`` annotations. Patch by Gregory Beauregard. +In :func:`typing.get_type_hints`, support evaluating stringified +``ParamSpecArgs`` and ``ParamSpecKwargs`` annotations. Patch by +Gregory Beauregard. From webhook-mailer at python.org Thu Mar 3 00:31:13 2022 From: webhook-mailer at python.org (methane) Date: Thu, 03 Mar 2022 05:31:13 -0000 Subject: [Python-checkins] dict: Fix refleak (GH-31650) Message-ID: https://github.com/python/cpython/commit/3241cba4ec55ef0b9e73bf7a5a77ef29ae4b8756 commit: 3241cba4ec55ef0b9e73bf7a5a77ef29ae4b8756 branch: main author: Inada Naoki committer: methane date: 2022-03-03T14:30:58+09:00 summary: dict: Fix refleak (GH-31650) files: M Objects/dictobject.c diff --git a/Objects/dictobject.c b/Objects/dictobject.c index abe455e4ae034..d8bf164f98ee6 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -1523,12 +1523,16 @@ dictresize(PyDictObject *mp, uint8_t log2_newsize, int unicode) // We can not use free_keys_object here because key's reference // are moved already. - if (oldkeys != Py_EMPTY_KEYS) { - assert(oldkeys->dk_kind != DICT_KEYS_SPLIT); - assert(oldkeys->dk_refcnt == 1); #ifdef Py_REF_DEBUG - _Py_RefTotal--; + _Py_RefTotal--; #endif + if (oldkeys == Py_EMPTY_KEYS) { + oldkeys->dk_refcnt--; + assert(oldkeys->dk_refcnt > 0); + } + else { + assert(oldkeys->dk_kind != DICT_KEYS_SPLIT); + assert(oldkeys->dk_refcnt == 1); #if PyDict_MAXFREELIST > 0 struct _Py_dict_state *state = get_dict_state(); #ifdef Py_DEBUG From webhook-mailer at python.org Thu Mar 3 00:33:07 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Thu, 03 Mar 2022 05:33:07 -0000 Subject: [Python-checkins] bpo-46831: Update __build_class__ comment (#31522) Message-ID: https://github.com/python/cpython/commit/81d968b7c30d5b41f3f28b297b7ee5345d569509 commit: 81d968b7c30d5b41f3f28b297b7ee5345d569509 branch: main author: Shantanu <12621235+hauntsaninja at users.noreply.github.com> committer: JelleZijlstra date: 2022-03-02T21:32:57-08:00 summary: bpo-46831: Update __build_class__ comment (#31522) Co-authored-by: Jelle Zijlstra files: M Python/compile.c diff --git a/Python/compile.c b/Python/compile.c index 3609ff8f4fb9e..14595d9b576f5 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -2604,9 +2604,8 @@ compiler_class(struct compiler *c, stmt_ty s) /* ultimately generate code for: = __build_class__(, , *, **) where: - is a function/closure created from the class body; - it has a single argument (__locals__) where the dict - (or MutableSequence) representing the locals is passed + is a zero arg function/closure created from the class body. + It mutates its locals to build the class namespace. is the class name is the positional arguments and *varargs argument is the keyword arguments and **kwds argument From webhook-mailer at python.org Thu Mar 3 01:00:09 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 03 Mar 2022 06:00:09 -0000 Subject: [Python-checkins] bpo-46831: Update __build_class__ comment (GH-31522) Message-ID: https://github.com/python/cpython/commit/1d428bb8c93120d449212e2a815988f28e33b868 commit: 1d428bb8c93120d449212e2a815988f28e33b868 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-02T21:59:57-08:00 summary: bpo-46831: Update __build_class__ comment (GH-31522) Co-authored-by: Jelle Zijlstra (cherry picked from commit 81d968b7c30d5b41f3f28b297b7ee5345d569509) Co-authored-by: Shantanu <12621235+hauntsaninja at users.noreply.github.com> files: M Python/compile.c diff --git a/Python/compile.c b/Python/compile.c index f426050ccef5b..28003b66bd4e6 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -2319,9 +2319,8 @@ compiler_class(struct compiler *c, stmt_ty s) /* ultimately generate code for: = __build_class__(, , *, **) where: - is a function/closure created from the class body; - it has a single argument (__locals__) where the dict - (or MutableSequence) representing the locals is passed + is a zero arg function/closure created from the class body. + It mutates its locals to build the class namespace. is the class name is the positional arguments and *varargs argument is the keyword arguments and **kwds argument From webhook-mailer at python.org Thu Mar 3 01:03:10 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 03 Mar 2022 06:03:10 -0000 Subject: [Python-checkins] bpo-46831: Update __build_class__ comment (GH-31522) Message-ID: https://github.com/python/cpython/commit/fa8c5ed9c80507670c756aa83ea872b8a92bcd1c commit: fa8c5ed9c80507670c756aa83ea872b8a92bcd1c branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-02T22:02:59-08:00 summary: bpo-46831: Update __build_class__ comment (GH-31522) Co-authored-by: Jelle Zijlstra (cherry picked from commit 81d968b7c30d5b41f3f28b297b7ee5345d569509) Co-authored-by: Shantanu <12621235+hauntsaninja at users.noreply.github.com> files: M Python/compile.c diff --git a/Python/compile.c b/Python/compile.c index 1416eb119c9e7..f012406c06693 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -2440,9 +2440,8 @@ compiler_class(struct compiler *c, stmt_ty s) /* ultimately generate code for: = __build_class__(, , *, **) where: - is a function/closure created from the class body; - it has a single argument (__locals__) where the dict - (or MutableSequence) representing the locals is passed + is a zero arg function/closure created from the class body. + It mutates its locals to build the class namespace. is the class name is the positional arguments and *varargs argument is the keyword arguments and **kwds argument From webhook-mailer at python.org Thu Mar 3 02:20:05 2022 From: webhook-mailer at python.org (methane) Date: Thu, 03 Mar 2022 07:20:05 -0000 Subject: [Python-checkins] Fix EncodingWarning in libregrtest (GH-31654) Message-ID: https://github.com/python/cpython/commit/3c4abfab0d3e2a3b1e626a5eb185ad1f5436b532 commit: 3c4abfab0d3e2a3b1e626a5eb185ad1f5436b532 branch: main author: Inada Naoki committer: methane date: 2022-03-03T16:19:56+09:00 summary: Fix EncodingWarning in libregrtest (GH-31654) files: M Lib/test/libregrtest/refleak.py diff --git a/Lib/test/libregrtest/refleak.py b/Lib/test/libregrtest/refleak.py index 1069e2da008ff..a0538cbb3c377 100644 --- a/Lib/test/libregrtest/refleak.py +++ b/Lib/test/libregrtest/refleak.py @@ -142,7 +142,7 @@ def check_fd_deltas(deltas): msg = '%s leaked %s %s, sum=%s' % ( test_name, deltas, item_name, sum(deltas)) print(msg, file=sys.stderr, flush=True) - with open(fname, "a") as refrep: + with open(fname, "a", encoding="utf-8") as refrep: print(msg, file=refrep) refrep.flush() failed = True From webhook-mailer at python.org Thu Mar 3 05:38:56 2022 From: webhook-mailer at python.org (markshannon) Date: Thu, 03 Mar 2022 10:38:56 -0000 Subject: [Python-checkins] bpo-46891: Fix creating a new instance of a module subclass with slots (GH-31643) Message-ID: https://github.com/python/cpython/commit/751c9ed801ad1189272ca10f0749bfc9d49b5038 commit: 751c9ed801ad1189272ca10f0749bfc9d49b5038 branch: main author: Mark Shannon committer: markshannon date: 2022-03-03T10:38:27Z summary: bpo-46891: Fix creating a new instance of a module subclass with slots (GH-31643) files: A Misc/NEWS.d/next/Core and Builtins/2022-03-02-15-04-08.bpo-46891.aIAgTD.rst M Lib/test/test_module.py M Objects/moduleobject.c diff --git a/Lib/test/test_module.py b/Lib/test/test_module.py index 619348e0e40c0..f72177dda3702 100644 --- a/Lib/test/test_module.py +++ b/Lib/test/test_module.py @@ -346,6 +346,25 @@ def test_repeated_attribute_pops(self): # frozen and namespace module reprs are tested in importlib. + def test_subclass_with_slots(self): + # In 3.11alpha this crashed, as the slots weren't NULLed. + + class ModuleWithSlots(ModuleType): + __slots__ = ("a", "b") + + def __init__(self, name): + super().__init__(name) + + m = ModuleWithSlots("name") + with self.assertRaises(AttributeError): + m.a + with self.assertRaises(AttributeError): + m.b + m.a, m.b = 1, 2 + self.assertEqual(m.a, 1) + self.assertEqual(m.b, 2) + + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-02-15-04-08.bpo-46891.aIAgTD.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-02-15-04-08.bpo-46891.aIAgTD.rst new file mode 100644 index 0000000000000..6834b08a885c1 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-02-15-04-08.bpo-46891.aIAgTD.rst @@ -0,0 +1,3 @@ +Fix bug introduced during 3.11alpha where subclasses of ``types.ModuleType`` +with ``__slots__`` were not initialized correctly, resulting in an +interpreter crash. diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 72ed9bb82f970..738b262288bcd 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -4,6 +4,7 @@ #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_interp.h" // PyInterpreterState.importlib +#include "pycore_object.h" // _PyType_AllocNoTrack #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_moduleobject.h" // _PyModule_GetDef() #include "structmember.h" // PyMemberDef @@ -80,7 +81,7 @@ static PyModuleObject * new_module_notrack(PyTypeObject *mt) { PyModuleObject *m; - m = PyObject_GC_New(PyModuleObject, mt); + m = (PyModuleObject *)_PyType_AllocNoTrack(mt, 0); if (m == NULL) return NULL; m->md_def = NULL; From webhook-mailer at python.org Thu Mar 3 08:54:45 2022 From: webhook-mailer at python.org (corona10) Date: Thu, 03 Mar 2022 13:54:45 -0000 Subject: [Python-checkins] bpo-46874: Speed up sqlite3 user-defined aggregate 'step' method (GH-31604) Message-ID: https://github.com/python/cpython/commit/88567a997005c9388137cd18c5d7f4483423dac3 commit: 88567a997005c9388137cd18c5d7f4483423dac3 branch: main author: Erlend Egeberg Aasland committer: corona10 date: 2022-03-03T22:54:36+09:00 summary: bpo-46874: Speed up sqlite3 user-defined aggregate 'step' method (GH-31604) files: M Lib/test/test_sqlite3/test_userfunctions.py M Modules/_sqlite/connection.c M Modules/_sqlite/module.c M Modules/_sqlite/module.h diff --git a/Lib/test/test_sqlite3/test_userfunctions.py b/Lib/test/test_sqlite3/test_userfunctions.py index 23ecfb4e8a689..2588cae3d1f15 100644 --- a/Lib/test/test_sqlite3/test_userfunctions.py +++ b/Lib/test/test_sqlite3/test_userfunctions.py @@ -502,11 +502,13 @@ def test_aggr_error_on_create(self): with self.assertRaises(sqlite.OperationalError): self.con.create_function("bla", -100, AggrSum) + @with_tracebacks(AttributeError, name="AggrNoStep") def test_aggr_no_step(self): cur = self.con.cursor() - with self.assertRaises(AttributeError) as cm: + with self.assertRaises(sqlite.OperationalError) as cm: cur.execute("select nostep(t) from test") - self.assertEqual(str(cm.exception), "'AggrNoStep' object has no attribute 'step'") + self.assertEqual(str(cm.exception), + "user-defined aggregate's 'step' method not defined") def test_aggr_no_finalize(self): cur = self.con.cursor() diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 0efb5ae35a7f5..9f12e691f8912 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -734,11 +734,11 @@ step_callback(sqlite3_context *context, int argc, sqlite3_value **params) PyObject** aggregate_instance; PyObject* stepmethod = NULL; - aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, sizeof(PyObject*)); + callback_context *ctx = (callback_context *)sqlite3_user_data(context); + assert(ctx != NULL); + aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, sizeof(PyObject*)); if (*aggregate_instance == NULL) { - callback_context *ctx = (callback_context *)sqlite3_user_data(context); - assert(ctx != NULL); *aggregate_instance = PyObject_CallNoArgs(ctx->callable); if (!*aggregate_instance) { set_sqlite_error(context, @@ -747,8 +747,10 @@ step_callback(sqlite3_context *context, int argc, sqlite3_value **params) } } - stepmethod = PyObject_GetAttrString(*aggregate_instance, "step"); + stepmethod = PyObject_GetAttr(*aggregate_instance, ctx->state->str_step); if (!stepmethod) { + set_sqlite_error(context, + "user-defined aggregate's 'step' method not defined"); goto error; } diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index 70fde4910f6a4..563105c639100 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -627,6 +627,7 @@ module_clear(PyObject *module) Py_CLEAR(state->str___conform__); Py_CLEAR(state->str_executescript); Py_CLEAR(state->str_finalize); + Py_CLEAR(state->str_step); Py_CLEAR(state->str_upper); return 0; @@ -713,6 +714,7 @@ module_exec(PyObject *module) ADD_INTERNED(state, __conform__); ADD_INTERNED(state, executescript); ADD_INTERNED(state, finalize); + ADD_INTERNED(state, step); ADD_INTERNED(state, upper); /* Set error constants */ diff --git a/Modules/_sqlite/module.h b/Modules/_sqlite/module.h index 35c6f38552606..cca52d1e04b2c 100644 --- a/Modules/_sqlite/module.h +++ b/Modules/_sqlite/module.h @@ -64,6 +64,7 @@ typedef struct { PyObject *str___conform__; PyObject *str_executescript; PyObject *str_finalize; + PyObject *str_step; PyObject *str_upper; } pysqlite_state; From webhook-mailer at python.org Thu Mar 3 09:23:56 2022 From: webhook-mailer at python.org (iritkatriel) Date: Thu, 03 Mar 2022 14:23:56 -0000 Subject: [Python-checkins] bpo-6634: [doc] clarify that sys.exit() does not always exit the interpreter (GH-31639) Message-ID: https://github.com/python/cpython/commit/10117f1d8cb49ce95493555c06050faf636ccee7 commit: 10117f1d8cb49ce95493555c06050faf636ccee7 branch: main author: vidhya <96202776+Vidhyavinu at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-03-03T14:23:47Z summary: bpo-6634: [doc] clarify that sys.exit() does not always exit the interpreter (GH-31639) files: M Doc/library/sys.rst diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 5e47201f88eae..b83b1167e8aad 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -449,10 +449,7 @@ always available. .. function:: exit([arg]) - Exit from Python. This is implemented by raising the :exc:`SystemExit` - exception, so cleanup actions specified by finally clauses of :keyword:`try` - statements are honored, and it is possible to intercept the exit attempt at - an outer level. + Raise a :exc:`SystemExit` exception, signaling an intention to exit the interpreter. The optional argument *arg* can be an integer giving the exit status (defaulting to zero), or another type of object. If it is an integer, zero @@ -469,7 +466,8 @@ always available. Since :func:`exit` ultimately "only" raises an exception, it will only exit the process when called from the main thread, and the exception is not - intercepted. + intercepted. Cleanup actions specified by finally clauses of :keyword:`try` statements + are honored, and it is possible to intercept the exit attempt at an outer level. .. versionchanged:: 3.6 If an error occurs in the cleanup after the Python interpreter From webhook-mailer at python.org Thu Mar 3 09:49:45 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 03 Mar 2022 14:49:45 -0000 Subject: [Python-checkins] bpo-6634: [doc] clarify that sys.exit() does not always exit the interpreter (GH-31639) Message-ID: https://github.com/python/cpython/commit/9d9dc59d07d51d73e5af7dd506d0da63aa336995 commit: 9d9dc59d07d51d73e5af7dd506d0da63aa336995 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-03T06:49:22-08:00 summary: bpo-6634: [doc] clarify that sys.exit() does not always exit the interpreter (GH-31639) (cherry picked from commit 10117f1d8cb49ce95493555c06050faf636ccee7) Co-authored-by: vidhya <96202776+Vidhyavinu at users.noreply.github.com> files: M Doc/library/sys.rst diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 29cb54b5d1ac3..b59fa2c9d7cf3 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -429,10 +429,7 @@ always available. .. function:: exit([arg]) - Exit from Python. This is implemented by raising the :exc:`SystemExit` - exception, so cleanup actions specified by finally clauses of :keyword:`try` - statements are honored, and it is possible to intercept the exit attempt at - an outer level. + Raise a :exc:`SystemExit` exception, signaling an intention to exit the interpreter. The optional argument *arg* can be an integer giving the exit status (defaulting to zero), or another type of object. If it is an integer, zero @@ -449,7 +446,8 @@ always available. Since :func:`exit` ultimately "only" raises an exception, it will only exit the process when called from the main thread, and the exception is not - intercepted. + intercepted. Cleanup actions specified by finally clauses of :keyword:`try` statements + are honored, and it is possible to intercept the exit attempt at an outer level. .. versionchanged:: 3.6 If an error occurs in the cleanup after the Python interpreter From webhook-mailer at python.org Thu Mar 3 10:16:35 2022 From: webhook-mailer at python.org (iritkatriel) Date: Thu, 03 Mar 2022 15:16:35 -0000 Subject: [Python-checkins] bpo-6634: [doc] clarify that sys.exit() does not always exit the interpreter (GH-31639) (GH-31661) Message-ID: https://github.com/python/cpython/commit/09819863a3fb7092ca5cbdfcb722882ebbac806b commit: 09819863a3fb7092ca5cbdfcb722882ebbac806b branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-03-03T15:16:23Z summary: bpo-6634: [doc] clarify that sys.exit() does not always exit the interpreter (GH-31639) (GH-31661) (cherry picked from commit 10117f1d8cb49ce95493555c06050faf636ccee7) Co-authored-by: vidhya <96202776+Vidhyavinu at users.noreply.github.com> Co-authored-by: vidhya <96202776+Vidhyavinu at users.noreply.github.com> files: M Doc/library/sys.rst diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 9e182826b7343..03986db16a78c 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -412,10 +412,7 @@ always available. .. function:: exit([arg]) - Exit from Python. This is implemented by raising the :exc:`SystemExit` - exception, so cleanup actions specified by finally clauses of :keyword:`try` - statements are honored, and it is possible to intercept the exit attempt at - an outer level. + Raise a :exc:`SystemExit` exception, signaling an intention to exit the interpreter. The optional argument *arg* can be an integer giving the exit status (defaulting to zero), or another type of object. If it is an integer, zero @@ -432,7 +429,8 @@ always available. Since :func:`exit` ultimately "only" raises an exception, it will only exit the process when called from the main thread, and the exception is not - intercepted. + intercepted. Cleanup actions specified by finally clauses of :keyword:`try` statements + are honored, and it is possible to intercept the exit attempt at an outer level. .. versionchanged:: 3.6 If an error occurs in the cleanup after the Python interpreter From webhook-mailer at python.org Thu Mar 3 10:17:24 2022 From: webhook-mailer at python.org (markshannon) Date: Thu, 03 Mar 2022 15:17:24 -0000 Subject: [Python-checkins] Move check for str-only keys in LOAD_GLOBAL specializations to specialization time. (GH-31659) Message-ID: https://github.com/python/cpython/commit/b35603532b52e25c91929177191c44c1deb2f765 commit: b35603532b52e25c91929177191c44c1deb2f765 branch: main author: Mark Shannon committer: markshannon date: 2022-03-03T15:17:18Z summary: Move check for str-only keys in LOAD_GLOBAL specializations to specialization time. (GH-31659) files: M Python/ceval.c M Python/specialize.c diff --git a/Python/ceval.c b/Python/ceval.c index e47e0521ea941..c86b7443768a1 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1595,19 +1595,6 @@ is_method(PyObject **stack_pointer, int args) { return PEEK(args+2) != NULL; } -static PyObject* -dictkeys_get_value_by_index(PyDictKeysObject *dk, int index) -{ - if (DK_IS_UNICODE(dk)) { - PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dk) + index; - return ep->me_value; - } - else { - PyDictKeyEntry *ep = DK_ENTRIES(dk) + index; - return ep->me_value; - } -} - #define KWNAMES_LEN() \ (call_shape.kwnames == NULL ? 0 : ((int)PyTuple_GET_SIZE(call_shape.kwnames))) @@ -3043,7 +3030,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; uint32_t version = read32(&cache->module_keys_version); DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); - PyObject *res = dictkeys_get_value_by_index(dict->ma_keys, cache->index); + assert(DK_IS_UNICODE(dict->ma_keys)); + PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); + PyObject *res = entries[cache->index].me_value; DEOPT_IF(res == NULL, LOAD_GLOBAL); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); STAT_INC(LOAD_GLOBAL, hit); @@ -3063,7 +3052,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int uint16_t bltn_version = cache->builtin_keys_version; DEOPT_IF(mdict->ma_keys->dk_version != mod_version, LOAD_GLOBAL); DEOPT_IF(bdict->ma_keys->dk_version != bltn_version, LOAD_GLOBAL); - PyObject *res = dictkeys_get_value_by_index(bdict->ma_keys, cache->index); + assert(DK_IS_UNICODE(bdict->ma_keys)); + PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(bdict->ma_keys); + PyObject *res = entries[cache->index].me_value; DEOPT_IF(res == NULL, LOAD_GLOBAL); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); STAT_INC(LOAD_GLOBAL, hit); diff --git a/Python/specialize.c b/Python/specialize.c index 5486b5b1f65dc..676258268f178 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -1219,6 +1219,10 @@ _Py_Specialize_LoadGlobal( goto fail; } PyDictKeysObject * globals_keys = ((PyDictObject *)globals)->ma_keys; + if (!DK_IS_UNICODE(globals_keys)) { + SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT); + goto fail; + } Py_ssize_t index = _PyDictKeys_StringLookup(globals_keys, name); if (index == DKIX_ERROR) { SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT); @@ -1241,6 +1245,10 @@ _Py_Specialize_LoadGlobal( goto fail; } PyDictKeysObject * builtin_keys = ((PyDictObject *)builtins)->ma_keys; + if (!DK_IS_UNICODE(builtin_keys)) { + SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT); + goto fail; + } index = _PyDictKeys_StringLookup(builtin_keys, name); if (index == DKIX_ERROR) { SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT); From webhook-mailer at python.org Thu Mar 3 13:41:58 2022 From: webhook-mailer at python.org (gvanrossum) Date: Thu, 03 Mar 2022 18:41:58 -0000 Subject: [Python-checkins] bpo-46877: export unittest.doModuleCleanups in unittest package (#31613) Message-ID: https://github.com/python/cpython/commit/cc400585fab02994255f21ae8183d5f147236815 commit: cc400585fab02994255f21ae8183d5f147236815 branch: main author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> committer: gvanrossum date: 2022-03-03T10:41:28-08:00 summary: bpo-46877: export unittest.doModuleCleanups in unittest package (#31613) files: A Misc/NEWS.d/next/Library/2022-03-03-06-58-52.bpo-46877.BKgjpD.rst M Lib/unittest/__init__.py diff --git a/Lib/unittest/__init__.py b/Lib/unittest/__init__.py index 4b184889573940..eda951ce73e665 100644 --- a/Lib/unittest/__init__.py +++ b/Lib/unittest/__init__.py @@ -49,7 +49,7 @@ def testMultiply(self): 'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless', 'expectedFailure', 'TextTestResult', 'installHandler', 'registerResult', 'removeResult', 'removeHandler', - 'addModuleCleanup'] + 'addModuleCleanup', 'doModuleCleanups'] # Expose obsolete functions for backwards compatibility # bpo-5846: Deprecated in Python 3.11, scheduled for removal in Python 3.13. @@ -59,7 +59,7 @@ def testMultiply(self): from .result import TestResult from .case import (addModuleCleanup, TestCase, FunctionTestCase, SkipTest, skip, - skipIf, skipUnless, expectedFailure) + skipIf, skipUnless, expectedFailure, doModuleCleanups) from .suite import BaseTestSuite, TestSuite from .loader import TestLoader, defaultTestLoader from .main import TestProgram, main diff --git a/Misc/NEWS.d/next/Library/2022-03-03-06-58-52.bpo-46877.BKgjpD.rst b/Misc/NEWS.d/next/Library/2022-03-03-06-58-52.bpo-46877.BKgjpD.rst new file mode 100644 index 00000000000000..6738519377f4ad --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-03-06-58-52.bpo-46877.BKgjpD.rst @@ -0,0 +1 @@ +Export :func:`unittest.doModuleCleanups` in :mod:`unittest`. Patch by Kumar Aditya. From webhook-mailer at python.org Thu Mar 3 14:29:25 2022 From: webhook-mailer at python.org (brandtbucher) Date: Thu, 03 Mar 2022 19:29:25 -0000 Subject: [Python-checkins] bpo-46841: Improve the failure stats for COMPARE_OP (GH-31663) Message-ID: https://github.com/python/cpython/commit/127797f572cc7374192e415c44ea2e95b009d5ab commit: 127797f572cc7374192e415c44ea2e95b009d5ab branch: main author: Brandt Bucher committer: brandtbucher date: 2022-03-03T11:28:47-08:00 summary: bpo-46841: Improve the failure stats for COMPARE_OP (GH-31663) files: A Misc/NEWS.d/next/Core and Builtins/2022-03-03-10-46-13.bpo-46841.7CkuZx.rst M Python/specialize.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-03-10-46-13.bpo-46841.7CkuZx.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-03-10-46-13.bpo-46841.7CkuZx.rst new file mode 100644 index 0000000000000..8be83bcab3c8e --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-03-10-46-13.bpo-46841.7CkuZx.rst @@ -0,0 +1,2 @@ +Add more detailed specialization failure stats for :opcode:`COMPARE_OP` +followed by :opcode:`EXTENDED_ARG`. diff --git a/Python/specialize.c b/Python/specialize.c index 676258268f178..4a94aafefea9c 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -616,6 +616,7 @@ initial_counter_value(void) { #define SPEC_FAIL_COMPARE_OP_BASEOBJECT 21 #define SPEC_FAIL_COMPARE_OP_FLOAT_LONG 22 #define SPEC_FAIL_COMPARE_OP_LONG_FLOAT 23 +#define SPEC_FAIL_COMPARE_OP_EXTENDED_ARG 24 /* FOR_ITER */ #define SPEC_FAIL_FOR_ITER_GENERATOR 10 @@ -2088,6 +2089,10 @@ _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, *instr = _Py_MAKECODEUNIT(COMPARE_OP, oparg); return; #endif + if (next_opcode == EXTENDED_ARG) { + SPECIALIZATION_FAIL(COMPARE_OP, SPEC_FAIL_COMPARE_OP_EXTENDED_ARG); + goto failure; + } SPECIALIZATION_FAIL(COMPARE_OP, SPEC_FAIL_COMPARE_OP_NOT_FOLLOWED_BY_COND_JUMP); goto failure; } From webhook-mailer at python.org Thu Mar 3 15:45:08 2022 From: webhook-mailer at python.org (vstinner) Date: Thu, 03 Mar 2022 20:45:08 -0000 Subject: [Python-checkins] bpo-46913: Fix test_faulthandler.test_sigfpe() on UBSAN (GH-31662) Message-ID: https://github.com/python/cpython/commit/4173d677a1d7c72bb32d292fbff1b4cf073d615c commit: 4173d677a1d7c72bb32d292fbff1b4cf073d615c branch: main author: Victor Stinner committer: vstinner date: 2022-03-03T21:45:01+01:00 summary: bpo-46913: Fix test_faulthandler.test_sigfpe() on UBSAN (GH-31662) Disable undefined behavior sanitizer (UBSAN) on faulthandler_sigfpe(). files: A Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst M Modules/faulthandler.c diff --git a/Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst b/Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst new file mode 100644 index 0000000000000..65fed1c249d87 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst @@ -0,0 +1,3 @@ +Fix test_faulthandler.test_sigfpe() if Python is built with undefined +behavior sanitizer (UBSAN): disable UBSAN on the faulthandler_sigfpe() +function. Patch by Victor Stinner. diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index 46e18c17d8d35..4f9f661c662a6 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -1102,17 +1102,35 @@ faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args) Py_RETURN_NONE; } -static PyObject * +// clang uses __attribute__((no_sanitize("undefined"))) +// GCC 4.9+ uses __attribute__((no_sanitize_undefined)) +#if defined(__has_feature) // Clang +# if __has_feature(undefined_behavior_sanitizer) +# define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize("undefined"))) +# endif +#endif +#if defined(__GNUC__) \ + && ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) +# define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize_undefined)) +#endif +#ifndef _Py_NO_SANITIZE_UNDEFINED +# define _Py_NO_SANITIZE_UNDEFINED +#endif + +static PyObject* _Py_NO_SANITIZE_UNDEFINED faulthandler_sigfpe(PyObject *self, PyObject *args) { + faulthandler_suppress_crash_report(); + /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on PowerPC. Use volatile to disable compile-time optimizations. */ volatile int x = 1, y = 0, z; - faulthandler_suppress_crash_report(); z = x / y; + /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC), raise it manually. */ raise(SIGFPE); + /* This line is never reached, but we pretend to make something with z to silence a compiler warning. */ return PyLong_FromLong(z); From webhook-mailer at python.org Thu Mar 3 17:07:05 2022 From: webhook-mailer at python.org (vstinner) Date: Thu, 03 Mar 2022 22:07:05 -0000 Subject: [Python-checkins] bpo-45459: Fix PyModuleDef_Slot type in the limited C API (GH-31668) Message-ID: https://github.com/python/cpython/commit/0b63215bb152c06404cecbd5303b1a50969a9f9f commit: 0b63215bb152c06404cecbd5303b1a50969a9f9f branch: main author: Victor Stinner committer: vstinner date: 2022-03-03T23:06:55+01:00 summary: bpo-45459: Fix PyModuleDef_Slot type in the limited C API (GH-31668) Move the type definition to pytypedefs.h. files: M Include/moduleobject.h M Include/pytypedefs.h diff --git a/Include/moduleobject.h b/Include/moduleobject.h index 2d41f76df4b22..8b62c45505fb6 100644 --- a/Include/moduleobject.h +++ b/Include/moduleobject.h @@ -55,14 +55,12 @@ typedef struct PyModuleDef_Base { NULL, /* m_copy */ \ } -struct PyModuleDef_Slot; - #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 /* New in 3.5 */ -typedef struct PyModuleDef_Slot{ +struct PyModuleDef_Slot { int slot; void *value; -} PyModuleDef_Slot; +}; #define Py_mod_create 1 #define Py_mod_exec 2 diff --git a/Include/pytypedefs.h b/Include/pytypedefs.h index 5dd841e62173c..e78ed56a3b67c 100644 --- a/Include/pytypedefs.h +++ b/Include/pytypedefs.h @@ -10,6 +10,7 @@ extern "C" { #endif typedef struct PyModuleDef PyModuleDef; +typedef struct PyModuleDef_Slot PyModuleDef_Slot; typedef struct PyMethodDef PyMethodDef; typedef struct PyGetSetDef PyGetSetDef; typedef struct PyMemberDef PyMemberDef; From webhook-mailer at python.org Thu Mar 3 17:08:17 2022 From: webhook-mailer at python.org (vstinner) Date: Thu, 03 Mar 2022 22:08:17 -0000 Subject: [Python-checkins] bpo-45459: Use type names in the internal C API (GH-31669) Message-ID: https://github.com/python/cpython/commit/32f0c8271706550096c454eb512450b85fbfc320 commit: 32f0c8271706550096c454eb512450b85fbfc320 branch: main author: Victor Stinner committer: vstinner date: 2022-03-03T23:08:07+01:00 summary: bpo-45459: Use type names in the internal C API (GH-31669) Replace "struct xxx" with "xxx" types in the internal C API. files: M Include/internal/pycore_interp.h M Include/internal/pycore_moduleobject.h M Include/internal/pycore_pystate.h M Include/internal/pycore_runtime.h M Include/internal/pycore_traceback.h diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index 77e42b65f5d3c..db8edffda8bb9 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -79,12 +79,12 @@ struct atexit_state { */ struct _is { - struct _is *next; + PyInterpreterState *next; struct pythreads { uint64_t next_unique_id; /* The linked list of threads, newest first. */ - struct _ts *head; + PyThreadState *head; /* Used in Modules/_threadmodule.c. */ long count; /* Support for runtime thread stack size tuning. @@ -190,7 +190,7 @@ struct _is { */ /* the initial PyInterpreterState.threads.head */ - struct _ts _initial_thread; + PyThreadState _initial_thread; }; @@ -214,11 +214,11 @@ struct _xidregitem { struct _xidregitem *next; }; -PyAPI_FUNC(struct _is*) _PyInterpreterState_LookUpID(int64_t); +PyAPI_FUNC(PyInterpreterState*) _PyInterpreterState_LookUpID(int64_t); -PyAPI_FUNC(int) _PyInterpreterState_IDInitref(struct _is *); -PyAPI_FUNC(int) _PyInterpreterState_IDIncref(struct _is *); -PyAPI_FUNC(void) _PyInterpreterState_IDDecref(struct _is *); +PyAPI_FUNC(int) _PyInterpreterState_IDInitref(PyInterpreterState *); +PyAPI_FUNC(int) _PyInterpreterState_IDIncref(PyInterpreterState *); +PyAPI_FUNC(void) _PyInterpreterState_IDDecref(PyInterpreterState *); #ifdef __cplusplus } diff --git a/Include/internal/pycore_moduleobject.h b/Include/internal/pycore_moduleobject.h index e9978abd25b10..76361b8dff113 100644 --- a/Include/internal/pycore_moduleobject.h +++ b/Include/internal/pycore_moduleobject.h @@ -11,7 +11,7 @@ extern "C" { typedef struct { PyObject_HEAD PyObject *md_dict; - struct PyModuleDef *md_def; + PyModuleDef *md_def; void *md_state; PyObject *md_weaklist; // for logging purposes after md_dict is cleared diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index 06f58fb5100f0..f0c238a608b10 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -172,7 +172,7 @@ extern void _PySignal_AfterFork(void); PyAPI_FUNC(int) _PyState_AddModule( PyThreadState *tstate, PyObject* module, - struct PyModuleDef* def); + PyModuleDef* def); PyAPI_FUNC(int) _PyOS_InterruptOccurred(PyThreadState *tstate); diff --git a/Include/internal/pycore_runtime.h b/Include/internal/pycore_runtime.h index 038e6f8263fae..18191c3771dfc 100644 --- a/Include/internal/pycore_runtime.h +++ b/Include/internal/pycore_runtime.h @@ -11,7 +11,7 @@ extern "C" { #include "pycore_atomic.h" /* _Py_atomic_address */ #include "pycore_gil.h" // struct _gil_runtime_state #include "pycore_global_objects.h" // struct _Py_global_objects -#include "pycore_interp.h" // struct _is +#include "pycore_interp.h" // PyInterpreterState #include "pycore_unicodeobject.h" // struct _Py_unicode_runtime_ids diff --git a/Include/internal/pycore_traceback.h b/Include/internal/pycore_traceback.h index 84dbe27044fd3..c393b2c136f2d 100644 --- a/Include/internal/pycore_traceback.h +++ b/Include/internal/pycore_traceback.h @@ -8,9 +8,6 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -/* Forward declaration */ -struct _is; - /* Write the Python traceback into the file 'fd'. For example: Traceback (most recent call first): @@ -57,7 +54,7 @@ PyAPI_FUNC(void) _Py_DumpTraceback( PyAPI_FUNC(const char*) _Py_DumpTracebackThreads( int fd, - struct _is *interp, + PyInterpreterState *interp, PyThreadState *current_tstate); /* Write a Unicode object into the file descriptor fd. Encode the string to From webhook-mailer at python.org Thu Mar 3 18:25:37 2022 From: webhook-mailer at python.org (vstinner) Date: Thu, 03 Mar 2022 23:25:37 -0000 Subject: [Python-checkins] bpo-46913: Fix test_faulthandler.test_read_null() on UBSan (GH31672) Message-ID: https://github.com/python/cpython/commit/65b92ccdec2ee4a99e54aaf7ae2d9bbc2ebfe549 commit: 65b92ccdec2ee4a99e54aaf7ae2d9bbc2ebfe549 branch: main author: Victor Stinner committer: vstinner date: 2022-03-04T00:25:03+01:00 summary: bpo-46913: Fix test_faulthandler.test_read_null() on UBSan (GH31672) Disable undefined behavior sanitizer (UBSan) on faulthandler._read_null(). files: M Modules/faulthandler.c diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index 4f9f661c662a6..db3f4fbe5c616 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -32,6 +32,23 @@ #define PUTS(fd, str) _Py_write_noraise(fd, str, strlen(str)) + +// clang uses __attribute__((no_sanitize("undefined"))) +// GCC 4.9+ uses __attribute__((no_sanitize_undefined)) +#if defined(__has_feature) // Clang +# if __has_feature(undefined_behavior_sanitizer) +# define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize("undefined"))) +# endif +#endif +#if defined(__GNUC__) \ + && ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) +# define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize_undefined)) +#endif +#ifndef _Py_NO_SANITIZE_UNDEFINED +# define _Py_NO_SANITIZE_UNDEFINED +#endif + + #ifdef HAVE_SIGACTION typedef struct sigaction _Py_sighandler_t; #else @@ -1013,7 +1030,7 @@ faulthandler_suppress_crash_report(void) #endif } -static PyObject * +static PyObject* _Py_NO_SANITIZE_UNDEFINED faulthandler_read_null(PyObject *self, PyObject *args) { volatile int *x; @@ -1102,21 +1119,6 @@ faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args) Py_RETURN_NONE; } -// clang uses __attribute__((no_sanitize("undefined"))) -// GCC 4.9+ uses __attribute__((no_sanitize_undefined)) -#if defined(__has_feature) // Clang -# if __has_feature(undefined_behavior_sanitizer) -# define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize("undefined"))) -# endif -#endif -#if defined(__GNUC__) \ - && ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) -# define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize_undefined)) -#endif -#ifndef _Py_NO_SANITIZE_UNDEFINED -# define _Py_NO_SANITIZE_UNDEFINED -#endif - static PyObject* _Py_NO_SANITIZE_UNDEFINED faulthandler_sigfpe(PyObject *self, PyObject *args) { From webhook-mailer at python.org Thu Mar 3 18:31:13 2022 From: webhook-mailer at python.org (brandtbucher) Date: Thu, 03 Mar 2022 23:31:13 -0000 Subject: [Python-checkins] bpo-46841: Use inline caching for attribute accesses (GH-31640) Message-ID: https://github.com/python/cpython/commit/05a8bc1c944709e7468f157bd1b6032f368e43bf commit: 05a8bc1c944709e7468f157bd1b6032f368e43bf branch: main author: Brandt Bucher committer: brandtbucher date: 2022-03-03T15:31:00-08:00 summary: bpo-46841: Use inline caching for attribute accesses (GH-31640) files: A Misc/NEWS.d/next/Core and Builtins/2022-03-01-17-47-58.bpo-46841.inYQlU.rst M Include/internal/pycore_code.h M Include/opcode.h M Lib/importlib/_bootstrap_external.py M Lib/opcode.py M Lib/test/test_dis.py M Programs/test_frozenmain.h M Python/ceval.c M Python/opcode_targets.h M Python/specialize.c diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index b9671d0ec32bb..25c31a1fca7a6 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -20,14 +20,8 @@ typedef struct { uint32_t version; } _PyAdaptiveEntry; - typedef struct { - uint32_t tp_version; - uint32_t dk_version; -} _PyAttrCache; - -typedef struct { - /* Borrowed ref in LOAD_METHOD */ + /* Borrowed ref */ PyObject *obj; } _PyObjectCache; @@ -51,7 +45,6 @@ typedef struct { typedef union { _PyEntryZero zero; _PyAdaptiveEntry adaptive; - _PyAttrCache attr; _PyObjectCache obj; _PyCallCache call; } SpecializedCacheEntry; @@ -65,8 +58,7 @@ typedef union { typedef struct { _Py_CODEUNIT counter; _Py_CODEUNIT index; - _Py_CODEUNIT module_keys_version; - _Py_CODEUNIT _m1; + _Py_CODEUNIT module_keys_version[2]; _Py_CODEUNIT builtin_keys_version; } _PyLoadGlobalCache; @@ -94,13 +86,32 @@ typedef struct { typedef struct { _Py_CODEUNIT counter; - _Py_CODEUNIT type_version; - _Py_CODEUNIT _t1; + _Py_CODEUNIT type_version[2]; _Py_CODEUNIT func_version; } _PyBinarySubscrCache; #define INLINE_CACHE_ENTRIES_BINARY_SUBSCR CACHE_ENTRIES(_PyBinarySubscrCache) +typedef struct { + _Py_CODEUNIT counter; + _Py_CODEUNIT version[2]; + _Py_CODEUNIT index; +} _PyAttrCache; + +#define INLINE_CACHE_ENTRIES_LOAD_ATTR CACHE_ENTRIES(_PyAttrCache) + +#define INLINE_CACHE_ENTRIES_STORE_ATTR CACHE_ENTRIES(_PyAttrCache) + +typedef struct { + _Py_CODEUNIT counter; + _Py_CODEUNIT type_version[2]; + _Py_CODEUNIT dict_offset; + _Py_CODEUNIT keys_version[2]; + _Py_CODEUNIT descr[4]; +} _PyLoadMethodCache; + +#define INLINE_CACHE_ENTRIES_LOAD_METHOD CACHE_ENTRIES(_PyLoadMethodCache) + /* Maximum size of code to quicken, in code units. */ #define MAX_SIZE_TO_QUICKEN 5000 @@ -328,10 +339,13 @@ cache_backoff(_PyAdaptiveEntry *entry) { /* Specialization functions */ -extern int _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, SpecializedCacheEntry *cache); -extern int _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, SpecializedCacheEntry *cache); +extern int _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, + PyObject *name); +extern int _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, + PyObject *name); extern int _Py_Specialize_LoadGlobal(PyObject *globals, PyObject *builtins, _Py_CODEUNIT *instr, PyObject *name); -extern int _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, SpecializedCacheEntry *cache); +extern int _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, + PyObject *name); extern int _Py_Specialize_BinarySubscr(PyObject *sub, PyObject *container, _Py_CODEUNIT *instr); extern int _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *instr); extern int _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, @@ -416,34 +430,107 @@ extern PyObject* _Py_GetSpecializationStats(void); #ifdef WORDS_BIGENDIAN static inline void -write32(uint16_t *p, uint32_t val) +write_u32(uint16_t *p, uint32_t val) { - p[0] = val >> 16; - p[1] = (uint16_t)val; + p[0] = (uint16_t)(val >> 16); + p[1] = (uint16_t)(val >> 0); +} + +static inline void +write_u64(uint16_t *p, uint64_t val) +{ + p[0] = (uint16_t)(val >> 48); + p[1] = (uint16_t)(val >> 32); + p[2] = (uint16_t)(val >> 16); + p[3] = (uint16_t)(val >> 0); } static inline uint32_t -read32(uint16_t *p) +read_u32(uint16_t *p) +{ + uint32_t val = 0; + val |= (uint32_t)p[0] << 16; + val |= (uint32_t)p[1] << 0; + return val; +} + +static inline uint64_t +read_u64(uint16_t *p) { - return (p[0] << 16) | p[1]; + uint64_t val = 0; + val |= (uint64_t)p[0] << 48; + val |= (uint64_t)p[1] << 32; + val |= (uint64_t)p[2] << 16; + val |= (uint64_t)p[3] << 0; + return val; } #else static inline void -write32(uint16_t *p, uint32_t val) +write_u32(uint16_t *p, uint32_t val) +{ + p[0] = (uint16_t)(val >> 0); + p[1] = (uint16_t)(val >> 16); +} + +static inline void +write_u64(uint16_t *p, uint64_t val) { - p[0] = (uint16_t)val; - p[1] = val >> 16; + p[0] = (uint16_t)(val >> 0); + p[1] = (uint16_t)(val >> 16); + p[2] = (uint16_t)(val >> 32); + p[3] = (uint16_t)(val >> 48); } static inline uint32_t -read32(uint16_t *p) +read_u32(uint16_t *p) +{ + uint32_t val = 0; + val |= (uint32_t)p[0] << 0; + val |= (uint32_t)p[1] << 16; + return val; +} + +static inline uint64_t +read_u64(uint16_t *p) +{ + uint64_t val = 0; + val |= (uint64_t)p[0] << 0; + val |= (uint64_t)p[1] << 16; + val |= (uint64_t)p[2] << 32; + val |= (uint64_t)p[3] << 48; + return val; +} + +#endif + +static inline void +write_obj(uint16_t *p, PyObject *obj) { - return p[0] | (p[1] << 16); + uintptr_t val = (uintptr_t)obj; +#if SIZEOF_VOID_P == 8 + write_u64(p, val); +#elif SIZEOF_VOID_P == 4 + write_u32(p, val); +#else + #error "SIZEOF_VOID_P must be 4 or 8" +#endif } +static inline PyObject * +read_obj(uint16_t *p) +{ + uintptr_t val; +#if SIZEOF_VOID_P == 8 + val = read_u64(p); +#elif SIZEOF_VOID_P == 4 + val = read_u32(p); +#else + #error "SIZEOF_VOID_P must be 4 or 8" #endif + return (PyObject *)val; +} #ifdef __cplusplus } diff --git a/Include/opcode.h b/Include/opcode.h index f6330d9056aa1..110f8c3617140 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -183,7 +183,6 @@ extern "C" { #define LOAD_FAST__LOAD_CONST 173 #define LOAD_CONST__LOAD_FAST 174 #define STORE_FAST__STORE_FAST 175 -#define LOAD_FAST__LOAD_ATTR_INSTANCE_VALUE 176 #define DO_TRACING 255 extern const uint8_t _PyOpcode_InlineCacheEntries[256]; @@ -213,9 +212,12 @@ static const uint32_t _PyOpcode_Jump[8] = { const uint8_t _PyOpcode_InlineCacheEntries[256] = { [BINARY_SUBSCR] = 4, [UNPACK_SEQUENCE] = 1, + [STORE_ATTR] = 4, + [LOAD_ATTR] = 4, [COMPARE_OP] = 2, [LOAD_GLOBAL] = 5, [BINARY_OP] = 1, + [LOAD_METHOD] = 10, }; #endif /* OPCODE_TABLES */ diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index dd1f6ffd64cee..9d36bc27c44d4 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -390,6 +390,8 @@ def _write_atomic(path, data, mode=0o666): # Python 3.11a5 3481 (Use inline cache for BINARY_OP) # Python 3.11a5 3482 (Use inline caching for UNPACK_SEQUENCE and LOAD_GLOBAL) # Python 3.11a5 3483 (Use inline caching for COMPARE_OP and BINARY_SUBSCR) +# Python 3.11a5 3484 (Use inline caching for LOAD_ATTR, LOAD_METHOD, and +# STORE_ATTR) # Python 3.12 will start with magic number 3500 @@ -404,7 +406,7 @@ def _write_atomic(path, data, mode=0o666): # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array # in PC/launcher.c must also be updated. -MAGIC_NUMBER = (3483).to_bytes(2, 'little') + b'\r\n' +MAGIC_NUMBER = (3484).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c _PYCACHE = '__pycache__' diff --git a/Lib/opcode.py b/Lib/opcode.py index 9b08562cd04f6..f6e2dec32e0f5 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -112,7 +112,7 @@ def jabs_op(name, op, entries=0): def_op('UNPACK_SEQUENCE', 92, 1) # Number of tuple items jrel_op('FOR_ITER', 93) def_op('UNPACK_EX', 94) -name_op('STORE_ATTR', 95) # Index in name list +name_op('STORE_ATTR', 95, 4) # Index in name list name_op('DELETE_ATTR', 96) # "" name_op('STORE_GLOBAL', 97) # "" name_op('DELETE_GLOBAL', 98) # "" @@ -124,7 +124,7 @@ def jabs_op(name, op, entries=0): def_op('BUILD_LIST', 103) # Number of list items def_op('BUILD_SET', 104) # Number of set items def_op('BUILD_MAP', 105) # Number of dict entries -name_op('LOAD_ATTR', 106) # Index in name list +name_op('LOAD_ATTR', 106, 4) # Index in name list def_op('COMPARE_OP', 107, 2) # Comparison operator hascompare.append(107) name_op('IMPORT_NAME', 108) # Index in name list @@ -186,7 +186,7 @@ def jabs_op(name, op, entries=0): def_op('BUILD_CONST_KEY_MAP', 156) def_op('BUILD_STRING', 157) -name_op('LOAD_METHOD', 160) +name_op('LOAD_METHOD', 160, 10) def_op('LIST_EXTEND', 162) def_op('SET_UPDATE', 163) @@ -301,7 +301,6 @@ def jabs_op(name, op, entries=0): "LOAD_FAST__LOAD_CONST", "LOAD_CONST__LOAD_FAST", "STORE_FAST__STORE_FAST", - "LOAD_FAST__LOAD_ATTR_INSTANCE_VALUE", ] _specialization_stats = [ "success", diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 8de2ed09e8352..7e0542ae0ae9e 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -375,7 +375,7 @@ def bug42562(): >> PUSH_EXC_INFO %3d LOAD_GLOBAL 0 (Exception) - JUMP_IF_NOT_EXC_MATCH 31 (to 62) + JUMP_IF_NOT_EXC_MATCH 35 (to 70) STORE_FAST 0 (e) %3d LOAD_FAST 0 (e) diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-01-17-47-58.bpo-46841.inYQlU.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-01-17-47-58.bpo-46841.inYQlU.rst new file mode 100644 index 0000000000000..0e7beb019f46a --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-01-17-47-58.bpo-46841.inYQlU.rst @@ -0,0 +1,2 @@ +Use inline caching for :opcode:`LOAD_ATTR`, :opcode:`LOAD_METHOD`, and +:opcode:`STORE_ATTR`. diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h index 3fef981e42ff9..4ebab4f7544bb 100644 --- a/Programs/test_frozenmain.h +++ b/Programs/test_frozenmain.h @@ -1,14 +1,15 @@ // Auto-generated by Programs/freeze_test_frozenmain.py unsigned char M_test_frozenmain[] = { 227,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0, - 0,0,0,0,0,115,120,0,0,0,151,0,100,0,100,1, + 0,0,0,0,0,115,136,0,0,0,151,0,100,0,100,1, 108,0,90,0,100,0,100,1,108,1,90,1,2,0,101,2, 100,2,166,1,171,1,1,0,2,0,101,2,100,3,101,0, - 106,3,166,2,171,2,1,0,2,0,101,1,106,4,166,0, + 106,3,3,0,3,0,3,0,3,0,166,2,171,2,1,0, + 2,0,101,1,106,4,3,0,3,0,3,0,3,0,166,0, 171,0,100,4,25,0,3,0,3,0,3,0,3,0,90,5, 100,5,68,0,93,20,90,6,2,0,101,2,100,6,101,6, 155,0,100,7,101,5,101,6,25,0,3,0,3,0,3,0, - 3,0,155,0,157,4,166,1,171,1,1,0,113,37,100,1, + 3,0,155,0,157,4,166,1,171,1,1,0,113,45,100,1, 83,0,41,8,233,0,0,0,0,78,122,18,70,114,111,122, 101,110,32,72,101,108,108,111,32,87,111,114,108,100,122,8, 115,121,115,46,97,114,103,118,218,6,99,111,110,102,105,103, @@ -25,12 +26,13 @@ unsigned char M_test_frozenmain[] = { 0,0,250,18,116,101,115,116,95,102,114,111,122,101,110,109, 97,105,110,46,112,121,250,8,60,109,111,100,117,108,101,62, 114,11,0,0,0,1,0,0,0,115,18,0,0,0,2,128, - 8,3,8,1,12,2,16,1,24,1,8,1,38,7,4,249, - 115,20,0,0,0,2,128,8,3,8,1,12,2,16,1,24, - 1,2,7,4,1,2,249,42,7,115,120,0,0,0,0,0, + 8,3,8,1,12,2,24,1,32,1,8,1,38,7,4,249, + 115,20,0,0,0,2,128,8,3,8,1,12,2,24,1,32, + 1,2,7,4,1,2,249,42,7,115,136,0,0,0,0,0, 1,11,1,11,1,11,1,11,1,25,1,25,1,25,1,25, 1,6,1,6,7,27,1,28,1,28,1,28,1,6,1,6, - 7,17,19,22,19,27,1,28,1,28,1,28,10,39,10,27, + 7,17,19,22,19,27,19,27,19,27,19,27,19,27,1,28, + 1,28,1,28,10,39,10,27,10,39,10,39,10,39,10,39, 10,39,10,41,10,41,42,50,10,51,10,51,10,51,10,51, 10,51,1,7,12,2,1,42,1,42,5,8,5,10,5,10, 11,41,21,24,11,41,11,41,28,34,35,38,28,39,28,39, diff --git a/Python/ceval.c b/Python/ceval.c index c86b7443768a1..915ab9313a95a 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1448,16 +1448,15 @@ eval_frame_handle_pending(PyThreadState *tstate) // shared by LOAD_ATTR_MODULE and LOAD_METHOD_MODULE #define LOAD_MODULE_ATTR_OR_METHOD(attr_or_method) \ - SpecializedCacheEntry *caches = GET_CACHE(); \ - _PyAdaptiveEntry *cache0 = &caches[0].adaptive; \ + _PyAttrCache *cache = (_PyAttrCache *)next_instr; \ DEOPT_IF(!PyModule_CheckExact(owner), LOAD_##attr_or_method); \ PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict; \ assert(dict != NULL); \ - DEOPT_IF(dict->ma_keys->dk_version != cache0->version, \ - LOAD_##attr_or_method); \ + DEOPT_IF(dict->ma_keys->dk_version != read_u32(cache->version), \ + LOAD_##attr_or_method); \ assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE); \ - assert(cache0->index < dict->ma_keys->dk_nentries); \ - PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + cache0->index; \ + assert(cache->index < dict->ma_keys->dk_nentries); \ + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + cache->index; \ res = ep->me_value; \ DEOPT_IF(res == NULL, LOAD_##attr_or_method); \ STAT_INC(LOAD_##attr_or_method, hit); \ @@ -2197,7 +2196,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int PyObject *sub = TOP(); PyObject *container = SECOND(); _PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr; - uint32_t type_version = read32(&cache->type_version); + uint32_t type_version = read_u32(cache->type_version); PyTypeObject *tp = Py_TYPE(container); DEOPT_IF(tp->tp_version_tag != type_version, BINARY_SUBSCR); assert(tp->tp_flags & Py_TPFLAGS_HEAPTYPE); @@ -2849,8 +2848,10 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int err = PyObject_SetAttr(owner, name, v); Py_DECREF(v); Py_DECREF(owner); - if (err != 0) + if (err != 0) { goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_STORE_ATTR); DISPATCH(); } @@ -3028,7 +3029,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); PyDictObject *dict = (PyDictObject *)GLOBALS(); _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; - uint32_t version = read32(&cache->module_keys_version); + uint32_t version = read_u32(cache->module_keys_version); DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); assert(DK_IS_UNICODE(dict->ma_keys)); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); @@ -3048,7 +3049,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int PyDictObject *mdict = (PyDictObject *)GLOBALS(); PyDictObject *bdict = (PyDictObject *)BUILTINS(); _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; - uint32_t mod_version = read32(&cache->module_keys_version); + uint32_t mod_version = read_u32(cache->module_keys_version); uint16_t bltn_version = cache->builtin_keys_version; DEOPT_IF(mdict->ma_keys->dk_version != mod_version, LOAD_GLOBAL); DEOPT_IF(bdict->ma_keys->dk_version != bltn_version, LOAD_GLOBAL); @@ -3423,76 +3424,49 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } Py_DECREF(owner); SET_TOP(res); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); DISPATCH(); } TARGET(LOAD_ATTR_ADAPTIVE) { assert(cframe.use_tracing == 0); - SpecializedCacheEntry *cache = GET_CACHE(); - if (cache->adaptive.counter == 0) { + _PyAttrCache *cache = (_PyAttrCache *)next_instr; + if (cache->counter == 0) { PyObject *owner = TOP(); - PyObject *name = GETITEM(names, cache->adaptive.original_oparg); + PyObject *name = GETITEM(names, oparg); next_instr--; - if (_Py_Specialize_LoadAttr(owner, next_instr, name, cache) < 0) { + if (_Py_Specialize_LoadAttr(owner, next_instr, name) < 0) { goto error; } DISPATCH(); } else { STAT_INC(LOAD_ATTR, deferred); - cache->adaptive.counter--; - oparg = cache->adaptive.original_oparg; + cache->counter--; JUMP_TO_INSTRUCTION(LOAD_ATTR); } } - TARGET(LOAD_FAST__LOAD_ATTR_INSTANCE_VALUE) { - assert(cframe.use_tracing == 0); - PyObject *owner = GETLOCAL(oparg); // borrowed - if (owner == NULL) { - goto unbound_local_error; - } - // GET_CACHE(), but for the following opcode - assert(_Py_OPCODE(*next_instr) == LOAD_ATTR_INSTANCE_VALUE); - SpecializedCacheEntry *caches = _GetSpecializedCacheEntryForInstruction( - first_instr, INSTR_OFFSET() + 1, _Py_OPARG(*next_instr)); - _PyAdaptiveEntry *cache0 = &caches[0].adaptive; - assert(cache0->version != 0); - PyTypeObject *tp = Py_TYPE(owner); - // These DEOPT_IF miss branches do PUSH(Py_NewRef(owner)). - DEOPT_IF(tp->tp_version_tag != cache0->version, - LOAD_FAST__LOAD_ATTR_INSTANCE_VALUE); - assert(tp->tp_dictoffset < 0); - assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictValues *values = *_PyObject_ValuesPointer(owner); - DEOPT_IF(values == NULL, LOAD_FAST__LOAD_ATTR_INSTANCE_VALUE); - PyObject *res = values->values[cache0->index]; - DEOPT_IF(res == NULL, LOAD_FAST__LOAD_ATTR_INSTANCE_VALUE); - STAT_INC(LOAD_ATTR, hit); - PUSH(Py_NewRef(res)); - next_instr++; - NOTRACE_DISPATCH(); - } - TARGET(LOAD_ATTR_INSTANCE_VALUE) { assert(cframe.use_tracing == 0); PyObject *owner = TOP(); PyObject *res; PyTypeObject *tp = Py_TYPE(owner); - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAdaptiveEntry *cache0 = &caches[0].adaptive; - assert(cache0->version != 0); - DEOPT_IF(tp->tp_version_tag != cache0->version, LOAD_ATTR_INSTANCE_VALUE); + _PyAttrCache *cache = (_PyAttrCache *)next_instr; + uint32_t type_version = read_u32(cache->version); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); assert(tp->tp_dictoffset < 0); assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); PyDictValues *values = *_PyObject_ValuesPointer(owner); - DEOPT_IF(values == NULL, LOAD_ATTR_INSTANCE_VALUE); - res = values->values[cache0->index]; - DEOPT_IF(res == NULL, LOAD_ATTR_INSTANCE_VALUE); + DEOPT_IF(values == NULL, LOAD_ATTR); + res = values->values[cache->index]; + DEOPT_IF(res == NULL, LOAD_ATTR); STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); SET_TOP(res); Py_DECREF(owner); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); NOTRACE_DISPATCH(); } @@ -3504,6 +3478,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int LOAD_MODULE_ATTR_OR_METHOD(ATTR); SET_TOP(res); Py_DECREF(owner); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); NOTRACE_DISPATCH(); } @@ -3512,16 +3487,16 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int PyObject *owner = TOP(); PyObject *res; PyTypeObject *tp = Py_TYPE(owner); - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAdaptiveEntry *cache0 = &caches[0].adaptive; - assert(cache0->version != 0); - DEOPT_IF(tp->tp_version_tag != cache0->version, LOAD_ATTR); + _PyAttrCache *cache = (_PyAttrCache *)next_instr; + uint32_t type_version = read_u32(cache->version); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); PyDictObject *dict = *(PyDictObject **)_PyObject_ManagedDictPointer(owner); DEOPT_IF(dict == NULL, LOAD_ATTR); assert(PyDict_CheckExact((PyObject *)dict)); - PyObject *name = GETITEM(names, cache0->original_oparg); - uint16_t hint = cache0->index; + PyObject *name = GETITEM(names, oparg); + uint16_t hint = cache->index; DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, LOAD_ATTR); if (DK_IS_UNICODE(dict->ma_keys)) { PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint; @@ -3538,6 +3513,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int Py_INCREF(res); SET_TOP(res); Py_DECREF(owner); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); NOTRACE_DISPATCH(); } @@ -3546,36 +3522,36 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int PyObject *owner = TOP(); PyObject *res; PyTypeObject *tp = Py_TYPE(owner); - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAdaptiveEntry *cache0 = &caches[0].adaptive; - assert(cache0->version != 0); - DEOPT_IF(tp->tp_version_tag != cache0->version, LOAD_ATTR); - char *addr = (char *)owner + cache0->index; + _PyAttrCache *cache = (_PyAttrCache *)next_instr; + uint32_t type_version = read_u32(cache->version); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); + char *addr = (char *)owner + cache->index; res = *(PyObject **)addr; DEOPT_IF(res == NULL, LOAD_ATTR); STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); SET_TOP(res); Py_DECREF(owner); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); NOTRACE_DISPATCH(); } TARGET(STORE_ATTR_ADAPTIVE) { assert(cframe.use_tracing == 0); - SpecializedCacheEntry *cache = GET_CACHE(); - if (cache->adaptive.counter == 0) { + _PyAttrCache *cache = (_PyAttrCache *)next_instr; + if (cache->counter == 0) { PyObject *owner = TOP(); - PyObject *name = GETITEM(names, cache->adaptive.original_oparg); + PyObject *name = GETITEM(names, oparg); next_instr--; - if (_Py_Specialize_StoreAttr(owner, next_instr, name, cache) < 0) { + if (_Py_Specialize_StoreAttr(owner, next_instr, name) < 0) { goto error; } DISPATCH(); } else { STAT_INC(STORE_ATTR, deferred); - cache->adaptive.counter--; - oparg = cache->adaptive.original_oparg; + cache->counter--; JUMP_TO_INSTRUCTION(STORE_ATTR); } } @@ -3584,15 +3560,15 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert(cframe.use_tracing == 0); PyObject *owner = TOP(); PyTypeObject *tp = Py_TYPE(owner); - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAdaptiveEntry *cache0 = &caches[0].adaptive; - assert(cache0->version != 0); - DEOPT_IF(tp->tp_version_tag != cache0->version, STORE_ATTR); + _PyAttrCache *cache = (_PyAttrCache *)next_instr; + uint32_t type_version = read_u32(cache->version); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); PyDictValues *values = *_PyObject_ValuesPointer(owner); DEOPT_IF(values == NULL, STORE_ATTR); STAT_INC(STORE_ATTR, hit); - Py_ssize_t index = cache0->index; + Py_ssize_t index = cache->index; STACK_SHRINK(1); PyObject *value = POP(); PyObject *old_value = values->values[index]; @@ -3604,6 +3580,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int Py_DECREF(old_value); } Py_DECREF(owner); + JUMPBY(INLINE_CACHE_ENTRIES_STORE_ATTR); NOTRACE_DISPATCH(); } @@ -3611,16 +3588,16 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert(cframe.use_tracing == 0); PyObject *owner = TOP(); PyTypeObject *tp = Py_TYPE(owner); - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAdaptiveEntry *cache0 = &caches[0].adaptive; - assert(cache0->version != 0); - DEOPT_IF(tp->tp_version_tag != cache0->version, STORE_ATTR); + _PyAttrCache *cache = (_PyAttrCache *)next_instr; + uint32_t type_version = read_u32(cache->version); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); PyDictObject *dict = *(PyDictObject **)_PyObject_ManagedDictPointer(owner); DEOPT_IF(dict == NULL, STORE_ATTR); assert(PyDict_CheckExact((PyObject *)dict)); - PyObject *name = GETITEM(names, cache0->original_oparg); - uint16_t hint = cache0->index; + PyObject *name = GETITEM(names, oparg); + uint16_t hint = cache->index; DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, STORE_ATTR); PyObject *value, *old_value; if (DK_IS_UNICODE(dict->ma_keys)) { @@ -3650,6 +3627,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int /* PEP 509 */ dict->ma_version_tag = DICT_NEXT_VERSION(); Py_DECREF(owner); + JUMPBY(INLINE_CACHE_ENTRIES_STORE_ATTR); NOTRACE_DISPATCH(); } @@ -3657,11 +3635,11 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert(cframe.use_tracing == 0); PyObject *owner = TOP(); PyTypeObject *tp = Py_TYPE(owner); - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAdaptiveEntry *cache0 = &caches[0].adaptive; - assert(cache0->version != 0); - DEOPT_IF(tp->tp_version_tag != cache0->version, STORE_ATTR); - char *addr = (char *)owner + cache0->index; + _PyAttrCache *cache = (_PyAttrCache *)next_instr; + uint32_t type_version = read_u32(cache->version); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); + char *addr = (char *)owner + cache->index; STAT_INC(STORE_ATTR, hit); STACK_SHRINK(1); PyObject *value = POP(); @@ -3669,6 +3647,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int *(PyObject **)addr = value; Py_XDECREF(old_value); Py_DECREF(owner); + JUMPBY(INLINE_CACHE_ENTRIES_STORE_ATTR); NOTRACE_DISPATCH(); } @@ -4425,25 +4404,25 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int Py_DECREF(obj); PUSH(meth); } + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_METHOD); DISPATCH(); } TARGET(LOAD_METHOD_ADAPTIVE) { assert(cframe.use_tracing == 0); - SpecializedCacheEntry *cache = GET_CACHE(); - if (cache->adaptive.counter == 0) { + _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; + if (cache->counter == 0) { PyObject *owner = TOP(); - PyObject *name = GETITEM(names, cache->adaptive.original_oparg); + PyObject *name = GETITEM(names, oparg); next_instr--; - if (_Py_Specialize_LoadMethod(owner, next_instr, name, cache) < 0) { + if (_Py_Specialize_LoadMethod(owner, next_instr, name) < 0) { goto error; } DISPATCH(); } else { STAT_INC(LOAD_METHOD, deferred); - cache->adaptive.counter--; - oparg = cache->adaptive.original_oparg; + cache->counter--; JUMP_TO_INSTRUCTION(LOAD_METHOD); } } @@ -4453,22 +4432,24 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert(cframe.use_tracing == 0); PyObject *self = TOP(); PyTypeObject *self_cls = Py_TYPE(self); - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAttrCache *cache1 = &caches[-1].attr; - _PyObjectCache *cache2 = &caches[-2].obj; - assert(cache1->tp_version != 0); - DEOPT_IF(self_cls->tp_version_tag != cache1->tp_version, LOAD_METHOD); + _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; + uint32_t type_version = read_u32(cache->type_version); + assert(type_version != 0); + DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_METHOD); assert(self_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT); PyDictObject *dict = *(PyDictObject**)_PyObject_ManagedDictPointer(self); DEOPT_IF(dict != NULL, LOAD_METHOD); - DEOPT_IF(((PyHeapTypeObject *)self_cls)->ht_cached_keys->dk_version != cache1->dk_version, LOAD_METHOD); + PyHeapTypeObject *self_heap_type = (PyHeapTypeObject *)self_cls; + DEOPT_IF(self_heap_type->ht_cached_keys->dk_version != + read_u32(cache->keys_version), LOAD_METHOD); STAT_INC(LOAD_METHOD, hit); - PyObject *res = cache2->obj; + PyObject *res = read_obj(cache->descr); assert(res != NULL); assert(_PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)); Py_INCREF(res); SET_TOP(res); PUSH(self); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_METHOD); NOTRACE_DISPATCH(); } @@ -4478,14 +4459,12 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert(cframe.use_tracing == 0); PyObject *self = TOP(); PyTypeObject *self_cls = Py_TYPE(self); - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAdaptiveEntry *cache0 = &caches[0].adaptive; - _PyAttrCache *cache1 = &caches[-1].attr; - _PyObjectCache *cache2 = &caches[-2].obj; + _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; - DEOPT_IF(self_cls->tp_version_tag != cache1->tp_version, LOAD_METHOD); + DEOPT_IF(self_cls->tp_version_tag != read_u32(cache->type_version), + LOAD_METHOD); /* Treat index as a signed 16 bit value */ - int dictoffset = *(int16_t *)&cache0->index; + int dictoffset = *(int16_t *)&cache->dict_offset; PyDictObject **dictptr = (PyDictObject**)(((char *)self)+dictoffset); assert( dictoffset == MANAGED_DICT_OFFSET || @@ -4493,14 +4472,16 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int ); PyDictObject *dict = *dictptr; DEOPT_IF(dict == NULL, LOAD_METHOD); - DEOPT_IF(dict->ma_keys->dk_version != cache1->dk_version, LOAD_METHOD); + DEOPT_IF(dict->ma_keys->dk_version != read_u32(cache->keys_version), + LOAD_METHOD); STAT_INC(LOAD_METHOD, hit); - PyObject *res = cache2->obj; + PyObject *res = read_obj(cache->descr); assert(res != NULL); assert(_PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)); Py_INCREF(res); SET_TOP(res); PUSH(self); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_METHOD); NOTRACE_DISPATCH(); } @@ -4508,18 +4489,18 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert(cframe.use_tracing == 0); PyObject *self = TOP(); PyTypeObject *self_cls = Py_TYPE(self); - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAttrCache *cache1 = &caches[-1].attr; - _PyObjectCache *cache2 = &caches[-2].obj; - DEOPT_IF(self_cls->tp_version_tag != cache1->tp_version, LOAD_METHOD); + _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; + uint32_t type_version = read_u32(cache->type_version); + DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_METHOD); assert(self_cls->tp_dictoffset == 0); STAT_INC(LOAD_METHOD, hit); - PyObject *res = cache2->obj; + PyObject *res = read_obj(cache->descr); assert(res != NULL); assert(_PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)); Py_INCREF(res); SET_TOP(res); PUSH(self); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_METHOD); NOTRACE_DISPATCH(); } @@ -4532,29 +4513,30 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int SET_TOP(NULL); Py_DECREF(owner); PUSH(res); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_METHOD); NOTRACE_DISPATCH(); } TARGET(LOAD_METHOD_CLASS) { /* LOAD_METHOD, for class methods */ assert(cframe.use_tracing == 0); - SpecializedCacheEntry *caches = GET_CACHE(); - _PyAttrCache *cache1 = &caches[-1].attr; - _PyObjectCache *cache2 = &caches[-2].obj; + _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; PyObject *cls = TOP(); DEOPT_IF(!PyType_Check(cls), LOAD_METHOD); - DEOPT_IF(((PyTypeObject *)cls)->tp_version_tag != cache1->tp_version, - LOAD_METHOD); - assert(cache1->tp_version != 0); + uint32_t type_version = read_u32(cache->type_version); + DEOPT_IF(((PyTypeObject *)cls)->tp_version_tag != type_version, + LOAD_METHOD); + assert(type_version != 0); STAT_INC(LOAD_METHOD, hit); - PyObject *res = cache2->obj; + PyObject *res = read_obj(cache->descr); assert(res != NULL); Py_INCREF(res); SET_TOP(NULL); Py_DECREF(cls); PUSH(res); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_METHOD); NOTRACE_DISPATCH(); } @@ -5607,10 +5589,10 @@ opname ## _miss: \ JUMP_TO_INSTRUCTION(opname); \ } -MISS_WITH_CACHE(LOAD_ATTR) -MISS_WITH_CACHE(STORE_ATTR) +MISS_WITH_INLINE_CACHE(LOAD_ATTR) +MISS_WITH_INLINE_CACHE(STORE_ATTR) MISS_WITH_INLINE_CACHE(LOAD_GLOBAL) -MISS_WITH_CACHE(LOAD_METHOD) +MISS_WITH_INLINE_CACHE(LOAD_METHOD) MISS_WITH_CACHE(PRECALL) MISS_WITH_CACHE(CALL) MISS_WITH_INLINE_CACHE(BINARY_OP) @@ -5619,52 +5601,6 @@ MISS_WITH_INLINE_CACHE(BINARY_SUBSCR) MISS_WITH_INLINE_CACHE(UNPACK_SEQUENCE) MISS_WITH_OPARG_COUNTER(STORE_SUBSCR) -LOAD_ATTR_INSTANCE_VALUE_miss: - { - // Special-cased so that if LOAD_ATTR_INSTANCE_VALUE - // gets replaced, then any preceeding - // LOAD_FAST__LOAD_ATTR_INSTANCE_VALUE gets replaced as well - STAT_INC(LOAD_ATTR_INSTANCE_VALUE, miss); - STAT_INC(LOAD_ATTR, miss); - _PyAdaptiveEntry *cache = &GET_CACHE()->adaptive; - cache->counter--; - if (cache->counter == 0) { - next_instr[-1] = _Py_MAKECODEUNIT(LOAD_ATTR_ADAPTIVE, _Py_OPARG(next_instr[-1])); - if (_Py_OPCODE(next_instr[-2]) == LOAD_FAST__LOAD_ATTR_INSTANCE_VALUE) { - next_instr[-2] = _Py_MAKECODEUNIT(LOAD_FAST, _Py_OPARG(next_instr[-2])); - if (_Py_OPCODE(next_instr[-3]) == LOAD_FAST) { - next_instr[-3] = _Py_MAKECODEUNIT(LOAD_FAST__LOAD_FAST, _Py_OPARG(next_instr[-3])); - } - } - STAT_INC(LOAD_ATTR, deopt); - cache_backoff(cache); - } - oparg = cache->original_oparg; - JUMP_TO_INSTRUCTION(LOAD_ATTR); - } - -LOAD_FAST__LOAD_ATTR_INSTANCE_VALUE_miss: - { - // This is special-cased because we have a superinstruction - // that includes a specialized instruction. - // If the specialized portion misses, carry out - // the first instruction, then perform a miss - // for the second instruction as usual. - - // Do LOAD_FAST - { - PyObject *value = GETLOCAL(oparg); - assert(value != NULL); // Already checked if unbound - Py_INCREF(value); - PUSH(value); - NEXTOPARG(); - next_instr++; - } - - // Now we are in the correct state for LOAD_ATTR - goto LOAD_ATTR_INSTANCE_VALUE_miss; - } - binary_subscr_dict_error: { PyObject *sub = POP(); diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index d463e303e27ac..7be7b168a755d 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -175,7 +175,7 @@ static void *opcode_targets[256] = { &&TARGET_LOAD_FAST__LOAD_CONST, &&TARGET_LOAD_CONST__LOAD_FAST, &&TARGET_STORE_FAST__STORE_FAST, - &&TARGET_LOAD_FAST__LOAD_ATTR_INSTANCE_VALUE, + &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, diff --git a/Python/specialize.c b/Python/specialize.c index 4a94aafefea9c..66dce8c93d77b 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -58,12 +58,9 @@ static uint8_t adaptive_opcodes[256] = { /* The number of cache entries required for a "family" of instructions. */ static uint8_t cache_requirements[256] = { - [LOAD_ATTR] = 1, // _PyAdaptiveEntry - [LOAD_METHOD] = 3, /* _PyAdaptiveEntry, _PyAttrCache and _PyObjectCache */ [STORE_SUBSCR] = 0, [CALL] = 2, /* _PyAdaptiveEntry and _PyObjectCache/_PyCallCache */ [PRECALL] = 2, /* _PyAdaptiveEntry and _PyObjectCache/_PyCallCache */ - [STORE_ATTR] = 1, // _PyAdaptiveEntry }; Py_ssize_t _Py_QuickenedCount = 0; @@ -641,11 +638,10 @@ initial_counter_value(void) { static int -specialize_module_load_attr( - PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, - _PyAdaptiveEntry *cache0, int opcode, - int opcode_module) +specialize_module_load_attr(PyObject *owner, _Py_CODEUNIT *instr, + PyObject *name, int opcode, int opcode_module) { + _PyAttrCache *cache = (_PyAttrCache *)(instr + 1); PyModuleObject *m = (PyModuleObject *)owner; PyObject *value = NULL; assert((owner->ob_type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0); @@ -676,8 +672,8 @@ specialize_module_load_attr( SPECIALIZATION_FAIL(opcode, SPEC_FAIL_OUT_OF_VERSIONS); return -1; } - cache0->version = keys_version; - cache0->index = (uint16_t)index; + write_u32(cache->version, keys_version); + cache->index = (uint16_t)index; *instr = _Py_MAKECODEUNIT(opcode_module, _Py_OPARG(*instr)); return 0; } @@ -765,7 +761,6 @@ static int specialize_dict_access( PyObject *owner, _Py_CODEUNIT *instr, PyTypeObject *type, DescriptorClassification kind, PyObject *name, - _PyAdaptiveEntry *cache0, int base_op, int values_op, int hint_op) { assert(kind == NON_OVERRIDING || kind == NON_DESCRIPTOR || kind == ABSENT || @@ -775,6 +770,7 @@ specialize_dict_access( SPECIALIZATION_FAIL(base_op, SPEC_FAIL_ATTR_NOT_MANAGED_DICT); return 0; } + _PyAttrCache *cache = (_PyAttrCache *)(instr + 1); PyObject **dictptr = _PyObject_ManagedDictPointer(owner); PyDictObject *dict = (PyDictObject *)*dictptr; if (dict == NULL) { @@ -787,8 +783,8 @@ specialize_dict_access( SPECIALIZATION_FAIL(base_op, SPEC_FAIL_OUT_OF_RANGE); return 0; } - cache0->version = type->tp_version_tag; - cache0->index = (uint16_t)index; + write_u32(cache->version, type->tp_version_tag); + cache->index = (uint16_t)index; *instr = _Py_MAKECODEUNIT(values_op, _Py_OPARG(*instr)); } else { @@ -804,20 +800,22 @@ specialize_dict_access( SPECIALIZATION_FAIL(base_op, SPEC_FAIL_OUT_OF_RANGE); return 0; } - cache0->index = (uint16_t)hint; - cache0->version = type->tp_version_tag; + cache->index = (uint16_t)hint; + write_u32(cache->version, type->tp_version_tag); *instr = _Py_MAKECODEUNIT(hint_op, _Py_OPARG(*instr)); } return 1; } int -_Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, SpecializedCacheEntry *cache) +_Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) { - _PyAdaptiveEntry *cache0 = &cache->adaptive; + assert(_PyOpcode_InlineCacheEntries[LOAD_ATTR] == + INLINE_CACHE_ENTRIES_LOAD_ATTR); + _PyAttrCache *cache = (_PyAttrCache *)(instr + 1); if (PyModule_CheckExact(owner)) { - int err = specialize_module_load_attr(owner, instr, name, cache0, - LOAD_ATTR, LOAD_ATTR_MODULE); + int err = specialize_module_load_attr(owner, instr, name, LOAD_ATTR, + LOAD_ATTR_MODULE); if (err) { goto fail; } @@ -856,8 +854,8 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, Sp } assert(dmem->type == T_OBJECT_EX); assert(offset > 0); - cache0->index = (uint16_t)offset; - cache0->version = type->tp_version_tag; + cache->index = (uint16_t)offset; + write_u32(cache->version, type->tp_version_tag); *instr = _Py_MAKECODEUNIT(LOAD_ATTR_SLOT, _Py_OPARG(*instr)); goto success; } @@ -865,8 +863,8 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, Sp { Py_ssize_t offset = offsetof(PyObject, ob_type); assert(offset == (uint16_t)offset); - cache0->index = (uint16_t)offset; - cache0->version = type->tp_version_tag; + cache->index = (uint16_t)offset; + write_u32(cache->version, type->tp_version_tag); *instr = _Py_MAKECODEUNIT(LOAD_ATTR_SLOT, _Py_OPARG(*instr)); goto success; } @@ -887,41 +885,33 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, Sp break; } int err = specialize_dict_access( - owner, instr, type, kind, name, cache0, + owner, instr, type, kind, name, LOAD_ATTR, LOAD_ATTR_INSTANCE_VALUE, LOAD_ATTR_WITH_HINT ); if (err < 0) { return -1; } if (err) { - if (_Py_OPCODE(instr[0]) == LOAD_ATTR_INSTANCE_VALUE) { - // Note: instr[-1] exists because there's something on the stack, - // and instr[-2] exists because there's at least a RESUME as well. - if (_Py_OPCODE(instr[-1]) == LOAD_FAST) { - instr[-1] = _Py_MAKECODEUNIT(LOAD_FAST__LOAD_ATTR_INSTANCE_VALUE, _Py_OPARG(instr[-1])); - if (_Py_OPCODE(instr[-2]) == LOAD_FAST__LOAD_FAST) { - instr[-2] = _Py_MAKECODEUNIT(LOAD_FAST, _Py_OPARG(instr[-2])); - } - } - } goto success; } fail: STAT_INC(LOAD_ATTR, failure); assert(!PyErr_Occurred()); - cache_backoff(cache0); + cache->counter = ADAPTIVE_CACHE_BACKOFF; return 0; success: STAT_INC(LOAD_ATTR, success); assert(!PyErr_Occurred()); - cache0->counter = initial_counter_value(); + cache->counter = initial_counter_value(); return 0; } int -_Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, SpecializedCacheEntry *cache) +_Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) { - _PyAdaptiveEntry *cache0 = &cache->adaptive; + assert(_PyOpcode_InlineCacheEntries[STORE_ATTR] == + INLINE_CACHE_ENTRIES_STORE_ATTR); + _PyAttrCache *cache = (_PyAttrCache *)(instr + 1); PyTypeObject *type = Py_TYPE(owner); if (PyModule_CheckExact(owner)) { SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_OVERRIDDEN); @@ -954,8 +944,8 @@ _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, S } assert(dmem->type == T_OBJECT_EX); assert(offset > 0); - cache0->index = (uint16_t)offset; - cache0->version = type->tp_version_tag; + cache->index = (uint16_t)offset; + write_u32(cache->version, type->tp_version_tag); *instr = _Py_MAKECODEUNIT(STORE_ATTR_SLOT, _Py_OPARG(*instr)); goto success; } @@ -978,7 +968,7 @@ _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, S } int err = specialize_dict_access( - owner, instr, type, kind, name, cache0, + owner, instr, type, kind, name, STORE_ATTR, STORE_ATTR_INSTANCE_VALUE, STORE_ATTR_WITH_HINT ); if (err < 0) { @@ -990,12 +980,12 @@ _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, S fail: STAT_INC(STORE_ATTR, failure); assert(!PyErr_Occurred()); - cache_backoff(cache0); + cache->counter = ADAPTIVE_CACHE_BACKOFF; return 0; success: STAT_INC(STORE_ATTR, success); assert(!PyErr_Occurred()); - cache0->counter = initial_counter_value(); + cache->counter = initial_counter_value(); return 0; } @@ -1037,18 +1027,18 @@ load_method_fail_kind(DescriptorClassification kind) #endif static int -specialize_class_load_method(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, - _PyAttrCache *cache1, _PyObjectCache *cache2) +specialize_class_load_method(PyObject *owner, _Py_CODEUNIT *instr, + PyObject *name) { - + _PyLoadMethodCache *cache = (_PyLoadMethodCache *)(instr + 1); PyObject *descr = NULL; DescriptorClassification kind = 0; kind = analyze_descriptor((PyTypeObject *)owner, name, &descr, 0); switch (kind) { case METHOD: case NON_DESCRIPTOR: - cache1->tp_version = ((PyTypeObject *)owner)->tp_version_tag; - cache2->obj = descr; + write_u32(cache->type_version, ((PyTypeObject *)owner)->tp_version_tag); + write_obj(cache->descr, descr); *instr = _Py_MAKECODEUNIT(LOAD_METHOD_CLASS, _Py_OPARG(*instr)); return 0; #ifdef Py_STATS @@ -1078,16 +1068,18 @@ typedef enum { // can cause a significant drop in cache hits. A possible test is // python.exe -m test_typing test_re test_dis test_zlib. int -_Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, SpecializedCacheEntry *cache) +_Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) { - _PyAdaptiveEntry *cache0 = &cache->adaptive; - _PyAttrCache *cache1 = &cache[-1].attr; - _PyObjectCache *cache2 = &cache[-2].obj; + assert(_PyOpcode_InlineCacheEntries[LOAD_METHOD] == + INLINE_CACHE_ENTRIES_LOAD_METHOD); + _PyLoadMethodCache *cache = (_PyLoadMethodCache *)(instr + 1); PyTypeObject *owner_cls = Py_TYPE(owner); if (PyModule_CheckExact(owner)) { - int err = specialize_module_load_attr(owner, instr, name, cache0, - LOAD_METHOD, LOAD_METHOD_MODULE); + assert(INLINE_CACHE_ENTRIES_LOAD_ATTR <= + INLINE_CACHE_ENTRIES_LOAD_METHOD); + int err = specialize_module_load_attr(owner, instr, name, LOAD_METHOD, + LOAD_METHOD_MODULE); if (err) { goto fail; } @@ -1099,7 +1091,7 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, } } if (PyType_Check(owner)) { - int err = specialize_class_load_method(owner, instr, name, cache1, cache2); + int err = specialize_class_load_method(owner, instr, name); if (err) { goto fail; } @@ -1157,7 +1149,7 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OUT_OF_VERSIONS); goto fail; } - cache1->dk_version = keys_version; + write_u32(cache->keys_version, keys_version); } switch(dictkind) { case NO_DICT: @@ -1167,12 +1159,12 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, *instr = _Py_MAKECODEUNIT(LOAD_METHOD_WITH_VALUES, _Py_OPARG(*instr)); break; case MANAGED_DICT: - *(int16_t *)&cache0->index = (int16_t)MANAGED_DICT_OFFSET; + *(int16_t *)&cache->dict_offset = (int16_t)MANAGED_DICT_OFFSET; *instr = _Py_MAKECODEUNIT(LOAD_METHOD_WITH_DICT, _Py_OPARG(*instr)); break; case OFFSET_DICT: assert(owner_cls->tp_dictoffset > 0 && owner_cls->tp_dictoffset <= INT16_MAX); - cache0->index = (uint16_t)owner_cls->tp_dictoffset; + cache->dict_offset = (uint16_t)owner_cls->tp_dictoffset; *instr = _Py_MAKECODEUNIT(LOAD_METHOD_WITH_DICT, _Py_OPARG(*instr)); break; } @@ -1190,18 +1182,18 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, * PyType_Modified usages in typeobject.c). The MCACHE has been * working since Python 2.6 and it's battle-tested. */ - cache1->tp_version = owner_cls->tp_version_tag; - cache2->obj = descr; + write_u32(cache->type_version, owner_cls->tp_version_tag); + write_obj(cache->descr, descr); // Fall through. success: STAT_INC(LOAD_METHOD, success); assert(!PyErr_Occurred()); - cache0->counter = initial_counter_value(); + cache->counter = initial_counter_value(); return 0; fail: STAT_INC(LOAD_METHOD, failure); assert(!PyErr_Occurred()); - cache_backoff(cache0); + cache->counter = ADAPTIVE_CACHE_BACKOFF; return 0; } @@ -1238,7 +1230,7 @@ _Py_Specialize_LoadGlobal( goto fail; } cache->index = (uint16_t)index; - write32(&cache->module_keys_version, keys_version); + write_u32(cache->module_keys_version, keys_version); *instr = _Py_MAKECODEUNIT(LOAD_GLOBAL_MODULE, _Py_OPARG(*instr)); goto success; } @@ -1273,7 +1265,7 @@ _Py_Specialize_LoadGlobal( goto fail; } cache->index = (uint16_t)index; - write32(&cache->module_keys_version, globals_version); + write_u32(cache->module_keys_version, globals_version); cache->builtin_keys_version = (uint16_t)builtins_version; *instr = _Py_MAKECODEUNIT(LOAD_GLOBAL_BUILTIN, _Py_OPARG(*instr)); goto success; @@ -1393,7 +1385,7 @@ _Py_Specialize_BinarySubscr( goto fail; } assert(cls->tp_version_tag != 0); - write32(&cache->type_version, cls->tp_version_tag); + write_u32(cache->type_version, cls->tp_version_tag); int version = _PyFunction_GetVersionForCurrentState(func); if (version == 0 || version != (uint16_t)version) { SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_OUT_OF_VERSIONS); From webhook-mailer at python.org Thu Mar 3 18:41:44 2022 From: webhook-mailer at python.org (vstinner) Date: Thu, 03 Mar 2022 23:41:44 -0000 Subject: [Python-checkins] bpo-46913: test_hashlib skips _sha3 tests on UBSan (GH-31673) Message-ID: https://github.com/python/cpython/commit/6d0d7d2b8c1e04fd51c6cb29cc09a41b60b97b7b commit: 6d0d7d2b8c1e04fd51c6cb29cc09a41b60b97b7b branch: main author: Victor Stinner committer: vstinner date: 2022-03-04T00:41:34+01:00 summary: bpo-46913: test_hashlib skips _sha3 tests on UBSan (GH-31673) If Python is built with UBSan, test_hashlib skips tests on the _sha3 extension which currently has undefined behaviors. This change allows to run test_hashlib to check for new UBSan regression, but the known _sha3 undefined behavior must be fixed. files: M Lib/test/test_hashlib.py diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py index 110eb48fd4f8c..ea31f8be2cb82 100644 --- a/Lib/test/test_hashlib.py +++ b/Lib/test/test_hashlib.py @@ -64,6 +64,10 @@ def get_fips_mode(): requires_blake2 = unittest.skipUnless(_blake2, 'requires _blake2') +# bpo-46913: Don't test the _sha3 extension on a Python UBSAN build +SKIP_SHA3 = support.check_sanitizer(ub=True) +requires_sha3 = unittest.skipUnless(not SKIP_SHA3, 'requires _sha3') + def hexstr(s): assert isinstance(s, bytes), repr(s) @@ -125,6 +129,8 @@ def __init__(self, *args, **kwargs): self.constructors_to_test = {} for algorithm in algorithms: + if SKIP_SHA3 and algorithm.startswith('sha3_'): + continue self.constructors_to_test[algorithm] = set() # For each algorithm, test the direct constructor and the use @@ -177,14 +183,15 @@ def add_builtin_constructor(name): add_builtin_constructor('blake2s') add_builtin_constructor('blake2b') - _sha3 = self._conditional_import_module('_sha3') - if _sha3: - add_builtin_constructor('sha3_224') - add_builtin_constructor('sha3_256') - add_builtin_constructor('sha3_384') - add_builtin_constructor('sha3_512') - add_builtin_constructor('shake_128') - add_builtin_constructor('shake_256') + if not SKIP_SHA3: + _sha3 = self._conditional_import_module('_sha3') + if _sha3: + add_builtin_constructor('sha3_224') + add_builtin_constructor('sha3_256') + add_builtin_constructor('sha3_384') + add_builtin_constructor('sha3_512') + add_builtin_constructor('shake_128') + add_builtin_constructor('shake_256') super(HashLibTestCase, self).__init__(*args, **kwargs) @@ -383,6 +390,7 @@ def test_no_unicode_blake2(self): self.check_no_unicode('blake2b') self.check_no_unicode('blake2s') + @requires_sha3 def test_no_unicode_sha3(self): self.check_no_unicode('sha3_224') self.check_no_unicode('sha3_256') @@ -418,6 +426,7 @@ def test_blocksize_name(self): self.check_blocksize_name('sha384', 128, 48) self.check_blocksize_name('sha512', 128, 64) + @requires_sha3 def test_blocksize_name_sha3(self): self.check_blocksize_name('sha3_224', 144, 28) self.check_blocksize_name('sha3_256', 136, 32) @@ -438,6 +447,7 @@ def check_sha3(self, name, capacity, rate, suffix): self.assertEqual(m._rate_bits, rate) self.assertEqual(m._suffix, suffix) + @requires_sha3 def test_extra_sha3(self): self.check_sha3('sha3_224', 448, 1152, b'\x06') self.check_sha3('sha3_256', 512, 1088, b'\x06') @@ -777,36 +787,44 @@ def test_blake2s_vectors(self): key = bytes.fromhex(key) self.check('blake2s', msg, md, key=key) + @requires_sha3 def test_case_sha3_224_0(self): self.check('sha3_224', b"", "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7") + @requires_sha3 def test_case_sha3_224_vector(self): for msg, md in read_vectors('sha3_224'): self.check('sha3_224', msg, md) + @requires_sha3 def test_case_sha3_256_0(self): self.check('sha3_256', b"", "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a") + @requires_sha3 def test_case_sha3_256_vector(self): for msg, md in read_vectors('sha3_256'): self.check('sha3_256', msg, md) + @requires_sha3 def test_case_sha3_384_0(self): self.check('sha3_384', b"", "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2a"+ "c3713831264adb47fb6bd1e058d5f004") + @requires_sha3 def test_case_sha3_384_vector(self): for msg, md in read_vectors('sha3_384'): self.check('sha3_384', msg, md) + @requires_sha3 def test_case_sha3_512_0(self): self.check('sha3_512', b"", "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a6"+ "15b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26") + @requires_sha3 def test_case_sha3_512_vector(self): for msg, md in read_vectors('sha3_512'): self.check('sha3_512', msg, md) From webhook-mailer at python.org Thu Mar 3 18:42:02 2022 From: webhook-mailer at python.org (vstinner) Date: Thu, 03 Mar 2022 23:42:02 -0000 Subject: [Python-checkins] bpo-46913: Skip test_ctypes.test_shorts() on UBSan (GH-31674) Message-ID: https://github.com/python/cpython/commit/ad1b04451d3aca2c6fa6dbe2891676a4e0baac49 commit: ad1b04451d3aca2c6fa6dbe2891676a4e0baac49 branch: main author: Victor Stinner committer: vstinner date: 2022-03-04T00:41:57+01:00 summary: bpo-46913: Skip test_ctypes.test_shorts() on UBSan (GH-31674) If Python is built with UBSan, test_ctypes now skips test_shorts(). This change allows to run test_ctypes to check for new UBSan regression, but the known test_shorts() undefined behavior must be fixed. files: M Lib/ctypes/test/test_bitfields.py diff --git a/Lib/ctypes/test/test_bitfields.py b/Lib/ctypes/test/test_bitfields.py index 992b8c4da3a77..66acd62e6851a 100644 --- a/Lib/ctypes/test/test_bitfields.py +++ b/Lib/ctypes/test/test_bitfields.py @@ -1,5 +1,6 @@ from ctypes import * from ctypes.test import need_symbol +from test import support import unittest import os @@ -39,6 +40,8 @@ def test_ints(self): setattr(b, name, i) self.assertEqual(getattr(b, name), func(byref(b), name.encode('ascii'))) + # bpo-46913: _ctypes/cfield.c h_get() has an undefined behavior + @support.skip_if_sanitizer(ub=True) def test_shorts(self): b = BITS() name = "M" From webhook-mailer at python.org Thu Mar 3 18:47:01 2022 From: webhook-mailer at python.org (vstinner) Date: Thu, 03 Mar 2022 23:47:01 -0000 Subject: [Python-checkins] bpo-46355: Update pythoncapi_compat project URL (GH-31670) Message-ID: https://github.com/python/cpython/commit/ec4a580f7cada002441ae5611b909d56e3b5b613 commit: ec4a580f7cada002441ae5611b909d56e3b5b613 branch: main author: Victor Stinner committer: vstinner date: 2022-03-04T00:46:56+01:00 summary: bpo-46355: Update pythoncapi_compat project URL (GH-31670) files: M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index fbfe02ccfc2c0..5843287ae8e18 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -909,7 +909,7 @@ Porting to Python 3.11 #endif Or use the `pythoncapi_compat project - `__ to get these two + `__ to get these two functions on older Python versions. * Changes of the :c:type:`PyThreadState` structure members: @@ -962,7 +962,7 @@ Porting to Python 3.11 #endif Or use `the pythoncapi_compat project - `__ to get these functions + `__ to get these functions on old Python functions. From webhook-mailer at python.org Thu Mar 3 19:12:17 2022 From: webhook-mailer at python.org (vstinner) Date: Fri, 04 Mar 2022 00:12:17 -0000 Subject: [Python-checkins] [3.10] bpo-46913: Fix test_ctypes, test_hashlib, test_faulthandler on UBSan (GH-31675) Message-ID: https://github.com/python/cpython/commit/7b5b429adab4fe0fe81858fe3831f06adc2e2141 commit: 7b5b429adab4fe0fe81858fe3831f06adc2e2141 branch: 3.10 author: Victor Stinner committer: vstinner date: 2022-03-04T01:12:06+01:00 summary: [3.10] bpo-46913: Fix test_ctypes, test_hashlib, test_faulthandler on UBSan (GH-31675) * bpo-46913: Fix test_faulthandler.test_sigfpe() on UBSAN (GH-31662) Disable undefined behavior sanitizer (UBSAN) on faulthandler_sigfpe(). (cherry picked from commit 4173d677a1d7c72bb32d292fbff1b4cf073d615c) * bpo-46913: Fix test_faulthandler.test_read_null() on UBSan (GH31672) Disable undefined behavior sanitizer (UBSan) on faulthandler._read_null(). (cherry picked from commit 65b92ccdec2ee4a99e54aaf7ae2d9bbc2ebfe549) * bpo-46913: test_hashlib skips _sha3 tests on UBSan (GH-31673) If Python is built with UBSan, test_hashlib skips tests on the _sha3 extension which currently has undefined behaviors. This change allows to run test_hashlib to check for new UBSan regression, but the known _sha3 undefined behavior must be fixed. (cherry picked from commit 6d0d7d2b8c1e04fd51c6cb29cc09a41b60b97b7b) * bpo-46913: Skip test_ctypes.test_shorts() on UBSan (GH-31674) If Python is built with UBSan, test_ctypes now skips test_shorts(). This change allows to run test_ctypes to check for new UBSan regression, but the known test_shorts() undefined behavior must be fixed. (cherry picked from commit ad1b04451d3aca2c6fa6dbe2891676a4e0baac49) files: A Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst M Lib/ctypes/test/test_bitfields.py M Lib/test/test_hashlib.py M Modules/faulthandler.c diff --git a/Lib/ctypes/test/test_bitfields.py b/Lib/ctypes/test/test_bitfields.py index 992b8c4da3a77..66acd62e6851a 100644 --- a/Lib/ctypes/test/test_bitfields.py +++ b/Lib/ctypes/test/test_bitfields.py @@ -1,5 +1,6 @@ from ctypes import * from ctypes.test import need_symbol +from test import support import unittest import os @@ -39,6 +40,8 @@ def test_ints(self): setattr(b, name, i) self.assertEqual(getattr(b, name), func(byref(b), name.encode('ascii'))) + # bpo-46913: _ctypes/cfield.c h_get() has an undefined behavior + @support.skip_if_sanitizer(ub=True) def test_shorts(self): b = BITS() name = "M" diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py index 110eb48fd4f8c..ea31f8be2cb82 100644 --- a/Lib/test/test_hashlib.py +++ b/Lib/test/test_hashlib.py @@ -64,6 +64,10 @@ def get_fips_mode(): requires_blake2 = unittest.skipUnless(_blake2, 'requires _blake2') +# bpo-46913: Don't test the _sha3 extension on a Python UBSAN build +SKIP_SHA3 = support.check_sanitizer(ub=True) +requires_sha3 = unittest.skipUnless(not SKIP_SHA3, 'requires _sha3') + def hexstr(s): assert isinstance(s, bytes), repr(s) @@ -125,6 +129,8 @@ def __init__(self, *args, **kwargs): self.constructors_to_test = {} for algorithm in algorithms: + if SKIP_SHA3 and algorithm.startswith('sha3_'): + continue self.constructors_to_test[algorithm] = set() # For each algorithm, test the direct constructor and the use @@ -177,14 +183,15 @@ def add_builtin_constructor(name): add_builtin_constructor('blake2s') add_builtin_constructor('blake2b') - _sha3 = self._conditional_import_module('_sha3') - if _sha3: - add_builtin_constructor('sha3_224') - add_builtin_constructor('sha3_256') - add_builtin_constructor('sha3_384') - add_builtin_constructor('sha3_512') - add_builtin_constructor('shake_128') - add_builtin_constructor('shake_256') + if not SKIP_SHA3: + _sha3 = self._conditional_import_module('_sha3') + if _sha3: + add_builtin_constructor('sha3_224') + add_builtin_constructor('sha3_256') + add_builtin_constructor('sha3_384') + add_builtin_constructor('sha3_512') + add_builtin_constructor('shake_128') + add_builtin_constructor('shake_256') super(HashLibTestCase, self).__init__(*args, **kwargs) @@ -383,6 +390,7 @@ def test_no_unicode_blake2(self): self.check_no_unicode('blake2b') self.check_no_unicode('blake2s') + @requires_sha3 def test_no_unicode_sha3(self): self.check_no_unicode('sha3_224') self.check_no_unicode('sha3_256') @@ -418,6 +426,7 @@ def test_blocksize_name(self): self.check_blocksize_name('sha384', 128, 48) self.check_blocksize_name('sha512', 128, 64) + @requires_sha3 def test_blocksize_name_sha3(self): self.check_blocksize_name('sha3_224', 144, 28) self.check_blocksize_name('sha3_256', 136, 32) @@ -438,6 +447,7 @@ def check_sha3(self, name, capacity, rate, suffix): self.assertEqual(m._rate_bits, rate) self.assertEqual(m._suffix, suffix) + @requires_sha3 def test_extra_sha3(self): self.check_sha3('sha3_224', 448, 1152, b'\x06') self.check_sha3('sha3_256', 512, 1088, b'\x06') @@ -777,36 +787,44 @@ def test_blake2s_vectors(self): key = bytes.fromhex(key) self.check('blake2s', msg, md, key=key) + @requires_sha3 def test_case_sha3_224_0(self): self.check('sha3_224', b"", "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7") + @requires_sha3 def test_case_sha3_224_vector(self): for msg, md in read_vectors('sha3_224'): self.check('sha3_224', msg, md) + @requires_sha3 def test_case_sha3_256_0(self): self.check('sha3_256', b"", "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a") + @requires_sha3 def test_case_sha3_256_vector(self): for msg, md in read_vectors('sha3_256'): self.check('sha3_256', msg, md) + @requires_sha3 def test_case_sha3_384_0(self): self.check('sha3_384', b"", "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2a"+ "c3713831264adb47fb6bd1e058d5f004") + @requires_sha3 def test_case_sha3_384_vector(self): for msg, md in read_vectors('sha3_384'): self.check('sha3_384', msg, md) + @requires_sha3 def test_case_sha3_512_0(self): self.check('sha3_512', b"", "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a6"+ "15b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26") + @requires_sha3 def test_case_sha3_512_vector(self): for msg, md in read_vectors('sha3_512'): self.check('sha3_512', msg, md) diff --git a/Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst b/Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst new file mode 100644 index 0000000000000..65fed1c249d87 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst @@ -0,0 +1,3 @@ +Fix test_faulthandler.test_sigfpe() if Python is built with undefined +behavior sanitizer (UBSAN): disable UBSAN on the faulthandler_sigfpe() +function. Patch by Victor Stinner. diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index 350f4cf6b8edf..e03f6d96c8edb 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -29,6 +29,23 @@ #define PUTS(fd, str) _Py_write_noraise(fd, str, strlen(str)) + +// clang uses __attribute__((no_sanitize("undefined"))) +// GCC 4.9+ uses __attribute__((no_sanitize_undefined)) +#if defined(__has_feature) // Clang +# if __has_feature(undefined_behavior_sanitizer) +# define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize("undefined"))) +# endif +#endif +#if defined(__GNUC__) \ + && ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) +# define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize_undefined)) +#endif +#ifndef _Py_NO_SANITIZE_UNDEFINED +# define _Py_NO_SANITIZE_UNDEFINED +#endif + + _Py_IDENTIFIER(enable); _Py_IDENTIFIER(fileno); _Py_IDENTIFIER(flush); @@ -1014,7 +1031,7 @@ faulthandler_suppress_crash_report(void) #endif } -static PyObject * +static PyObject* _Py_NO_SANITIZE_UNDEFINED faulthandler_read_null(PyObject *self, PyObject *args) { volatile int *x; @@ -1103,17 +1120,20 @@ faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args) Py_RETURN_NONE; } -static PyObject * +static PyObject* _Py_NO_SANITIZE_UNDEFINED faulthandler_sigfpe(PyObject *self, PyObject *args) { + faulthandler_suppress_crash_report(); + /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on PowerPC. Use volatile to disable compile-time optimizations. */ volatile int x = 1, y = 0, z; - faulthandler_suppress_crash_report(); z = x / y; + /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC), raise it manually. */ raise(SIGFPE); + /* This line is never reached, but we pretend to make something with z to silence a compiler warning. */ return PyLong_FromLong(z); From webhook-mailer at python.org Thu Mar 3 19:32:05 2022 From: webhook-mailer at python.org (vstinner) Date: Fri, 04 Mar 2022 00:32:05 -0000 Subject: [Python-checkins] bpo-46913: Fix test_ctypes, test_hashlib, test_faulthandler on UBSan (GH-31675) (GH-31676) Message-ID: https://github.com/python/cpython/commit/6a14330318c9c7aedf3e9841c3dfea337064d8e6 commit: 6a14330318c9c7aedf3e9841c3dfea337064d8e6 branch: 3.9 author: Victor Stinner committer: vstinner date: 2022-03-04T01:31:54+01:00 summary: bpo-46913: Fix test_ctypes, test_hashlib, test_faulthandler on UBSan (GH-31675) (GH-31676) * bpo-46913: Fix test_faulthandler.test_sigfpe() on UBSAN (GH-31662) Disable undefined behavior sanitizer (UBSAN) on faulthandler_sigfpe(). (cherry picked from commit 4173d677a1d7c72bb32d292fbff1b4cf073d615c) * bpo-46913: Fix test_faulthandler.test_read_null() on UBSan (GH31672) Disable undefined behavior sanitizer (UBSan) on faulthandler._read_null(). (cherry picked from commit 65b92ccdec2ee4a99e54aaf7ae2d9bbc2ebfe549) * bpo-46913: test_hashlib skips _sha3 tests on UBSan (GH-31673) If Python is built with UBSan, test_hashlib skips tests on the _sha3 extension which currently has undefined behaviors. This change allows to run test_hashlib to check for new UBSan regression, but the known _sha3 undefined behavior must be fixed. (cherry picked from commit 6d0d7d2b8c1e04fd51c6cb29cc09a41b60b97b7b) * bpo-46913: Skip test_ctypes.test_shorts() on UBSan (GH-31674) If Python is built with UBSan, test_ctypes now skips test_shorts(). This change allows to run test_ctypes to check for new UBSan regression, but the known test_shorts() undefined behavior must be fixed. (cherry picked from commit ad1b04451d3aca2c6fa6dbe2891676a4e0baac49) (cherry picked from commit 7b5b429adab4fe0fe81858fe3831f06adc2e2141) files: A Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst M Lib/ctypes/test/test_bitfields.py M Lib/test/test_hashlib.py M Modules/faulthandler.c diff --git a/Lib/ctypes/test/test_bitfields.py b/Lib/ctypes/test/test_bitfields.py index 992b8c4da3a77..66acd62e6851a 100644 --- a/Lib/ctypes/test/test_bitfields.py +++ b/Lib/ctypes/test/test_bitfields.py @@ -1,5 +1,6 @@ from ctypes import * from ctypes.test import need_symbol +from test import support import unittest import os @@ -39,6 +40,8 @@ def test_ints(self): setattr(b, name, i) self.assertEqual(getattr(b, name), func(byref(b), name.encode('ascii'))) + # bpo-46913: _ctypes/cfield.c h_get() has an undefined behavior + @support.skip_if_sanitizer(ub=True) def test_shorts(self): b = BITS() name = "M" diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py index 969e5e42e44c7..214bc3cb2b187 100644 --- a/Lib/test/test_hashlib.py +++ b/Lib/test/test_hashlib.py @@ -66,7 +66,9 @@ def get_fips_mode(): except ImportError: _sha3 = None -requires_sha3 = unittest.skipUnless(_sha3, 'requires _sha3') +# bpo-46913: Don't test the _sha3 extension on a Python UBSAN build +SKIP_SHA3 = support.check_sanitizer(ub=True) +requires_sha3 = unittest.skipUnless(not SKIP_SHA3 and _sha3, 'requires _sha3') def hexstr(s): @@ -129,6 +131,8 @@ def __init__(self, *args, **kwargs): self.constructors_to_test = {} for algorithm in algorithms: + if SKIP_SHA3 and algorithm.startswith('sha3_'): + continue self.constructors_to_test[algorithm] = set() # For each algorithm, test the direct constructor and the use @@ -181,14 +185,15 @@ def add_builtin_constructor(name): add_builtin_constructor('blake2s') add_builtin_constructor('blake2b') - _sha3 = self._conditional_import_module('_sha3') - if _sha3: - add_builtin_constructor('sha3_224') - add_builtin_constructor('sha3_256') - add_builtin_constructor('sha3_384') - add_builtin_constructor('sha3_512') - add_builtin_constructor('shake_128') - add_builtin_constructor('shake_256') + if not SKIP_SHA3: + _sha3 = self._conditional_import_module('_sha3') + if _sha3: + add_builtin_constructor('sha3_224') + add_builtin_constructor('sha3_256') + add_builtin_constructor('sha3_384') + add_builtin_constructor('sha3_512') + add_builtin_constructor('shake_128') + add_builtin_constructor('shake_256') super(HashLibTestCase, self).__init__(*args, **kwargs) diff --git a/Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst b/Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst new file mode 100644 index 0000000000000..65fed1c249d87 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst @@ -0,0 +1,3 @@ +Fix test_faulthandler.test_sigfpe() if Python is built with undefined +behavior sanitizer (UBSAN): disable UBSAN on the faulthandler_sigfpe() +function. Patch by Victor Stinner. diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index e7a285033051d..9855a3e0065ca 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -27,6 +27,23 @@ #define PUTS(fd, str) _Py_write_noraise(fd, str, strlen(str)) + +// clang uses __attribute__((no_sanitize("undefined"))) +// GCC 4.9+ uses __attribute__((no_sanitize_undefined)) +#if defined(__has_feature) // Clang +# if __has_feature(undefined_behavior_sanitizer) +# define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize("undefined"))) +# endif +#endif +#if defined(__GNUC__) \ + && ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) +# define _Py_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize_undefined)) +#endif +#ifndef _Py_NO_SANITIZE_UNDEFINED +# define _Py_NO_SANITIZE_UNDEFINED +#endif + + _Py_IDENTIFIER(enable); _Py_IDENTIFIER(fileno); _Py_IDENTIFIER(flush); @@ -1010,7 +1027,7 @@ faulthandler_suppress_crash_report(void) #endif } -static PyObject * +static PyObject* _Py_NO_SANITIZE_UNDEFINED faulthandler_read_null(PyObject *self, PyObject *args) { volatile int *x; @@ -1099,17 +1116,20 @@ faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args) Py_RETURN_NONE; } -static PyObject * +static PyObject* _Py_NO_SANITIZE_UNDEFINED faulthandler_sigfpe(PyObject *self, PyObject *args) { + faulthandler_suppress_crash_report(); + /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on PowerPC. Use volatile to disable compile-time optimizations. */ volatile int x = 1, y = 0, z; - faulthandler_suppress_crash_report(); z = x / y; + /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC), raise it manually. */ raise(SIGFPE); + /* This line is never reached, but we pretend to make something with z to silence a compiler warning. */ return PyLong_FromLong(z); From webhook-mailer at python.org Thu Mar 3 19:51:03 2022 From: webhook-mailer at python.org (zooba) Date: Fri, 04 Mar 2022 00:51:03 -0000 Subject: [Python-checkins] bpo-46744: Move Windows ARM64 installation directory to correct ProgramFiles (GH-31677) Message-ID: https://github.com/python/cpython/commit/8f31bf46980956c735dd18f9914f3e7144e87c77 commit: 8f31bf46980956c735dd18f9914f3e7144e87c77 branch: main author: Steve Dower committer: zooba date: 2022-03-04T00:50:42Z summary: bpo-46744: Move Windows ARM64 installation directory to correct ProgramFiles (GH-31677) files: A Misc/NEWS.d/next/Windows/2022-03-04-00-24-55.bpo-46744.tneWFr.rst M Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp M Tools/msi/bundle/bundle.wxs diff --git a/Misc/NEWS.d/next/Windows/2022-03-04-00-24-55.bpo-46744.tneWFr.rst b/Misc/NEWS.d/next/Windows/2022-03-04-00-24-55.bpo-46744.tneWFr.rst new file mode 100644 index 0000000000000..25f9e7a04b08d --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-03-04-00-24-55.bpo-46744.tneWFr.rst @@ -0,0 +1,3 @@ +The default all users install directory for ARM64 is now under the native +``Program Files`` folder, rather than ``Program Files (Arm)`` which is +intended for ARM (32-bit) files. diff --git a/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp b/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp index 226416f354585..fdc2a21d83d5f 100644 --- a/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp +++ b/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp @@ -1501,9 +1501,6 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { hr = UpdateUIStrings(_command.action); BalExitOnFailure(hr, "Failed to load UI strings."); - hr = FindProgramFilesArm(); - BalExitOnFailure(hr, "Fatal error locating Program Files (Arm)"); - GetBundleFileVersion(); // don't fail if we couldn't get the version info; best-effort only LExit: @@ -2184,37 +2181,6 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { return hr; } - HRESULT FindProgramFilesArm() { - wchar_t buffer[MAX_PATH + 1]; - DWORD bufferLen = MAX_PATH; - LSTATUS res = RegGetValueW( - HKEY_LOCAL_MACHINE, - L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion", - L"ProgramFilesDir (Arm)", - RRF_RT_REG_SZ | RRF_RT_REG_EXPAND_SZ | RRF_SUBKEY_WOW6464KEY, - NULL, - buffer, - &bufferLen - ); - if (res != ERROR_SUCCESS) { - // ProgramFilesArmFolder will default to ProgramFilesFolder. We only report - // an error if the value existed, as it will simply just be absent on non-ARM - // devices. - if (res != ERROR_FILE_NOT_FOUND) { - BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Failed to query 'ProgramFilesDir (Arm)': error code %d", res); - } - return S_OK; - } - if (buffer[0]) { - wchar_t *p = &buffer[bufferLen / sizeof(wchar_t) - 1]; - while (*p == L'\\' || *p == L'\0') { p -= 1; } - *++p = L'\\'; - *++p = L'\0'; - _engine->SetVariableString(L"ProgramFilesArmFolder", buffer); - } - return S_OK; - } - // // OnPlan - plan the detected changes. // diff --git a/Tools/msi/bundle/bundle.wxs b/Tools/msi/bundle/bundle.wxs index 340c72acf408b..0683f87cb0586 100644 --- a/Tools/msi/bundle/bundle.wxs +++ b/Tools/msi/bundle/bundle.wxs @@ -26,9 +26,6 @@ - - - @@ -40,7 +37,7 @@ - + From webhook-mailer at python.org Fri Mar 4 06:32:15 2022 From: webhook-mailer at python.org (markshannon) Date: Fri, 04 Mar 2022 11:32:15 -0000 Subject: [Python-checkins] bpo-46903: Handle str-subclasses in virtual instance dictionaries. (GH-31658) Message-ID: https://github.com/python/cpython/commit/03c2a36b2bd2d4469160d1607619ee144175d753 commit: 03c2a36b2bd2d4469160d1607619ee144175d753 branch: main author: Mark Shannon committer: markshannon date: 2022-03-04T11:31:29Z summary: bpo-46903: Handle str-subclasses in virtual instance dictionaries. (GH-31658) files: A Misc/NEWS.d/next/Core and Builtins/2022-03-03-12-02-41.bpo-46903.OzgaFZ.rst M Include/internal/pycore_code.h M Lib/test/test_unicode.py M Objects/dictobject.c M Python/specialize.c diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index 25c31a1fca7a6..2e03358dfcd47 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -398,6 +398,7 @@ typedef struct _object_stats { uint64_t dict_materialized_on_request; uint64_t dict_materialized_new_key; uint64_t dict_materialized_too_big; + uint64_t dict_materialized_str_subclass; } ObjectStats; typedef struct _stats { diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py index 8e4e64808b688..e97f971b77a63 100644 --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -3044,6 +3044,30 @@ def split(name): ]]) self.assertRaises(TypeError, _string.formatter_field_name_split, 1) + def test_str_subclass_attr(self): + + name = StrSubclass("name") + name2 = StrSubclass("name2") + class Bag: + pass + + o = Bag() + with self.assertRaises(AttributeError): + delattr(o, name) + setattr(o, name, 1) + self.assertEquals(o.name, 1) + o.name = 2 + self.assertEquals(list(o.__dict__), [name]) + + with self.assertRaises(AttributeError): + delattr(o, name2) + with self.assertRaises(AttributeError): + del o.name2 + setattr(o, name2, 3) + self.assertEquals(o.name2, 3) + o.name2 = 4 + self.assertEquals(list(o.__dict__), [name, name2]) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-03-12-02-41.bpo-46903.OzgaFZ.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-03-12-02-41.bpo-46903.OzgaFZ.rst new file mode 100644 index 0000000000000..f6120ef4b8d58 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-03-12-02-41.bpo-46903.OzgaFZ.rst @@ -0,0 +1,2 @@ +Make sure that str subclasses can be used as attribute names for instances +with virtual dictionaries. Fixes regression in 3.11alpha diff --git a/Objects/dictobject.c b/Objects/dictobject.c index d8bf164f98ee6..635a738985c01 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -5427,23 +5427,26 @@ int _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values, PyObject *name, PyObject *value) { - assert(PyUnicode_CheckExact(name)); PyDictKeysObject *keys = CACHED_KEYS(Py_TYPE(obj)); assert(keys != NULL); assert(values != NULL); assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - Py_ssize_t ix = insert_into_dictkeys(keys, name); + Py_ssize_t ix = DKIX_EMPTY; + if (PyUnicode_CheckExact(name)) { + ix = insert_into_dictkeys(keys, name); + } if (ix == DKIX_EMPTY) { - if (value == NULL) { - PyErr_SetObject(PyExc_AttributeError, name); - return -1; - } #ifdef Py_STATS - if (shared_keys_usable_size(keys) == SHARED_KEYS_MAX_SIZE) { - OBJECT_STAT_INC(dict_materialized_too_big); + if (PyUnicode_CheckExact(name)) { + if (shared_keys_usable_size(keys) == SHARED_KEYS_MAX_SIZE) { + OBJECT_STAT_INC(dict_materialized_too_big); + } + else { + OBJECT_STAT_INC(dict_materialized_new_key); + } } else { - OBJECT_STAT_INC(dict_materialized_new_key); + OBJECT_STAT_INC(dict_materialized_str_subclass); } #endif PyObject *dict = make_dict_from_instance_attributes(keys, values); @@ -5452,7 +5455,12 @@ _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values, } *_PyObject_ValuesPointer(obj) = NULL; *_PyObject_ManagedDictPointer(obj) = dict; - return PyDict_SetItem(dict, name, value); + if (value == NULL) { + return PyDict_DelItem(dict, name); + } + else { + return PyDict_SetItem(dict, name, value); + } } PyObject *old_value = values->values[ix]; Py_XINCREF(value); diff --git a/Python/specialize.c b/Python/specialize.c index 66dce8c93d77b..912b9e29198ee 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -221,6 +221,7 @@ print_object_stats(FILE *out, ObjectStats *stats) fprintf(out, "Object materialize dict (on request): %" PRIu64 "\n", stats->dict_materialized_on_request); fprintf(out, "Object materialize dict (new key): %" PRIu64 "\n", stats->dict_materialized_new_key); fprintf(out, "Object materialize dict (too big): %" PRIu64 "\n", stats->dict_materialized_too_big); + fprintf(out, "Object materialize dict (str subclass): %" PRIu64 "\n", stats->dict_materialized_str_subclass); } static void From webhook-mailer at python.org Fri Mar 4 07:41:46 2022 From: webhook-mailer at python.org (markshannon) Date: Fri, 04 Mar 2022 12:41:46 -0000 Subject: [Python-checkins] bpo-46841: Fix error message hacks in `GET_AWAITABLE` (GH-31664) Message-ID: https://github.com/python/cpython/commit/586b24d3be1aec5d2568b070a249b4d75e608782 commit: 586b24d3be1aec5d2568b070a249b4d75e608782 branch: main author: Brandt Bucher committer: markshannon date: 2022-03-04T12:41:17Z summary: bpo-46841: Fix error message hacks in `GET_AWAITABLE` (GH-31664) files: A Misc/NEWS.d/next/Core and Builtins/2022-03-03-12-36-15.bpo-46841.apPev2.rst M Doc/library/dis.rst M Include/opcode.h M Lib/importlib/_bootstrap_external.py M Lib/opcode.py M Python/ceval.c M Python/compile.c M Python/opcode_targets.h diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 3dac3911da276..65e888dc86a19 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -475,15 +475,24 @@ the original TOS1. **Coroutine opcodes** -.. opcode:: GET_AWAITABLE +.. opcode:: GET_AWAITABLE (where) Implements ``TOS = get_awaitable(TOS)``, where ``get_awaitable(o)`` returns ``o`` if ``o`` is a coroutine object or a generator object with the CO_ITERABLE_COROUTINE flag, or resolves ``o.__await__``. + If the ``where`` operand is nonzero, it indicates where the instruction + occurs: + + * ``1`` After a call to ``__aenter__`` + * ``2`` After a call to ``__aexit__`` + .. versionadded:: 3.5 + .. versionchanged:: 3.11 + Previously, this instruction did not have an oparg. + .. opcode:: GET_AITER diff --git a/Include/opcode.h b/Include/opcode.h index 110f8c3617140..1b9eeacdeab01 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -33,7 +33,6 @@ extern "C" { #define GET_YIELD_FROM_ITER 69 #define PRINT_EXPR 70 #define LOAD_BUILD_CLASS 71 -#define GET_AWAITABLE 73 #define LOAD_ASSERTION_ERROR 74 #define RETURN_GENERATOR 75 #define LIST_TO_TUPLE 82 @@ -86,6 +85,7 @@ extern "C" { #define POP_JUMP_IF_NOT_NONE 128 #define POP_JUMP_IF_NONE 129 #define RAISE_VARARGS 130 +#define GET_AWAITABLE 131 #define MAKE_FUNCTION 132 #define BUILD_SLICE 133 #define JUMP_NO_INTERRUPT 134 @@ -160,13 +160,13 @@ extern "C" { #define PRECALL_BUILTIN_FAST_WITH_KEYWORDS 66 #define PRECALL_NO_KW_LEN 67 #define PRECALL_NO_KW_ISINSTANCE 72 -#define PRECALL_NO_KW_LIST_APPEND 76 -#define PRECALL_NO_KW_METHOD_DESCRIPTOR_O 77 -#define PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS 78 -#define PRECALL_NO_KW_STR_1 79 -#define PRECALL_NO_KW_TUPLE_1 80 -#define PRECALL_NO_KW_TYPE_1 81 -#define PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST 131 +#define PRECALL_NO_KW_LIST_APPEND 73 +#define PRECALL_NO_KW_METHOD_DESCRIPTOR_O 76 +#define PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS 77 +#define PRECALL_NO_KW_STR_1 78 +#define PRECALL_NO_KW_TUPLE_1 79 +#define PRECALL_NO_KW_TYPE_1 80 +#define PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST 81 #define PRECALL_BOUND_METHOD 140 #define PRECALL_PYFUNC 141 #define RESUME_QUICK 143 diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 9d36bc27c44d4..529ca5a295178 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -392,6 +392,7 @@ def _write_atomic(path, data, mode=0o666): # Python 3.11a5 3483 (Use inline caching for COMPARE_OP and BINARY_SUBSCR) # Python 3.11a5 3484 (Use inline caching for LOAD_ATTR, LOAD_METHOD, and # STORE_ATTR) +# Python 3.11a5 3485 (Add an oparg to GET_AWAITABLE) # Python 3.12 will start with magic number 3500 @@ -406,7 +407,7 @@ def _write_atomic(path, data, mode=0o666): # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array # in PC/launcher.c must also be updated. -MAGIC_NUMBER = (3484).to_bytes(2, 'little') + b'\r\n' +MAGIC_NUMBER = (3485).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c _PYCACHE = '__pycache__' diff --git a/Lib/opcode.py b/Lib/opcode.py index f6e2dec32e0f5..3675780839671 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -92,7 +92,6 @@ def jabs_op(name, op, entries=0): def_op('PRINT_EXPR', 70) def_op('LOAD_BUILD_CLASS', 71) -def_op('GET_AWAITABLE', 73) def_op('LOAD_ASSERTION_ERROR', 74) def_op('RETURN_GENERATOR', 75) @@ -153,7 +152,7 @@ def jabs_op(name, op, entries=0): jabs_op('POP_JUMP_IF_NOT_NONE', 128) jabs_op('POP_JUMP_IF_NONE', 129) def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3) - +def_op('GET_AWAITABLE', 131) def_op('MAKE_FUNCTION', 132) # Flags def_op('BUILD_SLICE', 133) # Number of items jabs_op('JUMP_NO_INTERRUPT', 134) # Target byte offset from beginning of code diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-03-12-36-15.bpo-46841.apPev2.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-03-12-36-15.bpo-46841.apPev2.rst new file mode 100644 index 0000000000000..6a45e6e88241b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-03-12-36-15.bpo-46841.apPev2.rst @@ -0,0 +1,2 @@ +Use an oparg to simplify the construction of helpful error messages in +:opcode:`GET_AWAITABLE`. diff --git a/Python/ceval.c b/Python/ceval.c index 915ab9313a95a..67c8b46db2d63 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -95,7 +95,7 @@ static int check_args_iterable(PyThreadState *, PyObject *func, PyObject *vararg static int check_except_type_valid(PyThreadState *tstate, PyObject* right); static int check_except_star_type_valid(PyThreadState *tstate, PyObject* right); static void format_kwargs_error(PyThreadState *, PyObject *func, PyObject *kwargs); -static void format_awaitable_error(PyThreadState *, PyTypeObject *, int, int); +static void format_awaitable_error(PyThreadState *, PyTypeObject *, int); static int get_exception_handler(PyCodeObject *, int, int*, int*, int*); static _PyInterpreterFrame * _PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func, @@ -2505,13 +2505,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int PyObject *iter = _PyCoro_GetAwaitableIter(iterable); if (iter == NULL) { - int opcode_at_minus_4 = 0; - if ((next_instr - first_instr) > 4) { - opcode_at_minus_4 = _Py_OPCODE(next_instr[-4]); - } - format_awaitable_error(tstate, Py_TYPE(iterable), - opcode_at_minus_4, - _Py_OPCODE(next_instr[-2])); + format_awaitable_error(tstate, Py_TYPE(iterable), oparg); } Py_DECREF(iterable); @@ -7638,16 +7632,16 @@ format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg) } static void -format_awaitable_error(PyThreadState *tstate, PyTypeObject *type, int prevprevprevopcode, int prevopcode) +format_awaitable_error(PyThreadState *tstate, PyTypeObject *type, int oparg) { if (type->tp_as_async == NULL || type->tp_as_async->am_await == NULL) { - if (prevopcode == BEFORE_ASYNC_WITH) { + if (oparg == 1) { _PyErr_Format(tstate, PyExc_TypeError, "'async with' received an object from __aenter__ " "that does not implement __await__: %.100s", type->tp_name); } - else if (prevopcode == WITH_EXCEPT_START || (prevopcode == CALL && prevprevprevopcode == LOAD_CONST)) { + else if (oparg == 2) { _PyErr_Format(tstate, PyExc_TypeError, "'async with' received an object from __aexit__ " "that does not implement __await__: %.100s", diff --git a/Python/compile.c b/Python/compile.c index 14595d9b576f5..ac9ddbcd79d03 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1978,7 +1978,7 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, return 0; } if (info->fb_type == ASYNC_WITH) { - ADDOP(c, GET_AWAITABLE); + ADDOP_I(c, GET_AWAITABLE, 2); ADDOP_LOAD_CONST(c, Py_None); ADD_YIELD_FROM(c, 1); } @@ -5353,7 +5353,7 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type, ADDOP_I(c, CALL, 0); if (is_async_generator && type != COMP_GENEXP) { - ADDOP(c, GET_AWAITABLE); + ADDOP_I(c, GET_AWAITABLE, 0); ADDOP_LOAD_CONST(c, Py_None); ADD_YIELD_FROM(c, 1); } @@ -5485,7 +5485,7 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos) VISIT(c, expr, item->context_expr); ADDOP(c, BEFORE_ASYNC_WITH); - ADDOP(c, GET_AWAITABLE); + ADDOP_I(c, GET_AWAITABLE, 1); ADDOP_LOAD_CONST(c, Py_None); ADD_YIELD_FROM(c, 1); @@ -5522,7 +5522,7 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos) SET_LOC(c, s); if(!compiler_call_exit_with_nones(c)) return 0; - ADDOP(c, GET_AWAITABLE); + ADDOP_I(c, GET_AWAITABLE, 2); ADDOP_LOAD_CONST(c, Py_None); ADD_YIELD_FROM(c, 1); @@ -5536,7 +5536,7 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos) ADDOP_JUMP(c, SETUP_CLEANUP, cleanup); ADDOP(c, PUSH_EXC_INFO); ADDOP(c, WITH_EXCEPT_START); - ADDOP(c, GET_AWAITABLE); + ADDOP_I(c, GET_AWAITABLE, 2); ADDOP_LOAD_CONST(c, Py_None); ADD_YIELD_FROM(c, 1); compiler_with_except_finish(c, cleanup); @@ -5710,7 +5710,7 @@ compiler_visit_expr1(struct compiler *c, expr_ty e) } VISIT(c, expr, e->v.Await.value); - ADDOP(c, GET_AWAITABLE); + ADDOP_I(c, GET_AWAITABLE, 0); ADDOP_LOAD_CONST(c, Py_None); ADD_YIELD_FROM(c, 1); break; diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index 7be7b168a755d..2060793b4f1c8 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -72,15 +72,15 @@ static void *opcode_targets[256] = { &&TARGET_PRINT_EXPR, &&TARGET_LOAD_BUILD_CLASS, &&TARGET_PRECALL_NO_KW_ISINSTANCE, - &&TARGET_GET_AWAITABLE, + &&TARGET_PRECALL_NO_KW_LIST_APPEND, &&TARGET_LOAD_ASSERTION_ERROR, &&TARGET_RETURN_GENERATOR, - &&TARGET_PRECALL_NO_KW_LIST_APPEND, &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_O, &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS, &&TARGET_PRECALL_NO_KW_STR_1, &&TARGET_PRECALL_NO_KW_TUPLE_1, &&TARGET_PRECALL_NO_KW_TYPE_1, + &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST, &&TARGET_LIST_TO_TUPLE, &&TARGET_RETURN_VALUE, &&TARGET_IMPORT_STAR, @@ -130,7 +130,7 @@ static void *opcode_targets[256] = { &&TARGET_POP_JUMP_IF_NOT_NONE, &&TARGET_POP_JUMP_IF_NONE, &&TARGET_RAISE_VARARGS, - &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST, + &&TARGET_GET_AWAITABLE, &&TARGET_MAKE_FUNCTION, &&TARGET_BUILD_SLICE, &&TARGET_JUMP_NO_INTERRUPT, From webhook-mailer at python.org Fri Mar 4 11:39:27 2022 From: webhook-mailer at python.org (corona10) Date: Fri, 04 Mar 2022 16:39:27 -0000 Subject: [Python-checkins] bpo-46541: Remove usage of _Py_IDENTIFIER from lzma module (GH-31683) Message-ID: https://github.com/python/cpython/commit/d168c728f7114959e8fc147538ea1d24f2f5af79 commit: d168c728f7114959e8fc147538ea1d24f2f5af79 branch: main author: Dong-hee Na committer: corona10 date: 2022-03-05T01:38:56+09:00 summary: bpo-46541: Remove usage of _Py_IDENTIFIER from lzma module (GH-31683) files: M Modules/_lzmamodule.c diff --git a/Modules/_lzmamodule.c b/Modules/_lzmamodule.c index e3fc90e5175eb..b572d8cd909fd 100644 --- a/Modules/_lzmamodule.c +++ b/Modules/_lzmamodule.c @@ -6,7 +6,6 @@ */ #define PY_SSIZE_T_CLEAN -#define NEEDS_PY_IDENTIFIER #include "Python.h" #include "structmember.h" // PyMemberDef @@ -431,17 +430,19 @@ parse_filter_chain_spec(_lzma_state *state, lzma_filter filters[], PyObject *fil Python-level filter specifiers (represented as dicts). */ static int -spec_add_field(PyObject *spec, _Py_Identifier *key, unsigned long long value) +spec_add_field(PyObject *spec, const char *key, unsigned long long value) { - int status; - PyObject *value_object; - - value_object = PyLong_FromUnsignedLongLong(value); + PyObject *value_object = PyLong_FromUnsignedLongLong(value); if (value_object == NULL) { return -1; } - - status = _PyDict_SetItemId(spec, key, value_object); + PyObject *key_object = PyUnicode_InternFromString(key); + if (key_object == NULL) { + Py_DECREF(value_object); + return -1; + } + int status = PyDict_SetItem(spec, key_object, value_object); + Py_DECREF(key_object); Py_DECREF(value_object); return status; } @@ -458,8 +459,7 @@ build_filter_spec(const lzma_filter *f) #define ADD_FIELD(SOURCE, FIELD) \ do { \ - _Py_IDENTIFIER(FIELD); \ - if (spec_add_field(spec, &PyId_##FIELD, SOURCE->FIELD) == -1) \ + if (spec_add_field(spec, #FIELD, SOURCE->FIELD) == -1) \ goto error;\ } while (0) From webhook-mailer at python.org Fri Mar 4 12:36:05 2022 From: webhook-mailer at python.org (terryjreedy) Date: Fri, 04 Mar 2022 17:36:05 -0000 Subject: [Python-checkins] bpo-25415: Remove confusing sentence from IOBase docstrings (PR-31631) Message-ID: https://github.com/python/cpython/commit/cedd2473a9bebe07f3ced4f341cf58a2fef07b03 commit: cedd2473a9bebe07f3ced4f341cf58a2fef07b03 branch: main author: slateny <46876382+slateny at users.noreply.github.com> committer: terryjreedy date: 2022-03-04T12:35:52-05:00 summary: bpo-25415: Remove confusing sentence from IOBase docstrings (PR-31631) files: M Doc/library/io.rst M Lib/_pyio.py M Modules/_io/iobase.c M Modules/_io/textio.c diff --git a/Doc/library/io.rst b/Doc/library/io.rst index de88c572f3662..d5123348195bd 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -306,8 +306,7 @@ I/O Base Classes .. class:: IOBase - The abstract base class for all I/O classes, acting on streams of bytes. - There is no public constructor. + The abstract base class for all I/O classes. This class provides empty abstract implementations for many methods that derived classes can override selectively; the default @@ -461,8 +460,7 @@ I/O Base Classes .. class:: RawIOBase - Base class for raw binary streams. It inherits :class:`IOBase`. There is no - public constructor. + Base class for raw binary streams. It inherits :class:`IOBase`. Raw binary streams typically provide low-level access to an underlying OS device or API, and do not try to encapsulate it in high-level primitives @@ -515,7 +513,7 @@ I/O Base Classes .. class:: BufferedIOBase Base class for binary streams that support some kind of buffering. - It inherits :class:`IOBase`. There is no public constructor. + It inherits :class:`IOBase`. The main difference with :class:`RawIOBase` is that methods :meth:`read`, :meth:`readinto` and :meth:`write` will try (respectively) to read as much @@ -852,8 +850,7 @@ Text I/O .. class:: TextIOBase Base class for text streams. This class provides a character and line based - interface to stream I/O. It inherits :class:`IOBase`. There is no public - constructor. + interface to stream I/O. It inherits :class:`IOBase`. :class:`TextIOBase` provides or overrides these data attributes and methods in addition to those from :class:`IOBase`: diff --git a/Lib/_pyio.py b/Lib/_pyio.py index 8f20c5ed2abd5..fd00d6536c076 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -326,8 +326,7 @@ class UnsupportedOperation(OSError, ValueError): class IOBase(metaclass=abc.ABCMeta): - """The abstract base class for all I/O classes, acting on streams of - bytes. There is no public constructor. + """The abstract base class for all I/O classes. This class provides dummy implementations for many methods that derived classes can override selectively; the default implementations @@ -1833,7 +1832,7 @@ class TextIOBase(IOBase): """Base class for text I/O. This class provides a character and line based interface to stream - I/O. There is no public constructor. + I/O. """ def read(self, size=-1): diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index b00b6b983ee0b..6ae43a8b3bd62 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -34,8 +34,7 @@ typedef struct { } iobase; PyDoc_STRVAR(iobase_doc, - "The abstract base class for all I/O classes, acting on streams of\n" - "bytes. There is no public constructor.\n" + "The abstract base class for all I/O classes.\n" "\n" "This class provides dummy implementations for many methods that\n" "derived classes can override selectively; the default implementations\n" diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index ca59a4ef27135..d9d1c88141874 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -30,7 +30,7 @@ PyDoc_STRVAR(textiobase_doc, "\n" "This class provides a character and line based interface to stream\n" "I/O. There is no readinto method because Python's character strings\n" - "are immutable. There is no public constructor.\n" + "are immutable.\n" ); static PyObject * From webhook-mailer at python.org Fri Mar 4 13:34:19 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 04 Mar 2022 18:34:19 -0000 Subject: [Python-checkins] bpo-25415: Remove confusing sentence from IOBase docstrings (PR-31631) Message-ID: https://github.com/python/cpython/commit/bdce1880365990403efdbeb60c4928c996370b0c commit: bdce1880365990403efdbeb60c4928c996370b0c branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-04T10:33:57-08:00 summary: bpo-25415: Remove confusing sentence from IOBase docstrings (PR-31631) (cherry picked from commit cedd2473a9bebe07f3ced4f341cf58a2fef07b03) Co-authored-by: slateny <46876382+slateny at users.noreply.github.com> files: M Doc/library/io.rst M Lib/_pyio.py M Modules/_io/iobase.c M Modules/_io/textio.c diff --git a/Doc/library/io.rst b/Doc/library/io.rst index de88c572f3662..d5123348195bd 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -306,8 +306,7 @@ I/O Base Classes .. class:: IOBase - The abstract base class for all I/O classes, acting on streams of bytes. - There is no public constructor. + The abstract base class for all I/O classes. This class provides empty abstract implementations for many methods that derived classes can override selectively; the default @@ -461,8 +460,7 @@ I/O Base Classes .. class:: RawIOBase - Base class for raw binary streams. It inherits :class:`IOBase`. There is no - public constructor. + Base class for raw binary streams. It inherits :class:`IOBase`. Raw binary streams typically provide low-level access to an underlying OS device or API, and do not try to encapsulate it in high-level primitives @@ -515,7 +513,7 @@ I/O Base Classes .. class:: BufferedIOBase Base class for binary streams that support some kind of buffering. - It inherits :class:`IOBase`. There is no public constructor. + It inherits :class:`IOBase`. The main difference with :class:`RawIOBase` is that methods :meth:`read`, :meth:`readinto` and :meth:`write` will try (respectively) to read as much @@ -852,8 +850,7 @@ Text I/O .. class:: TextIOBase Base class for text streams. This class provides a character and line based - interface to stream I/O. It inherits :class:`IOBase`. There is no public - constructor. + interface to stream I/O. It inherits :class:`IOBase`. :class:`TextIOBase` provides or overrides these data attributes and methods in addition to those from :class:`IOBase`: diff --git a/Lib/_pyio.py b/Lib/_pyio.py index 56e9a0cb33c5f..fb867fbc70f81 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -338,8 +338,7 @@ class UnsupportedOperation(OSError, ValueError): class IOBase(metaclass=abc.ABCMeta): - """The abstract base class for all I/O classes, acting on streams of - bytes. There is no public constructor. + """The abstract base class for all I/O classes. This class provides dummy implementations for many methods that derived classes can override selectively; the default implementations @@ -1845,7 +1844,7 @@ class TextIOBase(IOBase): """Base class for text I/O. This class provides a character and line based interface to stream - I/O. There is no public constructor. + I/O. """ def read(self, size=-1): diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index 5b687b78176e8..4c81befebd7a5 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -34,8 +34,7 @@ typedef struct { } iobase; PyDoc_STRVAR(iobase_doc, - "The abstract base class for all I/O classes, acting on streams of\n" - "bytes. There is no public constructor.\n" + "The abstract base class for all I/O classes.\n" "\n" "This class provides dummy implementations for many methods that\n" "derived classes can override selectively; the default implementations\n" diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index eb05ae1a16eb0..e28dbaa7b7e45 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -50,7 +50,7 @@ PyDoc_STRVAR(textiobase_doc, "\n" "This class provides a character and line based interface to stream\n" "I/O. There is no readinto method because Python's character strings\n" - "are immutable. There is no public constructor.\n" + "are immutable.\n" ); static PyObject * From webhook-mailer at python.org Fri Mar 4 13:34:19 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 04 Mar 2022 18:34:19 -0000 Subject: [Python-checkins] bpo-25415: Remove confusing sentence from IOBase docstrings (PR-31631) Message-ID: https://github.com/python/cpython/commit/01df048831eb631dfee41175f08d09b9ad1a9538 commit: 01df048831eb631dfee41175f08d09b9ad1a9538 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-04T10:34:14-08:00 summary: bpo-25415: Remove confusing sentence from IOBase docstrings (PR-31631) (cherry picked from commit cedd2473a9bebe07f3ced4f341cf58a2fef07b03) Co-authored-by: slateny <46876382+slateny at users.noreply.github.com> files: M Doc/library/io.rst M Lib/_pyio.py M Modules/_io/iobase.c M Modules/_io/textio.c diff --git a/Doc/library/io.rst b/Doc/library/io.rst index 0ff05cfc0e091..9f62dd21afbea 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -230,8 +230,7 @@ I/O Base Classes .. class:: IOBase - The abstract base class for all I/O classes, acting on streams of bytes. - There is no public constructor. + The abstract base class for all I/O classes. This class provides empty abstract implementations for many methods that derived classes can override selectively; the default @@ -385,8 +384,7 @@ I/O Base Classes .. class:: RawIOBase - Base class for raw binary streams. It inherits :class:`IOBase`. There is no - public constructor. + Base class for raw binary streams. It inherits :class:`IOBase`. Raw binary streams typically provide low-level access to an underlying OS device or API, and do not try to encapsulate it in high-level primitives @@ -439,7 +437,7 @@ I/O Base Classes .. class:: BufferedIOBase Base class for binary streams that support some kind of buffering. - It inherits :class:`IOBase`. There is no public constructor. + It inherits :class:`IOBase`. The main difference with :class:`RawIOBase` is that methods :meth:`read`, :meth:`readinto` and :meth:`write` will try (respectively) to read as much @@ -776,8 +774,7 @@ Text I/O .. class:: TextIOBase Base class for text streams. This class provides a character and line based - interface to stream I/O. It inherits :class:`IOBase`. There is no public - constructor. + interface to stream I/O. It inherits :class:`IOBase`. :class:`TextIOBase` provides or overrides these data attributes and methods in addition to those from :class:`IOBase`: diff --git a/Lib/_pyio.py b/Lib/_pyio.py index 4804ed27cd14d..7a9a2779fcee7 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -314,8 +314,7 @@ class UnsupportedOperation(OSError, ValueError): class IOBase(metaclass=abc.ABCMeta): - """The abstract base class for all I/O classes, acting on streams of - bytes. There is no public constructor. + """The abstract base class for all I/O classes. This class provides dummy implementations for many methods that derived classes can override selectively; the default implementations @@ -1821,7 +1820,7 @@ class TextIOBase(IOBase): """Base class for text I/O. This class provides a character and line based interface to stream - I/O. There is no public constructor. + I/O. """ def read(self, size=-1): diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index a8e55c34799bd..0f150a3583d5e 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -33,8 +33,7 @@ typedef struct { } iobase; PyDoc_STRVAR(iobase_doc, - "The abstract base class for all I/O classes, acting on streams of\n" - "bytes. There is no public constructor.\n" + "The abstract base class for all I/O classes.\n" "\n" "This class provides dummy implementations for many methods that\n" "derived classes can override selectively; the default implementations\n" diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index 966c532a0e3c3..f9903e2500006 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -49,7 +49,7 @@ PyDoc_STRVAR(textiobase_doc, "\n" "This class provides a character and line based interface to stream\n" "I/O. There is no readinto method because Python's character strings\n" - "are immutable. There is no public constructor.\n" + "are immutable.\n" ); static PyObject * From webhook-mailer at python.org Fri Mar 4 13:51:44 2022 From: webhook-mailer at python.org (brandtbucher) Date: Fri, 04 Mar 2022 18:51:44 -0000 Subject: [Python-checkins] bpo-46841: Fix BINARY_OP's handling of inline caches (GH-31671) Message-ID: https://github.com/python/cpython/commit/c4d2d57eefb1224a12e2e95e4508658dfbf6a7c9 commit: c4d2d57eefb1224a12e2e95e4508658dfbf6a7c9 branch: main author: Brandt Bucher committer: brandtbucher date: 2022-03-04T10:51:27-08:00 summary: bpo-46841: Fix BINARY_OP's handling of inline caches (GH-31671) files: A Misc/NEWS.d/next/Core and Builtins/2022-03-03-14-31-53.bpo-46841.agf-3X.rst M Python/ceval.c M Python/specialize.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-03-14-31-53.bpo-46841.agf-3X.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-03-14-31-53.bpo-46841.agf-3X.rst new file mode 100644 index 0000000000000..690293e97dcc3 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-03-14-31-53.bpo-46841.agf-3X.rst @@ -0,0 +1,2 @@ +Fix incorrect handling of inline cache entries when specializing +:opcode:`BINARY_OP`. diff --git a/Python/ceval.c b/Python/ceval.c index 67c8b46db2d63..0743894c457a7 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2028,8 +2028,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); DEOPT_IF(Py_REFCNT(left) != 2, BINARY_OP); - int next_oparg = _Py_OPARG(*next_instr); - assert(_Py_OPCODE(*next_instr) == STORE_FAST); + _Py_CODEUNIT true_next = next_instr[INLINE_CACHE_ENTRIES_BINARY_OP]; + int next_oparg = _Py_OPARG(true_next); + assert(_Py_OPCODE(true_next) == STORE_FAST); /* In the common case, there are 2 references to the value * stored in 'variable' when the v = v + ... is performed: one * on the value stack (in 'v') and one still stored in the diff --git a/Python/specialize.c b/Python/specialize.c index 912b9e29198ee..6328f11f90407 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -1951,7 +1951,8 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, break; } if (PyUnicode_CheckExact(lhs)) { - if (_Py_OPCODE(instr[1]) == STORE_FAST && Py_REFCNT(lhs) == 2) { + _Py_CODEUNIT next = instr[INLINE_CACHE_ENTRIES_BINARY_OP + 1]; + if (_Py_OPCODE(next) == STORE_FAST && Py_REFCNT(lhs) == 2) { *instr = _Py_MAKECODEUNIT(BINARY_OP_INPLACE_ADD_UNICODE, oparg); goto success; From webhook-mailer at python.org Fri Mar 4 15:13:25 2022 From: webhook-mailer at python.org (gpshead) Date: Fri, 04 Mar 2022 20:13:25 -0000 Subject: [Python-checkins] bpo-38738: Fix formatting of True and False in the threading documentation (GH-31678) Message-ID: https://github.com/python/cpython/commit/46a116c1c9f6b60a3d35ab9a419f8eee5de2542e commit: 46a116c1c9f6b60a3d35ab9a419f8eee5de2542e branch: main author: G?ry Ogam committer: gpshead date: 2022-03-04T12:13:09-08:00 summary: bpo-38738: Fix formatting of True and False in the threading documentation (GH-31678) * Fix formatting of True and False in the threading documentation * Update threading.rst files: M Doc/library/threading.rst diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 2bcb72b6d4e50..b777560961690 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -441,8 +441,8 @@ since it is impossible to detect the termination of alien threads. .. attribute:: daemon - A boolean value indicating whether this thread is a daemon thread (True) - or not (False). This must be set before :meth:`~Thread.start` is called, + A boolean value indicating whether this thread is a daemon thread (``True``) + or not (``False``). This must be set before :meth:`~Thread.start` is called, otherwise :exc:`RuntimeError` is raised. Its initial value is inherited from the creating thread; the main thread is not a daemon thread and therefore all threads created in the main thread default to @@ -516,7 +516,7 @@ All methods are executed atomically. value, block for at most the number of seconds specified by *timeout* and as long as the lock cannot be acquired. A *timeout* argument of ``-1`` specifies an unbounded wait. It is forbidden to specify a *timeout* - when *blocking* is false. + when *blocking* is ``False``. The return value is ``True`` if the lock is acquired successfully, ``False`` if not (for example if the *timeout* expired). @@ -544,7 +544,7 @@ All methods are executed atomically. .. method:: locked() - Return true if the lock is acquired. + Return ``True`` if the lock is acquired. @@ -593,17 +593,17 @@ Reentrant locks also support the :ref:`context management protocol ` is unlocked, only one at a time will be able to grab ownership of the lock. There is no return value in this case. - When invoked with the *blocking* argument set to true, do the same thing as when + When invoked with the *blocking* argument set to ``True``, do the same thing as when called without arguments, and return ``True``. - When invoked with the *blocking* argument set to false, do not block. If a call + When invoked with the *blocking* argument set to ``False``, do not block. If a call without an argument would block, return ``False`` immediately; otherwise, do the same thing as when called without arguments, and return ``True``. When invoked with the floating-point *timeout* argument set to a positive value, block for at most the number of seconds specified by *timeout* and as long as the lock cannot be acquired. Return ``True`` if the lock has - been acquired, false if the timeout has elapsed. + been acquired, ``False`` if the timeout has elapsed. .. versionchanged:: 3.2 The *timeout* parameter is new. @@ -844,7 +844,7 @@ Semaphores also support the :ref:`context management protocol `. thread will be awoken by each call to :meth:`~Semaphore.release`. The order in which threads are awoken should not be relied on. - When invoked with *blocking* set to false, do not block. If a call + When invoked with *blocking* set to ``False``, do not block. If a call without an argument would block, return ``False`` immediately; otherwise, do the same thing as when called without arguments, and return ``True``. From webhook-mailer at python.org Fri Mar 4 15:38:08 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 04 Mar 2022 20:38:08 -0000 Subject: [Python-checkins] bpo-38738: Fix formatting of True and False in the threading documentation (GH-31678) Message-ID: https://github.com/python/cpython/commit/fa69ec89393549a18944b3b92943709dac56a36a commit: fa69ec89393549a18944b3b92943709dac56a36a branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-04T12:37:56-08:00 summary: bpo-38738: Fix formatting of True and False in the threading documentation (GH-31678) * Fix formatting of True and False in the threading documentation * Update threading.rst (cherry picked from commit 46a116c1c9f6b60a3d35ab9a419f8eee5de2542e) Co-authored-by: G?ry Ogam files: M Doc/library/threading.rst diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 8c7664328a49d..14434fbd52d08 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -428,8 +428,8 @@ since it is impossible to detect the termination of alien threads. .. attribute:: daemon - A boolean value indicating whether this thread is a daemon thread (True) - or not (False). This must be set before :meth:`~Thread.start` is called, + A boolean value indicating whether this thread is a daemon thread (``True``) + or not (``False``). This must be set before :meth:`~Thread.start` is called, otherwise :exc:`RuntimeError` is raised. Its initial value is inherited from the creating thread; the main thread is not a daemon thread and therefore all threads created in the main thread default to @@ -503,7 +503,7 @@ All methods are executed atomically. value, block for at most the number of seconds specified by *timeout* and as long as the lock cannot be acquired. A *timeout* argument of ``-1`` specifies an unbounded wait. It is forbidden to specify a *timeout* - when *blocking* is false. + when *blocking* is ``False``. The return value is ``True`` if the lock is acquired successfully, ``False`` if not (for example if the *timeout* expired). @@ -531,7 +531,7 @@ All methods are executed atomically. .. method:: locked() - Return true if the lock is acquired. + Return ``True`` if the lock is acquired. @@ -580,17 +580,17 @@ Reentrant locks also support the :ref:`context management protocol ` is unlocked, only one at a time will be able to grab ownership of the lock. There is no return value in this case. - When invoked with the *blocking* argument set to true, do the same thing as when + When invoked with the *blocking* argument set to ``True``, do the same thing as when called without arguments, and return ``True``. - When invoked with the *blocking* argument set to false, do not block. If a call + When invoked with the *blocking* argument set to ``False``, do not block. If a call without an argument would block, return ``False`` immediately; otherwise, do the same thing as when called without arguments, and return ``True``. When invoked with the floating-point *timeout* argument set to a positive value, block for at most the number of seconds specified by *timeout* and as long as the lock cannot be acquired. Return ``True`` if the lock has - been acquired, false if the timeout has elapsed. + been acquired, ``False`` if the timeout has elapsed. .. versionchanged:: 3.2 The *timeout* parameter is new. @@ -831,7 +831,7 @@ Semaphores also support the :ref:`context management protocol `. thread will be awoken by each call to :meth:`~Semaphore.release`. The order in which threads are awoken should not be relied on. - When invoked with *blocking* set to false, do not block. If a call + When invoked with *blocking* set to ``False``, do not block. If a call without an argument would block, return ``False`` immediately; otherwise, do the same thing as when called without arguments, and return ``True``. From webhook-mailer at python.org Fri Mar 4 21:52:02 2022 From: webhook-mailer at python.org (Fidget-Spinner) Date: Sat, 05 Mar 2022 02:52:02 -0000 Subject: [Python-checkins] Lib/typing.py copy edits originating from GH-31061 (#31684) Message-ID: https://github.com/python/cpython/commit/2031149b9a7dfab5f5bad63f417e19f4fc2b9661 commit: 2031149b9a7dfab5f5bad63f417e19f4fc2b9661 branch: main author: Matt Bogosian committer: Fidget-Spinner <28750310+Fidget-Spinner at users.noreply.github.com> date: 2022-03-05T10:51:55+08:00 summary: Lib/typing.py copy edits originating from GH-31061 (#31684) files: M Lib/typing.py diff --git a/Lib/typing.py b/Lib/typing.py index 6e0c68c842420..27d83c5105fa4 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -330,8 +330,8 @@ def inner(*args, **kwds): def _eval_type(t, globalns, localns, recursive_guard=frozenset()): """Evaluate all forward references in the given type t. For use of globalns and localns see the docstring for get_type_hints(). - recursive_guard is used to prevent prevent infinite recursion - with recursive ForwardRef. + recursive_guard is used to prevent infinite recursion with a recursive + ForwardRef. """ if isinstance(t, ForwardRef): return t._evaluate(globalns, localns, recursive_guard) @@ -1036,7 +1036,7 @@ def __getattr__(self, attr): return self._name or self.__origin__.__name__ # We are careful for copy and pickle. - # Also for simplicity we just don't relay all dunder names + # Also for simplicity we don't relay any dunder names if '__origin__' in self.__dict__ and not _is_dunder(attr): return getattr(self.__origin__, attr) raise AttributeError(attr) From webhook-mailer at python.org Fri Mar 4 22:17:37 2022 From: webhook-mailer at python.org (miss-islington) Date: Sat, 05 Mar 2022 03:17:37 -0000 Subject: [Python-checkins] Lib/typing.py copy edits originating from GH-31061 (GH-31684) Message-ID: https://github.com/python/cpython/commit/4716f70c8543d12d18c64677af650d479b99edac commit: 4716f70c8543d12d18c64677af650d479b99edac branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-04T19:17:32-08:00 summary: Lib/typing.py copy edits originating from GH-31061 (GH-31684) (cherry picked from commit 2031149b9a7dfab5f5bad63f417e19f4fc2b9661) Co-authored-by: Matt Bogosian files: M Lib/typing.py diff --git a/Lib/typing.py b/Lib/typing.py index 4519cdbc951c9..da393eefc53a4 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -320,8 +320,8 @@ def inner(*args, **kwds): def _eval_type(t, globalns, localns, recursive_guard=frozenset()): """Evaluate all forward references in the given type t. For use of globalns and localns see the docstring for get_type_hints(). - recursive_guard is used to prevent prevent infinite recursion - with recursive ForwardRef. + recursive_guard is used to prevent infinite recursion with a recursive + ForwardRef. """ if isinstance(t, ForwardRef): return t._evaluate(globalns, localns, recursive_guard) @@ -976,7 +976,7 @@ def __getattr__(self, attr): return self._name or self.__origin__.__name__ # We are careful for copy and pickle. - # Also for simplicity we just don't relay all dunder names + # Also for simplicity we don't relay any dunder names if '__origin__' in self.__dict__ and not _is_dunder(attr): return getattr(self.__origin__, attr) raise AttributeError(attr) From webhook-mailer at python.org Fri Mar 4 22:22:00 2022 From: webhook-mailer at python.org (miss-islington) Date: Sat, 05 Mar 2022 03:22:00 -0000 Subject: [Python-checkins] Lib/typing.py copy edits originating from GH-31061 (GH-31684) Message-ID: https://github.com/python/cpython/commit/7fba55f15a01742c79214e1abf3e16015eecade8 commit: 7fba55f15a01742c79214e1abf3e16015eecade8 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-04T19:21:51-08:00 summary: Lib/typing.py copy edits originating from GH-31061 (GH-31684) (cherry picked from commit 2031149b9a7dfab5f5bad63f417e19f4fc2b9661) Co-authored-by: Matt Bogosian files: M Lib/typing.py diff --git a/Lib/typing.py b/Lib/typing.py index af2d8c758a454..d35a2a5b0185b 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -285,8 +285,8 @@ def inner(*args, **kwds): def _eval_type(t, globalns, localns, recursive_guard=frozenset()): """Evaluate all forward references in the given type t. For use of globalns and localns see the docstring for get_type_hints(). - recursive_guard is used to prevent prevent infinite recursion - with recursive ForwardRef. + recursive_guard is used to prevent infinite recursion with a recursive + ForwardRef. """ if isinstance(t, ForwardRef): return t._evaluate(globalns, localns, recursive_guard) @@ -705,7 +705,7 @@ def __mro_entries__(self, bases): def __getattr__(self, attr): # We are careful for copy and pickle. - # Also for simplicity we just don't relay all dunder names + # Also for simplicity we don't relay any dunder names if '__origin__' in self.__dict__ and not _is_dunder(attr): return getattr(self.__origin__, attr) raise AttributeError(attr) From webhook-mailer at python.org Sat Mar 5 08:59:51 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Sat, 05 Mar 2022 13:59:51 -0000 Subject: [Python-checkins] bpo-46927: Include the type's name in the error message for subscripting non-generic types (GH-31694) Message-ID: https://github.com/python/cpython/commit/ab9301a28fa431d7a32163126fc96de3b2ce6107 commit: ab9301a28fa431d7a32163126fc96de3b2ce6107 branch: main author: Serhiy Storchaka committer: serhiy-storchaka date: 2022-03-05T15:59:24+02:00 summary: bpo-46927: Include the type's name in the error message for subscripting non-generic types (GH-31694) files: A Misc/NEWS.d/next/Core and Builtins/2022-03-05-12-23-58.bpo-46927.URbHBi.rst M Lib/test/test_exception_group.py M Lib/test/test_genericalias.py M Objects/abstract.c diff --git a/Lib/test/test_exception_group.py b/Lib/test/test_exception_group.py index 8a55c826b8328..793e8d20de7e3 100644 --- a/Lib/test/test_exception_group.py +++ b/Lib/test/test_exception_group.py @@ -11,7 +11,7 @@ def test_exception_group_types(self): self.assertTrue(issubclass(BaseExceptionGroup, BaseException)) def test_exception_is_not_generic_type(self): - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, 'Exception'): Exception[OSError] def test_exception_group_is_generic_type(self): diff --git a/Lib/test/test_genericalias.py b/Lib/test/test_genericalias.py index d311281c578a2..1407657c9bb20 100644 --- a/Lib/test/test_genericalias.py +++ b/Lib/test/test_genericalias.py @@ -109,7 +109,7 @@ def test_unsubscriptable(self): for t in int, str, float, Sized, Hashable: tname = t.__name__ with self.subTest(f"Testing {tname}"): - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, tname): t[int] def test_instantiate(self): @@ -275,7 +275,7 @@ def test_type_generic(self): def test_type_subclass_generic(self): class MyType(type): pass - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, 'MyType'): MyType[int] def test_pickle(self): diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-05-12-23-58.bpo-46927.URbHBi.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-05-12-23-58.bpo-46927.URbHBi.rst new file mode 100644 index 0000000000000..cd59fb89c3654 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-05-12-23-58.bpo-46927.URbHBi.rst @@ -0,0 +1,2 @@ +Include the type's name in the error message for subscripting non-generic +types. diff --git a/Objects/abstract.c b/Objects/abstract.c index 6ad66a88b4619..79f5a5f760f8e 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -190,6 +190,9 @@ PyObject_GetItem(PyObject *o, PyObject *key) Py_DECREF(meth); return result; } + PyErr_Format(PyExc_TypeError, "type '%.200s' is not subscriptable", + ((PyTypeObject *)o)->tp_name); + return NULL; } return type_error("'%.200s' object is not subscriptable", o); From webhook-mailer at python.org Sat Mar 5 10:47:14 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Sat, 05 Mar 2022 15:47:14 -0000 Subject: [Python-checkins] Remove trailing spaces (GH-31695) Message-ID: https://github.com/python/cpython/commit/6927632492cbad86a250aa006c1847e03b03e70b commit: 6927632492cbad86a250aa006c1847e03b03e70b branch: main author: Serhiy Storchaka committer: serhiy-storchaka date: 2022-03-05T17:47:00+02:00 summary: Remove trailing spaces (GH-31695) files: M Lib/asyncio/sslproto.py M Lib/asyncio/transports.py M Lib/codeop.py M Lib/concurrent/futures/_base.py M Lib/importlib/_bootstrap_external.py M Lib/test/test_asyncio/test_sendfile.py M Lib/test/test_syntax.py M Lib/test/test_tokenize.py M Lib/test/test_typing.py M Modules/_blake2/blake2s_impl.c M Python/fileutils.c M Python/specialize.c M Tools/scripts/freeze_modules.py diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py index de7c3332e4dca..de00953cc1d0f 100644 --- a/Lib/asyncio/sslproto.py +++ b/Lib/asyncio/sslproto.py @@ -197,8 +197,8 @@ def get_read_buffer_size(self): return self._ssl_protocol._get_read_buffer_size() def get_write_buffer_limits(self): - """Get the high and low watermarks for write flow control. - Return a tuple (low, high) where low and high are + """Get the high and low watermarks for write flow control. + Return a tuple (low, high) where low and high are positive number of bytes.""" return self._ssl_protocol._transport.get_write_buffer_limits() diff --git a/Lib/asyncio/transports.py b/Lib/asyncio/transports.py index 73b1fa2de416c..30fd41d49af71 100644 --- a/Lib/asyncio/transports.py +++ b/Lib/asyncio/transports.py @@ -100,8 +100,8 @@ def get_write_buffer_size(self): raise NotImplementedError def get_write_buffer_limits(self): - """Get the high and low watermarks for write flow control. - Return a tuple (low, high) where low and high are + """Get the high and low watermarks for write flow control. + Return a tuple (low, high) where low and high are positive number of bytes.""" raise NotImplementedError diff --git a/Lib/codeop.py b/Lib/codeop.py index 568e9bbc11805..45a378baba433 100644 --- a/Lib/codeop.py +++ b/Lib/codeop.py @@ -43,7 +43,7 @@ # The following flags match the values from Include/cpython/compile.h # Caveat emptor: These flags are undocumented on purpose and depending # on their effect outside the standard library is **unsupported**. -PyCF_DONT_IMPLY_DEDENT = 0x200 +PyCF_DONT_IMPLY_DEDENT = 0x200 PyCF_ALLOW_INCOMPLETE_INPUT = 0x4000 def _maybe_compile(compiler, source, filename, symbol): diff --git a/Lib/concurrent/futures/_base.py b/Lib/concurrent/futures/_base.py index c5912c24a1c20..706a4f2c09d1f 100644 --- a/Lib/concurrent/futures/_base.py +++ b/Lib/concurrent/futures/_base.py @@ -282,7 +282,7 @@ def wait(fs, timeout=None, return_when=ALL_COMPLETED): A named 2-tuple of sets. The first set, named 'done', contains the futures that completed (is finished or cancelled) before the wait completed. The second set, named 'not_done', contains uncompleted - futures. Duplicate futures given to *fs* are removed and will be + futures. Duplicate futures given to *fs* are removed and will be returned only once. """ fs = set(fs) diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 529ca5a295178..741247dd25d63 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -390,7 +390,7 @@ def _write_atomic(path, data, mode=0o666): # Python 3.11a5 3481 (Use inline cache for BINARY_OP) # Python 3.11a5 3482 (Use inline caching for UNPACK_SEQUENCE and LOAD_GLOBAL) # Python 3.11a5 3483 (Use inline caching for COMPARE_OP and BINARY_SUBSCR) -# Python 3.11a5 3484 (Use inline caching for LOAD_ATTR, LOAD_METHOD, and +# Python 3.11a5 3484 (Use inline caching for LOAD_ATTR, LOAD_METHOD, and # STORE_ATTR) # Python 3.11a5 3485 (Add an oparg to GET_AWAITABLE) diff --git a/Lib/test/test_asyncio/test_sendfile.py b/Lib/test/test_asyncio/test_sendfile.py index effca6644c062..a10504b1c4130 100644 --- a/Lib/test/test_asyncio/test_sendfile.py +++ b/Lib/test/test_asyncio/test_sendfile.py @@ -93,8 +93,8 @@ async def wait_closed(self): class SendfileBase: # 256 KiB plus small unaligned to buffer chunk - # Newer versions of Windows seems to have increased its internal - # buffer and tries to send as much of the data as it can as it + # Newer versions of Windows seems to have increased its internal + # buffer and tries to send as much of the data as it can as it # has some form of buffering for this which is less than 256KiB # on newer server versions and Windows 11. # So DATA should be larger than 256 KiB to make this test reliable. diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 8ddfe91a6e127..5134dcbe6521c 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -1630,8 +1630,8 @@ def fib(n): self.assertEqual(compile(s1, '', 'exec'), compile(s2, '', 'exec')) except SyntaxError: self.fail("Indented statement over multiple lines is valid") - - def test_continuation_bad_indentation(self): + + def test_continuation_bad_indentation(self): # Check that code that breaks indentation across multiple lines raises a syntax error code = r"""\ diff --git a/Lib/test/test_tokenize.py b/Lib/test/test_tokenize.py index 334390abaa2de..1272e1e9be002 100644 --- a/Lib/test/test_tokenize.py +++ b/Lib/test/test_tokenize.py @@ -2511,8 +2511,8 @@ def get_tokens(string): self.assertRaises(SyntaxError, get_tokens, "("*1000+"a"+")"*1000) self.assertRaises(SyntaxError, get_tokens, "]") - - def test_continuation_lines_indentation(self): + + def test_continuation_lines_indentation(self): def get_tokens(string): return [(kind, string) for (kind, string, *_) in _generate_tokens_from_c_tokenizer(string)] @@ -2551,7 +2551,7 @@ def fib(n): '''Print a Fibonacci series up to n.''' a, b = 0, 1 """) - + self.assertEqual(get_tokens(code), get_tokens(code_no_cont)) code = dedent(""" @@ -2572,7 +2572,7 @@ def fib(n): pass pass """) - + self.assertEqual(get_tokens(code), get_tokens(code_no_cont)) code = dedent(""" @@ -2609,7 +2609,7 @@ def fib(n): """) self.assertEqual(get_tokens(code), get_tokens(code_no_cont)) - + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index bd9920436223c..86baed98fcab1 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -2930,8 +2930,8 @@ def fun(x: a): def test_forward_repr(self): self.assertEqual(repr(List['int']), "typing.List[ForwardRef('int')]") - self.assertEqual(repr(List[ForwardRef('int', module='mod')]), - "typing.List[ForwardRef('int', module='mod')]") + self.assertEqual(repr(List[ForwardRef('int', module='mod')]), + "typing.List[ForwardRef('int', module='mod')]") def test_union_forward(self): diff --git a/Modules/_blake2/blake2s_impl.c b/Modules/_blake2/blake2s_impl.c index 763c0178e6bcd..4812730bd8ef4 100644 --- a/Modules/_blake2/blake2s_impl.c +++ b/Modules/_blake2/blake2s_impl.c @@ -18,7 +18,7 @@ #endif #include "Python.h" -#include "pycore_strhex.h" // _Py_strhex() +#include "pycore_strhex.h" // _Py_strhex() #include "../hashlib.h" #include "blake2ns.h" @@ -37,6 +37,7 @@ #include "impl/blake2s-ref.c" #endif + extern PyType_Spec blake2s_type_spec; typedef struct { diff --git a/Python/fileutils.c b/Python/fileutils.c index 9a71b83f45578..111d7fa84b188 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -2093,7 +2093,7 @@ join_relfile(wchar_t *buffer, size_t bufsize, const wchar_t *dirname, const wchar_t *relfile) { #ifdef MS_WINDOWS - if (FAILED(PathCchCombineEx(buffer, bufsize, dirname, relfile, + if (FAILED(PathCchCombineEx(buffer, bufsize, dirname, relfile, PATHCCH_ALLOW_LONG_PATHS))) { return -1; } diff --git a/Python/specialize.c b/Python/specialize.c index 6328f11f90407..417eece88b86a 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -1077,7 +1077,7 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) PyTypeObject *owner_cls = Py_TYPE(owner); if (PyModule_CheckExact(owner)) { - assert(INLINE_CACHE_ENTRIES_LOAD_ATTR <= + assert(INLINE_CACHE_ENTRIES_LOAD_ATTR <= INLINE_CACHE_ENTRIES_LOAD_METHOD); int err = specialize_module_load_attr(owner, instr, name, LOAD_METHOD, LOAD_METHOD_MODULE); diff --git a/Tools/scripts/freeze_modules.py b/Tools/scripts/freeze_modules.py index 0dc61e2fe32b2..c8d8a7dd1fbab 100644 --- a/Tools/scripts/freeze_modules.py +++ b/Tools/scripts/freeze_modules.py @@ -18,7 +18,7 @@ FROZEN_ONLY = os.path.join(ROOT_DIR, 'Tools', 'freeze', 'flag.py') STDLIB_DIR = os.path.join(ROOT_DIR, 'Lib') -# If FROZEN_MODULES_DIR or DEEPFROZEN_MODULES_DIR is changed then the +# If FROZEN_MODULES_DIR or DEEPFROZEN_MODULES_DIR is changed then the # .gitattributes and .gitignore files needs to be updated. FROZEN_MODULES_DIR = os.path.join(ROOT_DIR, 'Python', 'frozen_modules') DEEPFROZEN_MODULES_DIR = os.path.join(ROOT_DIR, 'Python', 'deepfreeze') @@ -732,4 +732,4 @@ def main(): if __name__ == '__main__': - main() + main() From webhook-mailer at python.org Sat Mar 5 21:39:33 2022 From: webhook-mailer at python.org (methane) Date: Sun, 06 Mar 2022 02:39:33 -0000 Subject: [Python-checkins] bpo-46864: Deprecate PyBytesObject.ob_shash. (GH-31598) Message-ID: https://github.com/python/cpython/commit/2d8b764210c8de10893665aaeec8277b687975cd commit: 2d8b764210c8de10893665aaeec8277b687975cd branch: main author: Inada Naoki committer: methane date: 2022-03-06T11:39:10+09:00 summary: bpo-46864: Deprecate PyBytesObject.ob_shash. (GH-31598) files: A Misc/NEWS.d/next/Core and Builtins/2022-02-26-19-26-36.bpo-46864.EmLgFp.rst M Doc/whatsnew/3.11.rst M Include/cpython/bytesobject.h M Objects/bytesobject.c diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 5843287ae8e18..4a64e044c4a16 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -985,6 +985,9 @@ Deprecated ` instead (:pep:`587`). (Contributed by Victor Stinner in :issue:`44113`.) +* Deprecate the ``ob_shash`` member of the :c:type:`PyBytesObject`. Use :c:func:`PyObject_Hash` instead. + (Contributed by Inada Naoki in :issue:`46864`.) + Removed ------- diff --git a/Include/cpython/bytesobject.h b/Include/cpython/bytesobject.h index 6b3f55224fc55..2c6d631f0b21e 100644 --- a/Include/cpython/bytesobject.h +++ b/Include/cpython/bytesobject.h @@ -4,7 +4,7 @@ typedef struct { PyObject_VAR_HEAD - Py_hash_t ob_shash; + Py_DEPRECATED(3.11) Py_hash_t ob_shash; char ob_sval[1]; /* Invariants: diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-26-19-26-36.bpo-46864.EmLgFp.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-26-19-26-36.bpo-46864.EmLgFp.rst new file mode 100644 index 0000000000000..82657155d7228 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-02-26-19-26-36.bpo-46864.EmLgFp.rst @@ -0,0 +1 @@ +Deprecate ``PyBytesObject.ob_shash``. It will be removed in Python 3.13. diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index c6160aad790be..fd1c58c2f233e 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -105,7 +105,10 @@ _PyBytes_FromSize(Py_ssize_t size, int use_calloc) return PyErr_NoMemory(); } _PyObject_InitVar((PyVarObject*)op, &PyBytes_Type, size); +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS op->ob_shash = -1; +_Py_COMP_DIAG_POP if (!use_calloc) { op->ob_sval[size] = '\0'; } @@ -169,7 +172,10 @@ PyBytes_FromString(const char *str) return PyErr_NoMemory(); } _PyObject_InitVar((PyVarObject*)op, &PyBytes_Type, size); +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS op->ob_shash = -1; +_Py_COMP_DIAG_POP memcpy(op->ob_sval, str, size+1); return (PyObject *) op; } @@ -1446,7 +1452,10 @@ bytes_repeat(PyBytesObject *a, Py_ssize_t n) return PyErr_NoMemory(); } _PyObject_InitVar((PyVarObject*)op, &PyBytes_Type, size); +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS op->ob_shash = -1; +_Py_COMP_DIAG_POP op->ob_sval[size] = '\0'; if (Py_SIZE(a) == 1 && n > 0) { memset(op->ob_sval, a->ob_sval[0] , n); @@ -1562,11 +1571,14 @@ bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op) static Py_hash_t bytes_hash(PyBytesObject *a) { +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS if (a->ob_shash == -1) { /* Can't fail */ a->ob_shash = _Py_HashBytes(a->ob_sval, Py_SIZE(a)); } return a->ob_shash; +_Py_COMP_DIAG_POP } static PyObject* @@ -2868,8 +2880,11 @@ bytes_subtype_new(PyTypeObject *type, PyObject *tmp) if (pnew != NULL) { memcpy(PyBytes_AS_STRING(pnew), PyBytes_AS_STRING(tmp), n+1); +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS ((PyBytesObject *)pnew)->ob_shash = ((PyBytesObject *)tmp)->ob_shash; +_Py_COMP_DIAG_POP } return pnew; } @@ -3051,7 +3066,10 @@ _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize) sv = (PyBytesObject *) *pv; Py_SET_SIZE(sv, newsize); sv->ob_sval[newsize] = '\0'; +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS sv->ob_shash = -1; /* invalidate cached hash value */ +_Py_COMP_DIAG_POP return 0; error: *pv = 0; From webhook-mailer at python.org Sun Mar 6 01:22:00 2022 From: webhook-mailer at python.org (Fidget-Spinner) Date: Sun, 06 Mar 2022 06:22:00 -0000 Subject: [Python-checkins] bpo-46921: Vectorcall support for `super()` (GH-31687) Message-ID: https://github.com/python/cpython/commit/602024e6e12c69d836aa191d63db75862aec2493 commit: 602024e6e12c69d836aa191d63db75862aec2493 branch: main author: Ken Jin <28750310+Fidget-Spinner at users.noreply.github.com> committer: Fidget-Spinner <28750310+Fidget-Spinner at users.noreply.github.com> date: 2022-03-06T14:21:28+08:00 summary: bpo-46921: Vectorcall support for `super()` (GH-31687) Co-Authored-By: Dong-hee Na files: A Misc/NEWS.d/next/Core and Builtins/2022-03-05-00-43-22.bpo-46921.tyuPeB.rst M Lib/test/test_super.py M Objects/typeobject.c diff --git a/Lib/test/test_super.py b/Lib/test/test_super.py index 5d94372bf6ec7..a68b38cf79d53 100644 --- a/Lib/test/test_super.py +++ b/Lib/test/test_super.py @@ -317,6 +317,14 @@ def test_super_init_leaks(self): for i in range(1000): super.__init__(sp, int, i) + def test_super_argcount(self): + with self.assertRaisesRegex(TypeError, "expected at most"): + super(int, int, int) + + def test_super_argtype(self): + with self.assertRaisesRegex(TypeError, "argument 1 must be a type"): + super(1, int) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-05-00-43-22.bpo-46921.tyuPeB.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-05-00-43-22.bpo-46921.tyuPeB.rst new file mode 100644 index 0000000000000..4ccd00b87f591 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-05-00-43-22.bpo-46921.tyuPeB.rst @@ -0,0 +1 @@ +Support vectorcall for ``super()``. Patch by Ken Jin. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 1dfeac3b9e660..7879515075613 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -9000,19 +9000,28 @@ super_init_without_args(_PyInterpreterFrame *cframe, PyCodeObject *co, return 0; } +static int super_init_impl(PyObject *self, PyTypeObject *type, PyObject *obj); + static int super_init(PyObject *self, PyObject *args, PyObject *kwds) { - superobject *su = (superobject *)self; PyTypeObject *type = NULL; PyObject *obj = NULL; - PyTypeObject *obj_type = NULL; if (!_PyArg_NoKeywords("super", kwds)) return -1; if (!PyArg_ParseTuple(args, "|O!O:super", &PyType_Type, &type, &obj)) return -1; + if (super_init_impl(self, type, obj) < 0) { + return -1; + } + return 0; +} +static inline int +super_init_impl(PyObject *self, PyTypeObject *type, PyObject *obj) { + superobject *su = (superobject *)self; + PyTypeObject *obj_type = NULL; if (type == NULL) { /* Call super(), without args -- fill in from __class__ and first local variable on the stack. */ @@ -9072,6 +9081,47 @@ super_traverse(PyObject *self, visitproc visit, void *arg) return 0; } +static PyObject * +super_vectorcall(PyObject *self, PyObject *const *args, + size_t nargsf, PyObject *kwnames) +{ + assert(PyType_Check(self)); + if (!_PyArg_NoKwnames("super", kwnames)) { + return NULL; + } + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (!_PyArg_CheckPositional("super()", nargs, 0, 2)) { + return NULL; + } + PyTypeObject *type = NULL; + PyObject *obj = NULL; + PyTypeObject *self_type = (PyTypeObject *)self; + PyObject *su = self_type->tp_alloc(self_type, 0); + if (su == NULL) { + return NULL; + } + // 1 or 2 argument form super(). + if (nargs != 0) { + PyObject *arg0 = args[0]; + if (!PyType_Check(arg0)) { + PyErr_Format(PyExc_TypeError, + "super() argument 1 must be a type, not %.200s", Py_TYPE(arg0)->tp_name); + goto fail; + } + type = (PyTypeObject *)arg0; + } + if (nargs == 2) { + obj = args[1]; + } + if (super_init_impl(su, type, obj) < 0) { + goto fail; + } + return su; +fail: + Py_DECREF(su); + return NULL; +} + PyTypeObject PySuper_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "super", /* tp_name */ @@ -9114,4 +9164,5 @@ PyTypeObject PySuper_Type = { PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ PyObject_GC_Del, /* tp_free */ + .tp_vectorcall = (vectorcallfunc)super_vectorcall, }; From webhook-mailer at python.org Sun Mar 6 06:49:48 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Sun, 06 Mar 2022 11:49:48 -0000 Subject: [Python-checkins] bpo-14156: Make argparse.FileType work correctly for binary file modes when argument is '-' (GH-13165) Message-ID: https://github.com/python/cpython/commit/eafec26ae5327bb23b6dace2650b074c3327dfa0 commit: eafec26ae5327bb23b6dace2650b074c3327dfa0 branch: main author: MojoVampire committer: serhiy-storchaka date: 2022-03-06T13:49:42+02:00 summary: bpo-14156: Make argparse.FileType work correctly for binary file modes when argument is '-' (GH-13165) Also made modes containing 'a' or 'x' act the same as a mode containing 'w' when argument is '-' (so 'a'/'x' return sys.stdout like 'w', and 'ab'/'xb' return sys.stdout.buffer like 'wb'). files: A Misc/NEWS.d/next/Library/2019-05-07-14-25-45.bpo-14156.0FaHXE.rst M Lib/argparse.py M Lib/test/test_argparse.py diff --git a/Lib/argparse.py b/Lib/argparse.py index 3c6aa3c991bfd..429a72ab7841e 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -728,7 +728,7 @@ def _get_action_name(argument): if argument is None: return None elif argument.option_strings: - return '/'.join(argument.option_strings) + return '/'.join(argument.option_strings) elif argument.metavar not in (None, SUPPRESS): return argument.metavar elif argument.dest not in (None, SUPPRESS): @@ -1259,9 +1259,9 @@ def __call__(self, string): # the special argument "-" means sys.std{in,out} if string == '-': if 'r' in self._mode: - return _sys.stdin - elif 'w' in self._mode: - return _sys.stdout + return _sys.stdin.buffer if 'b' in self._mode else _sys.stdin + elif any(c in self._mode for c in 'wax'): + return _sys.stdout.buffer if 'b' in self._mode else _sys.stdout else: msg = _('argument "-" with mode %r') % self._mode raise ValueError(msg) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index df6da928c9beb..1f03b7fb24261 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -1,6 +1,8 @@ # Author: Steven J. Bethard . import inspect +import io +import operator import os import shutil import stat @@ -11,12 +13,27 @@ import argparse import warnings -from io import StringIO - from test.support import os_helper from unittest import mock -class StdIOBuffer(StringIO): - pass + + +class StdIOBuffer(io.TextIOWrapper): + '''Replacement for writable io.StringIO that behaves more like real file + + Unlike StringIO, provides a buffer attribute that holds the underlying + binary data, allowing it to replace sys.stdout/sys.stderr in more + contexts. + ''' + + def __init__(self, initial_value='', newline='\n'): + initial_value = initial_value.encode('utf-8') + super().__init__(io.BufferedWriter(io.BytesIO(initial_value)), + 'utf-8', newline=newline) + + def getvalue(self): + self.flush() + return self.buffer.raw.getvalue().decode('utf-8') + class TestCase(unittest.TestCase): @@ -43,11 +60,14 @@ def tearDown(self): os.chmod(os.path.join(self.temp_dir, name), stat.S_IWRITE) shutil.rmtree(self.temp_dir, True) - def create_readonly_file(self, filename): + def create_writable_file(self, filename): file_path = os.path.join(self.temp_dir, filename) with open(file_path, 'w', encoding="utf-8") as file: file.write(filename) - os.chmod(file_path, stat.S_IREAD) + return file_path + + def create_readonly_file(self, filename): + os.chmod(self.create_writable_file(filename), stat.S_IREAD) class Sig(object): @@ -97,10 +117,15 @@ def stderr_to_parser_error(parse_args, *args, **kwargs): try: result = parse_args(*args, **kwargs) for key in list(vars(result)): - if getattr(result, key) is sys.stdout: + attr = getattr(result, key) + if attr is sys.stdout: setattr(result, key, old_stdout) - if getattr(result, key) is sys.stderr: + elif attr is sys.stdout.buffer: + setattr(result, key, getattr(old_stdout, 'buffer', BIN_STDOUT_SENTINEL)) + elif attr is sys.stderr: setattr(result, key, old_stderr) + elif attr is sys.stderr.buffer: + setattr(result, key, getattr(old_stderr, 'buffer', BIN_STDERR_SENTINEL)) return result except SystemExit as e: code = e.code @@ -1565,16 +1590,40 @@ def test_r_1_replace(self): type = argparse.FileType('r', 1, errors='replace') self.assertEqual("FileType('r', 1, errors='replace')", repr(type)) + +BIN_STDOUT_SENTINEL = object() +BIN_STDERR_SENTINEL = object() + + class StdStreamComparer: def __init__(self, attr): - self.attr = attr + # We try to use the actual stdXXX.buffer attribute as our + # marker, but but under some test environments, + # sys.stdout/err are replaced by io.StringIO which won't have .buffer, + # so we use a sentinel simply to show that the tests do the right thing + # for any buffer supporting object + self.getattr = operator.attrgetter(attr) + if attr == 'stdout.buffer': + self.backupattr = BIN_STDOUT_SENTINEL + elif attr == 'stderr.buffer': + self.backupattr = BIN_STDERR_SENTINEL + else: + self.backupattr = object() # Not equal to anything def __eq__(self, other): - return other == getattr(sys, self.attr) + try: + return other == self.getattr(sys) + except AttributeError: + return other == self.backupattr + eq_stdin = StdStreamComparer('stdin') eq_stdout = StdStreamComparer('stdout') eq_stderr = StdStreamComparer('stderr') +eq_bstdin = StdStreamComparer('stdin.buffer') +eq_bstdout = StdStreamComparer('stdout.buffer') +eq_bstderr = StdStreamComparer('stderr.buffer') + class RFile(object): seen = {} @@ -1653,7 +1702,7 @@ def setUp(self): ('foo', NS(x=None, spam=RFile('foo'))), ('-x foo bar', NS(x=RFile('foo'), spam=RFile('bar'))), ('bar -x foo', NS(x=RFile('foo'), spam=RFile('bar'))), - ('-x - -', NS(x=eq_stdin, spam=eq_stdin)), + ('-x - -', NS(x=eq_bstdin, spam=eq_bstdin)), ] @@ -1680,8 +1729,9 @@ class TestFileTypeW(TempDirMixin, ParserTestCase): """Test the FileType option/argument type for writing files""" def setUp(self): - super(TestFileTypeW, self).setUp() + super().setUp() self.create_readonly_file('readonly') + self.create_writable_file('writable') argument_signatures = [ Sig('-x', type=argparse.FileType('w')), @@ -1690,13 +1740,37 @@ def setUp(self): failures = ['-x', '', 'readonly'] successes = [ ('foo', NS(x=None, spam=WFile('foo'))), + ('writable', NS(x=None, spam=WFile('writable'))), ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))), ('bar -x foo', NS(x=WFile('foo'), spam=WFile('bar'))), ('-x - -', NS(x=eq_stdout, spam=eq_stdout)), ] + at unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0, + "non-root user required") +class TestFileTypeX(TempDirMixin, ParserTestCase): + """Test the FileType option/argument type for writing new files only""" + + def setUp(self): + super().setUp() + self.create_readonly_file('readonly') + self.create_writable_file('writable') + + argument_signatures = [ + Sig('-x', type=argparse.FileType('x')), + Sig('spam', type=argparse.FileType('x')), + ] + failures = ['-x', '', 'readonly', 'writable'] + successes = [ + ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))), + ('-x - -', NS(x=eq_stdout, spam=eq_stdout)), + ] + + at unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0, + "non-root user required") class TestFileTypeWB(TempDirMixin, ParserTestCase): + """Test the FileType option/argument type for writing binary files""" argument_signatures = [ Sig('-x', type=argparse.FileType('wb')), @@ -1707,7 +1781,22 @@ class TestFileTypeWB(TempDirMixin, ParserTestCase): ('foo', NS(x=None, spam=WFile('foo'))), ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))), ('bar -x foo', NS(x=WFile('foo'), spam=WFile('bar'))), - ('-x - -', NS(x=eq_stdout, spam=eq_stdout)), + ('-x - -', NS(x=eq_bstdout, spam=eq_bstdout)), + ] + + + at unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0, + "non-root user required") +class TestFileTypeXB(TestFileTypeX): + "Test the FileType option/argument type for writing new binary files only" + + argument_signatures = [ + Sig('-x', type=argparse.FileType('xb')), + Sig('spam', type=argparse.FileType('xb')), + ] + successes = [ + ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))), + ('-x - -', NS(x=eq_bstdout, spam=eq_bstdout)), ] diff --git a/Misc/NEWS.d/next/Library/2019-05-07-14-25-45.bpo-14156.0FaHXE.rst b/Misc/NEWS.d/next/Library/2019-05-07-14-25-45.bpo-14156.0FaHXE.rst new file mode 100644 index 0000000000000..7bfc917a2a750 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-07-14-25-45.bpo-14156.0FaHXE.rst @@ -0,0 +1,4 @@ +argparse.FileType now supports an argument of '-' in binary mode, returning +the .buffer attribute of sys.stdin/sys.stdout as appropriate. Modes +including 'x' and 'a' are treated equivalently to 'w' when argument is '-'. +Patch contributed by Josh Rosenberg From webhook-mailer at python.org Sun Mar 6 07:12:13 2022 From: webhook-mailer at python.org (miss-islington) Date: Sun, 06 Mar 2022 12:12:13 -0000 Subject: [Python-checkins] bpo-14156: Make argparse.FileType work correctly for binary file modes when argument is '-' (GH-13165) Message-ID: https://github.com/python/cpython/commit/ee18df425209cfa4f394b57220177c168fc3a1da commit: ee18df425209cfa4f394b57220177c168fc3a1da branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-06T04:12:06-08:00 summary: bpo-14156: Make argparse.FileType work correctly for binary file modes when argument is '-' (GH-13165) Also made modes containing 'a' or 'x' act the same as a mode containing 'w' when argument is '-' (so 'a'/'x' return sys.stdout like 'w', and 'ab'/'xb' return sys.stdout.buffer like 'wb'). (cherry picked from commit eafec26ae5327bb23b6dace2650b074c3327dfa0) Co-authored-by: MojoVampire files: A Misc/NEWS.d/next/Library/2019-05-07-14-25-45.bpo-14156.0FaHXE.rst M Lib/argparse.py M Lib/test/test_argparse.py diff --git a/Lib/argparse.py b/Lib/argparse.py index b71a6703c3982..2c0dd853a5bdd 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -726,7 +726,7 @@ def _get_action_name(argument): if argument is None: return None elif argument.option_strings: - return '/'.join(argument.option_strings) + return '/'.join(argument.option_strings) elif argument.metavar not in (None, SUPPRESS): return argument.metavar elif argument.dest not in (None, SUPPRESS): @@ -1256,9 +1256,9 @@ def __call__(self, string): # the special argument "-" means sys.std{in,out} if string == '-': if 'r' in self._mode: - return _sys.stdin - elif 'w' in self._mode: - return _sys.stdout + return _sys.stdin.buffer if 'b' in self._mode else _sys.stdin + elif any(c in self._mode for c in 'wax'): + return _sys.stdout.buffer if 'b' in self._mode else _sys.stdout else: msg = _('argument "-" with mode %r') % self._mode raise ValueError(msg) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 9d66ace5474a1..d4426bab5e09a 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -1,6 +1,8 @@ # Author: Steven J. Bethard . import inspect +import io +import operator import os import shutil import stat @@ -10,12 +12,27 @@ import unittest import argparse -from io import StringIO - from test.support import os_helper from unittest import mock -class StdIOBuffer(StringIO): - pass + + +class StdIOBuffer(io.TextIOWrapper): + '''Replacement for writable io.StringIO that behaves more like real file + + Unlike StringIO, provides a buffer attribute that holds the underlying + binary data, allowing it to replace sys.stdout/sys.stderr in more + contexts. + ''' + + def __init__(self, initial_value='', newline='\n'): + initial_value = initial_value.encode('utf-8') + super().__init__(io.BufferedWriter(io.BytesIO(initial_value)), + 'utf-8', newline=newline) + + def getvalue(self): + self.flush() + return self.buffer.raw.getvalue().decode('utf-8') + class TestCase(unittest.TestCase): @@ -42,11 +59,14 @@ def tearDown(self): os.chmod(os.path.join(self.temp_dir, name), stat.S_IWRITE) shutil.rmtree(self.temp_dir, True) - def create_readonly_file(self, filename): + def create_writable_file(self, filename): file_path = os.path.join(self.temp_dir, filename) with open(file_path, 'w', encoding="utf-8") as file: file.write(filename) - os.chmod(file_path, stat.S_IREAD) + return file_path + + def create_readonly_file(self, filename): + os.chmod(self.create_writable_file(filename), stat.S_IREAD) class Sig(object): @@ -96,10 +116,15 @@ def stderr_to_parser_error(parse_args, *args, **kwargs): try: result = parse_args(*args, **kwargs) for key in list(vars(result)): - if getattr(result, key) is sys.stdout: + attr = getattr(result, key) + if attr is sys.stdout: setattr(result, key, old_stdout) - if getattr(result, key) is sys.stderr: + elif attr is sys.stdout.buffer: + setattr(result, key, getattr(old_stdout, 'buffer', BIN_STDOUT_SENTINEL)) + elif attr is sys.stderr: setattr(result, key, old_stderr) + elif attr is sys.stderr.buffer: + setattr(result, key, getattr(old_stderr, 'buffer', BIN_STDERR_SENTINEL)) return result except SystemExit as e: code = e.code @@ -1545,16 +1570,40 @@ def test_r_1_replace(self): type = argparse.FileType('r', 1, errors='replace') self.assertEqual("FileType('r', 1, errors='replace')", repr(type)) + +BIN_STDOUT_SENTINEL = object() +BIN_STDERR_SENTINEL = object() + + class StdStreamComparer: def __init__(self, attr): - self.attr = attr + # We try to use the actual stdXXX.buffer attribute as our + # marker, but but under some test environments, + # sys.stdout/err are replaced by io.StringIO which won't have .buffer, + # so we use a sentinel simply to show that the tests do the right thing + # for any buffer supporting object + self.getattr = operator.attrgetter(attr) + if attr == 'stdout.buffer': + self.backupattr = BIN_STDOUT_SENTINEL + elif attr == 'stderr.buffer': + self.backupattr = BIN_STDERR_SENTINEL + else: + self.backupattr = object() # Not equal to anything def __eq__(self, other): - return other == getattr(sys, self.attr) + try: + return other == self.getattr(sys) + except AttributeError: + return other == self.backupattr + eq_stdin = StdStreamComparer('stdin') eq_stdout = StdStreamComparer('stdout') eq_stderr = StdStreamComparer('stderr') +eq_bstdin = StdStreamComparer('stdin.buffer') +eq_bstdout = StdStreamComparer('stdout.buffer') +eq_bstderr = StdStreamComparer('stderr.buffer') + class RFile(object): seen = {} @@ -1633,7 +1682,7 @@ def setUp(self): ('foo', NS(x=None, spam=RFile('foo'))), ('-x foo bar', NS(x=RFile('foo'), spam=RFile('bar'))), ('bar -x foo', NS(x=RFile('foo'), spam=RFile('bar'))), - ('-x - -', NS(x=eq_stdin, spam=eq_stdin)), + ('-x - -', NS(x=eq_bstdin, spam=eq_bstdin)), ] @@ -1660,8 +1709,9 @@ class TestFileTypeW(TempDirMixin, ParserTestCase): """Test the FileType option/argument type for writing files""" def setUp(self): - super(TestFileTypeW, self).setUp() + super().setUp() self.create_readonly_file('readonly') + self.create_writable_file('writable') argument_signatures = [ Sig('-x', type=argparse.FileType('w')), @@ -1670,13 +1720,37 @@ def setUp(self): failures = ['-x', '', 'readonly'] successes = [ ('foo', NS(x=None, spam=WFile('foo'))), + ('writable', NS(x=None, spam=WFile('writable'))), ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))), ('bar -x foo', NS(x=WFile('foo'), spam=WFile('bar'))), ('-x - -', NS(x=eq_stdout, spam=eq_stdout)), ] + at unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0, + "non-root user required") +class TestFileTypeX(TempDirMixin, ParserTestCase): + """Test the FileType option/argument type for writing new files only""" + + def setUp(self): + super().setUp() + self.create_readonly_file('readonly') + self.create_writable_file('writable') + + argument_signatures = [ + Sig('-x', type=argparse.FileType('x')), + Sig('spam', type=argparse.FileType('x')), + ] + failures = ['-x', '', 'readonly', 'writable'] + successes = [ + ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))), + ('-x - -', NS(x=eq_stdout, spam=eq_stdout)), + ] + + at unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0, + "non-root user required") class TestFileTypeWB(TempDirMixin, ParserTestCase): + """Test the FileType option/argument type for writing binary files""" argument_signatures = [ Sig('-x', type=argparse.FileType('wb')), @@ -1687,7 +1761,22 @@ class TestFileTypeWB(TempDirMixin, ParserTestCase): ('foo', NS(x=None, spam=WFile('foo'))), ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))), ('bar -x foo', NS(x=WFile('foo'), spam=WFile('bar'))), - ('-x - -', NS(x=eq_stdout, spam=eq_stdout)), + ('-x - -', NS(x=eq_bstdout, spam=eq_bstdout)), + ] + + + at unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0, + "non-root user required") +class TestFileTypeXB(TestFileTypeX): + "Test the FileType option/argument type for writing new binary files only" + + argument_signatures = [ + Sig('-x', type=argparse.FileType('xb')), + Sig('spam', type=argparse.FileType('xb')), + ] + successes = [ + ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))), + ('-x - -', NS(x=eq_bstdout, spam=eq_bstdout)), ] diff --git a/Misc/NEWS.d/next/Library/2019-05-07-14-25-45.bpo-14156.0FaHXE.rst b/Misc/NEWS.d/next/Library/2019-05-07-14-25-45.bpo-14156.0FaHXE.rst new file mode 100644 index 0000000000000..7bfc917a2a750 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-07-14-25-45.bpo-14156.0FaHXE.rst @@ -0,0 +1,4 @@ +argparse.FileType now supports an argument of '-' in binary mode, returning +the .buffer attribute of sys.stdin/sys.stdout as appropriate. Modes +including 'x' and 'a' are treated equivalently to 'w' when argument is '-'. +Patch contributed by Josh Rosenberg From webhook-mailer at python.org Sun Mar 6 09:26:54 2022 From: webhook-mailer at python.org (pablogsal) Date: Sun, 06 Mar 2022 14:26:54 -0000 Subject: [Python-checkins] Update grammar_grapher with the new forced (&&) directive (#31704) Message-ID: https://github.com/python/cpython/commit/7f07b5ee9c2d17f837c44440bf066c73f92dac14 commit: 7f07b5ee9c2d17f837c44440bf066c73f92dac14 branch: main author: Luca Chiodini committer: pablogsal date: 2022-03-06T15:26:28+01:00 summary: Update grammar_grapher with the new forced (&&) directive (#31704) files: M Tools/peg_generator/scripts/grammar_grapher.py diff --git a/Tools/peg_generator/scripts/grammar_grapher.py b/Tools/peg_generator/scripts/grammar_grapher.py index 4d771239c2954..4a41dfaa3da0f 100755 --- a/Tools/peg_generator/scripts/grammar_grapher.py +++ b/Tools/peg_generator/scripts/grammar_grapher.py @@ -29,6 +29,7 @@ from pegen.grammar import ( Alt, Cut, + Forced, Grammar, Group, Leaf, @@ -60,6 +61,8 @@ def references_for_item(item: Any) -> List[Any]: return [_ref for _item in item.items for _ref in references_for_item(_item)] elif isinstance(item, Cut): return [] + elif isinstance(item, Forced): + return references_for_item(item.node) elif isinstance(item, Group): return references_for_item(item.rhs) elif isinstance(item, Lookahead): From webhook-mailer at python.org Sun Mar 6 14:49:36 2022 From: webhook-mailer at python.org (tiran) Date: Sun, 06 Mar 2022 19:49:36 -0000 Subject: [Python-checkins] bpo-45582: Don't fail if ENV_PATH is None in getpath.py (GH-31699) Message-ID: https://github.com/python/cpython/commit/55a5e17d19fecb6a7af85a1a9d44304e5fcb19c7 commit: 55a5e17d19fecb6a7af85a1a9d44304e5fcb19c7 branch: main author: Christian Heimes committer: tiran date: 2022-03-06T20:49:27+01:00 summary: bpo-45582: Don't fail if ENV_PATH is None in getpath.py (GH-31699) files: M Modules/getpath.py diff --git a/Modules/getpath.py b/Modules/getpath.py index f84e6e8afaf62..3a13bfdf491a1 100644 --- a/Modules/getpath.py +++ b/Modules/getpath.py @@ -277,7 +277,7 @@ def search_up(prefix, *landmarks, test=isfile): # executable path was provided in the config. real_executable = executable -if not executable and program_name: +if not executable and program_name and ENV_PATH: # Resolve names against PATH. # NOTE: The use_environment value is ignored for this lookup. # To properly isolate, launch Python with a full path. From webhook-mailer at python.org Sun Mar 6 21:05:29 2022 From: webhook-mailer at python.org (orsenthil) Date: Mon, 07 Mar 2022 02:05:29 -0000 Subject: [Python-checkins] Clean up CODEOWNERS (#31715) Message-ID: https://github.com/python/cpython/commit/e38d0dfe92c28e081a46a5a858ac26bd6a14aded commit: e38d0dfe92c28e081a46a5a858ac26bd6a14aded branch: main author: Jelle Zijlstra committer: orsenthil date: 2022-03-06T18:04:58-08:00 summary: Clean up CODEOWNERS (#31715) crypto-team apparently doesn't exist and skrah no longer has write access. Thanks @isidentical for noticing this. files: M .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index d2097d32557e1..ff7ffe1414605 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -32,13 +32,13 @@ Python/traceback.c @iritkatriel Python/pythonrun.c @iritkatriel # Hashing -**/*hashlib* @python/crypto-team @tiran -**/*pyhash* @python/crypto-team @tiran -**/*sha* @python/crypto-team @tiran -**/*md5* @python/crypto-team @tiran -**/*blake* @python/crypto-team @tiran -/Modules/_blake2/** @python/crypto-team @tiran -/Modules/_sha3/** @python/crypto-team @tiran +**/*hashlib* @tiran +**/*pyhash* @tiran +**/*sha* @tiran +**/*md5* @tiran +**/*blake* @tiran +/Modules/_blake2/** @tiran +/Modules/_sha3/** @tiran # logging **/*logging* @vsajip @@ -61,14 +61,6 @@ Python/pythonrun.c @iritkatriel **/*import*.c @brettcannon @encukou @ericsnowcurrently @ncoghlan @warsaw **/*import*.py @brettcannon @encukou @ericsnowcurrently @ncoghlan @warsaw - -# SSL -**/*ssl* @python/crypto-team -**/*.pem @python/crypto-team - -# CSPRNG -Python/bootstrap_hash.c @python/crypto-team - # Dates and times **/*datetime* @pganssle @abalkin **/*str*time* @pganssle @abalkin @@ -132,7 +124,7 @@ Lib/ast.py @isidentical **/*bisect* @rhettinger **/*heapq* @rhettinger **/*functools* @rhettinger -**/*decimal* @rhettinger @skrah +**/*decimal* @rhettinger **/*dataclasses* @ericvsmith From webhook-mailer at python.org Mon Mar 7 02:33:06 2022 From: webhook-mailer at python.org (sweeneyde) Date: Mon, 07 Mar 2022 07:33:06 -0000 Subject: [Python-checkins] Use assertEqual, not assertEquals, in test_unicode (GH-31718) Message-ID: https://github.com/python/cpython/commit/b748a36696ca56ed4ffcfae011a8488878eb2b3a commit: b748a36696ca56ed4ffcfae011a8488878eb2b3a branch: main author: Dennis Sweeney <36520290+sweeneyde at users.noreply.github.com> committer: sweeneyde <36520290+sweeneyde at users.noreply.github.com> date: 2022-03-07T02:32:51-05:00 summary: Use assertEqual, not assertEquals, in test_unicode (GH-31718) Fixes a DeprecationWarning files: M Lib/test/test_unicode.py diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py index e97f971b77a63..df7afd5046a56 100644 --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -3055,18 +3055,18 @@ class Bag: with self.assertRaises(AttributeError): delattr(o, name) setattr(o, name, 1) - self.assertEquals(o.name, 1) + self.assertEqual(o.name, 1) o.name = 2 - self.assertEquals(list(o.__dict__), [name]) + self.assertEqual(list(o.__dict__), [name]) with self.assertRaises(AttributeError): delattr(o, name2) with self.assertRaises(AttributeError): del o.name2 setattr(o, name2, 3) - self.assertEquals(o.name2, 3) + self.assertEqual(o.name2, 3) o.name2 = 4 - self.assertEquals(list(o.__dict__), [name, name2]) + self.assertEqual(list(o.__dict__), [name, name2]) if __name__ == "__main__": From webhook-mailer at python.org Mon Mar 7 04:32:26 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Mon, 07 Mar 2022 09:32:26 -0000 Subject: [Python-checkins] bpo-43292: Fix file leak in `ET.iterparse()` when not exhausted (GH-31696) Message-ID: https://github.com/python/cpython/commit/496c428de3318c9c5770937491b71dc3d3f18a6a commit: 496c428de3318c9c5770937491b71dc3d3f18a6a branch: main author: Jacob Walls committer: serhiy-storchaka date: 2022-03-07T11:31:46+02:00 summary: bpo-43292: Fix file leak in `ET.iterparse()` when not exhausted (GH-31696) Co-authored-by: Serhiy Storchaka files: A Misc/NEWS.d/next/Library/2022-03-05-09-43-53.bpo-25707.gTlclP.rst M Lib/test/test_xml_etree.py M Lib/xml/etree/ElementTree.py M Misc/ACKS diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index 35d901f9d0824..d2bdc4f7f0444 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -658,6 +658,14 @@ def test_iterparse(self): 'junk after document element: line 1, column 12') del cm, it + # Not exhausting the iterator still closes the resource (bpo-43292) + with warnings_helper.check_no_resource_warning(self): + it = iterparse(TESTFN) + del it + + with self.assertRaises(FileNotFoundError): + iterparse("nonexistent") + def test_writefile(self): elem = ET.Element("tag") elem.text = "text" diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py index 6059e2f592d2d..5249c7ab82b84 100644 --- a/Lib/xml/etree/ElementTree.py +++ b/Lib/xml/etree/ElementTree.py @@ -1244,8 +1244,14 @@ def iterparse(source, events=None, parser=None): # Use the internal, undocumented _parser argument for now; When the # parser argument of iterparse is removed, this can be killed. pullparser = XMLPullParser(events=events, _parser=parser) - def iterator(): + + def iterator(source): + close_source = False try: + if not hasattr(source, "read"): + source = open(source, "rb") + close_source = True + yield None while True: yield from pullparser.read_events() # load event buffer @@ -1261,16 +1267,12 @@ def iterator(): source.close() class IterParseIterator(collections.abc.Iterator): - __next__ = iterator().__next__ + __next__ = iterator(source).__next__ it = IterParseIterator() it.root = None del iterator, IterParseIterator - close_source = False - if not hasattr(source, "read"): - source = open(source, "rb") - close_source = True - + next(it) return it diff --git a/Misc/ACKS b/Misc/ACKS index da2c82610d5ad..df851bb834cd4 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1879,6 +1879,7 @@ Wojtek Walczak Charles Waldman Richard Walker Larry Wall +Jacob Walls Kevin Walzer Rodrigo Steinmuller Wanderley Dingyuan Wang diff --git a/Misc/NEWS.d/next/Library/2022-03-05-09-43-53.bpo-25707.gTlclP.rst b/Misc/NEWS.d/next/Library/2022-03-05-09-43-53.bpo-25707.gTlclP.rst new file mode 100644 index 0000000000000..a59f0a7657ff2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-05-09-43-53.bpo-25707.gTlclP.rst @@ -0,0 +1,2 @@ +Fixed a file leak in :func:`xml.etree.ElementTree.iterparse` when the +iterator is not exhausted. Patch by Jacob Walls. From webhook-mailer at python.org Mon Mar 7 04:57:55 2022 From: webhook-mailer at python.org (corona10) Date: Mon, 07 Mar 2022 09:57:55 -0000 Subject: [Python-checkins] bpo-46937: convert remaining functions to AC in _weakref (GH-31705) Message-ID: https://github.com/python/cpython/commit/5c06dba21b9767127f042b8a168703f06338c3f4 commit: 5c06dba21b9767127f042b8a168703f06338c3f4 branch: main author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> committer: corona10 date: 2022-03-07T18:57:45+09:00 summary: bpo-46937: convert remaining functions to AC in _weakref (GH-31705) files: M Modules/_weakref.c M Modules/clinic/_weakref.c.h diff --git a/Modules/_weakref.c b/Modules/_weakref.c index edc09b949fd3e..157a852ae9a37 100644 --- a/Modules/_weakref.c +++ b/Modules/_weakref.c @@ -76,12 +76,17 @@ _weakref__remove_dead_weakref_impl(PyObject *module, PyObject *dct, } -PyDoc_STRVAR(weakref_getweakrefs__doc__, -"getweakrefs(object) -- return a list of all weak reference objects\n" -"that point to 'object'."); +/*[clinic input] +_weakref.getweakrefs + object: object + / + +Return a list of all weak reference objects pointing to 'object'. +[clinic start generated code]*/ static PyObject * -weakref_getweakrefs(PyObject *self, PyObject *object) +_weakref_getweakrefs(PyObject *module, PyObject *object) +/*[clinic end generated code: output=25c7731d8e011824 input=00c6d0e5d3206693]*/ { PyObject *result = NULL; @@ -107,22 +112,24 @@ weakref_getweakrefs(PyObject *self, PyObject *object) } -PyDoc_STRVAR(weakref_proxy__doc__, -"proxy(object[, callback]) -- create a proxy object that weakly\n" -"references 'object'. 'callback', if given, is called with a\n" -"reference to the proxy when 'object' is about to be finalized."); +/*[clinic input] + +_weakref.proxy + object: object + callback: object(c_default="NULL") = None + / + +Create a proxy object that weakly references 'object'. + +'callback', if given, is called with a reference to the +proxy when 'object' is about to be finalized. +[clinic start generated code]*/ static PyObject * -weakref_proxy(PyObject *self, PyObject *args) +_weakref_proxy_impl(PyObject *module, PyObject *object, PyObject *callback) +/*[clinic end generated code: output=d68fa4ad9ea40519 input=4808adf22fd137e7]*/ { - PyObject *object; - PyObject *callback = NULL; - PyObject *result = NULL; - - if (PyArg_UnpackTuple(args, "proxy", 1, 2, &object, &callback)) { - result = PyWeakref_NewProxy(object, callback); - } - return result; + return PyWeakref_NewProxy(object, callback); } @@ -130,10 +137,8 @@ static PyMethodDef weakref_functions[] = { _WEAKREF_GETWEAKREFCOUNT_METHODDEF _WEAKREF__REMOVE_DEAD_WEAKREF_METHODDEF - {"getweakrefs", weakref_getweakrefs, METH_O, - weakref_getweakrefs__doc__}, - {"proxy", weakref_proxy, METH_VARARGS, - weakref_proxy__doc__}, + _WEAKREF_GETWEAKREFS_METHODDEF + _WEAKREF_PROXY_METHODDEF {NULL, NULL, 0, NULL} }; diff --git a/Modules/clinic/_weakref.c.h b/Modules/clinic/_weakref.c.h index c3a908fa6a139..02f0168937cde 100644 --- a/Modules/clinic/_weakref.c.h +++ b/Modules/clinic/_weakref.c.h @@ -64,4 +64,50 @@ _weakref__remove_dead_weakref(PyObject *module, PyObject *const *args, Py_ssize_ exit: return return_value; } -/*[clinic end generated code: output=c543dc2cd6ece975 input=a9049054013a1b77]*/ + +PyDoc_STRVAR(_weakref_getweakrefs__doc__, +"getweakrefs($module, object, /)\n" +"--\n" +"\n" +"Return a list of all weak reference objects pointing to \'object\'."); + +#define _WEAKREF_GETWEAKREFS_METHODDEF \ + {"getweakrefs", (PyCFunction)_weakref_getweakrefs, METH_O, _weakref_getweakrefs__doc__}, + +PyDoc_STRVAR(_weakref_proxy__doc__, +"proxy($module, object, callback=None, /)\n" +"--\n" +"\n" +"Create a proxy object that weakly references \'object\'.\n" +"\n" +"\'callback\', if given, is called with a reference to the\n" +"proxy when \'object\' is about to be finalized."); + +#define _WEAKREF_PROXY_METHODDEF \ + {"proxy", (PyCFunction)(void(*)(void))_weakref_proxy, METH_FASTCALL, _weakref_proxy__doc__}, + +static PyObject * +_weakref_proxy_impl(PyObject *module, PyObject *object, PyObject *callback); + +static PyObject * +_weakref_proxy(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *object; + PyObject *callback = NULL; + + if (!_PyArg_CheckPositional("proxy", nargs, 1, 2)) { + goto exit; + } + object = args[0]; + if (nargs < 2) { + goto skip_optional; + } + callback = args[1]; +skip_optional: + return_value = _weakref_proxy_impl(module, object, callback); + +exit: + return return_value; +} +/*[clinic end generated code: output=5a10a1fa43722399 input=a9049054013a1b77]*/ From webhook-mailer at python.org Mon Mar 7 05:32:07 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 07 Mar 2022 10:32:07 -0000 Subject: [Python-checkins] bpo-43292: Fix file leak in `ET.iterparse()` when not exhausted (GH-31696) Message-ID: https://github.com/python/cpython/commit/8acbb93c0763fa53b5959fe05d86ba275c9e8a5b commit: 8acbb93c0763fa53b5959fe05d86ba275c9e8a5b branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-07T02:31:52-08:00 summary: bpo-43292: Fix file leak in `ET.iterparse()` when not exhausted (GH-31696) Co-authored-by: Serhiy Storchaka (cherry picked from commit 496c428de3318c9c5770937491b71dc3d3f18a6a) Co-authored-by: Jacob Walls files: A Misc/NEWS.d/next/Library/2022-03-05-09-43-53.bpo-25707.gTlclP.rst M Lib/test/test_xml_etree.py M Lib/xml/etree/ElementTree.py M Misc/ACKS diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index c5292b5e9ef68..5a34d848b3944 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -658,6 +658,14 @@ def test_iterparse(self): 'junk after document element: line 1, column 12') del cm, it + # Not exhausting the iterator still closes the resource (bpo-43292) + with warnings_helper.check_no_resource_warning(self): + it = iterparse(TESTFN) + del it + + with self.assertRaises(FileNotFoundError): + iterparse("nonexistent") + def test_writefile(self): elem = ET.Element("tag") elem.text = "text" diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py index e9409fd29a115..07be8609b83d6 100644 --- a/Lib/xml/etree/ElementTree.py +++ b/Lib/xml/etree/ElementTree.py @@ -1248,8 +1248,14 @@ def iterparse(source, events=None, parser=None): # Use the internal, undocumented _parser argument for now; When the # parser argument of iterparse is removed, this can be killed. pullparser = XMLPullParser(events=events, _parser=parser) - def iterator(): + + def iterator(source): + close_source = False try: + if not hasattr(source, "read"): + source = open(source, "rb") + close_source = True + yield None while True: yield from pullparser.read_events() # load event buffer @@ -1265,16 +1271,12 @@ def iterator(): source.close() class IterParseIterator(collections.abc.Iterator): - __next__ = iterator().__next__ + __next__ = iterator(source).__next__ it = IterParseIterator() it.root = None del iterator, IterParseIterator - close_source = False - if not hasattr(source, "read"): - source = open(source, "rb") - close_source = True - + next(it) return it diff --git a/Misc/ACKS b/Misc/ACKS index e107945600988..c9bf79d035fcf 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1870,6 +1870,7 @@ Wojtek Walczak Charles Waldman Richard Walker Larry Wall +Jacob Walls Kevin Walzer Rodrigo Steinmuller Wanderley Dingyuan Wang diff --git a/Misc/NEWS.d/next/Library/2022-03-05-09-43-53.bpo-25707.gTlclP.rst b/Misc/NEWS.d/next/Library/2022-03-05-09-43-53.bpo-25707.gTlclP.rst new file mode 100644 index 0000000000000..a59f0a7657ff2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-05-09-43-53.bpo-25707.gTlclP.rst @@ -0,0 +1,2 @@ +Fixed a file leak in :func:`xml.etree.ElementTree.iterparse` when the +iterator is not exhausted. Patch by Jacob Walls. From webhook-mailer at python.org Mon Mar 7 06:49:11 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Mon, 07 Mar 2022 11:49:11 -0000 Subject: [Python-checkins] [3.9] bpo-43292: Fix file leak in `ET.iterparse()` when not exhausted (GH-31696) (GH-31720) Message-ID: https://github.com/python/cpython/commit/852d9b77abefcad2bb8d203e3ab9f2ca49ab305f commit: 852d9b77abefcad2bb8d203e3ab9f2ca49ab305f branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: serhiy-storchaka date: 2022-03-07T13:48:53+02:00 summary: [3.9] bpo-43292: Fix file leak in `ET.iterparse()` when not exhausted (GH-31696) (GH-31720) Co-authored-by: Serhiy Storchaka (cherry picked from commit 496c428de3318c9c5770937491b71dc3d3f18a6a) Co-authored-by: Jacob Walls files: A Misc/NEWS.d/next/Library/2022-03-05-09-43-53.bpo-25707.gTlclP.rst M Lib/test/test_xml_etree.py M Lib/xml/etree/ElementTree.py M Misc/ACKS diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index 762b0bfed2c33..0f45fc71ce773 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -640,6 +640,14 @@ def test_iterparse(self): 'junk after document element: line 1, column 12') del cm, it + # Not exhausting the iterator still closes the resource (bpo-43292) + with support.check_no_resource_warning(self): + it = iterparse(TESTFN) + del it + + with self.assertRaises(FileNotFoundError): + iterparse("nonexistent") + def test_writefile(self): elem = ET.Element("tag") elem.text = "text" diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py index fde303c875ce8..dae2251d859da 100644 --- a/Lib/xml/etree/ElementTree.py +++ b/Lib/xml/etree/ElementTree.py @@ -1248,8 +1248,14 @@ def iterparse(source, events=None, parser=None): # Use the internal, undocumented _parser argument for now; When the # parser argument of iterparse is removed, this can be killed. pullparser = XMLPullParser(events=events, _parser=parser) - def iterator(): + + def iterator(source): + close_source = False try: + if not hasattr(source, "read"): + source = open(source, "rb") + close_source = True + yield None while True: yield from pullparser.read_events() # load event buffer @@ -1265,16 +1271,12 @@ def iterator(): source.close() class IterParseIterator(collections.abc.Iterator): - __next__ = iterator().__next__ + __next__ = iterator(source).__next__ it = IterParseIterator() it.root = None del iterator, IterParseIterator - close_source = False - if not hasattr(source, "read"): - source = open(source, "rb") - close_source = True - + next(it) return it diff --git a/Misc/ACKS b/Misc/ACKS index c8d0be6999b78..2a26fdcd16b43 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1836,6 +1836,7 @@ Wojtek Walczak Charles Waldman Richard Walker Larry Wall +Jacob Walls Kevin Walzer Rodrigo Steinmuller Wanderley Dingyuan Wang diff --git a/Misc/NEWS.d/next/Library/2022-03-05-09-43-53.bpo-25707.gTlclP.rst b/Misc/NEWS.d/next/Library/2022-03-05-09-43-53.bpo-25707.gTlclP.rst new file mode 100644 index 0000000000000..a59f0a7657ff2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-05-09-43-53.bpo-25707.gTlclP.rst @@ -0,0 +1,2 @@ +Fixed a file leak in :func:`xml.etree.ElementTree.iterparse` when the +iterator is not exhausted. Patch by Jacob Walls. From webhook-mailer at python.org Mon Mar 7 07:23:16 2022 From: webhook-mailer at python.org (pablogsal) Date: Mon, 07 Mar 2022 12:23:16 -0000 Subject: [Python-checkins] bpo-46940: Don't override existing AttributeError suggestion information (GH-31710) Message-ID: https://github.com/python/cpython/commit/3b3be05a164da43f201e35b6dafbc840993a4d18 commit: 3b3be05a164da43f201e35b6dafbc840993a4d18 branch: main author: Pablo Galindo Salgado committer: pablogsal date: 2022-03-07T12:23:11Z summary: bpo-46940: Don't override existing AttributeError suggestion information (GH-31710) When an exception is created in a nested call to PyObject_GetAttr, any external calls will override the context information of the AttributeError that we have already placed in the most internal call. This will cause the suggestions we create to nor work properly as the attribute name and object that we will be using are the incorrect ones. To avoid this, we need to check first if these attributes are already set and bail out if that's the case. files: A Misc/NEWS.d/next/Core and Builtins/2022-03-06-20-16-13.bpo-46940._X47Hx.rst M Lib/test/test_exceptions.py M Objects/object.c M Python/ceval.c diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index e3897a0d89c5e..a75b7fae5518e 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -2272,6 +2272,24 @@ def test_attribute_error_with_bad_name(self): self.assertNotIn("?", err.getvalue()) + def test_attribute_error_inside_nested_getattr(self): + class A: + bluch = 1 + + class B: + def __getattribute__(self, attr): + a = A() + return a.blich + + try: + B().something + except AttributeError as exc: + with support.captured_stderr() as err: + sys.__excepthook__(*sys.exc_info()) + + self.assertIn("Did you mean", err.getvalue()) + self.assertIn("bluch", err.getvalue()) + class ImportErrorTests(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-06-20-16-13.bpo-46940._X47Hx.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-06-20-16-13.bpo-46940._X47Hx.rst new file mode 100644 index 0000000000000..fabc946019758 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-06-20-16-13.bpo-46940._X47Hx.rst @@ -0,0 +1,2 @@ +Avoid overriding :exc:`AttributeError` metadata information for nested +attribute access calls. Patch by Pablo Galindo. diff --git a/Objects/object.c b/Objects/object.c index 38919ff47a94a..f029a72dd3145 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -875,19 +875,29 @@ static inline int set_attribute_error_context(PyObject* v, PyObject* name) { assert(PyErr_Occurred()); - // Intercept AttributeError exceptions and augment them to offer - // suggestions later. - if (PyErr_ExceptionMatches(PyExc_AttributeError)){ - PyObject *type, *value, *traceback; - PyErr_Fetch(&type, &value, &traceback); - PyErr_NormalizeException(&type, &value, &traceback); - if (PyErr_GivenExceptionMatches(value, PyExc_AttributeError) && - (PyObject_SetAttr(value, &_Py_ID(name), name) || - PyObject_SetAttr(value, &_Py_ID(obj), v))) { - return 1; - } - PyErr_Restore(type, value, traceback); + if (!PyErr_ExceptionMatches(PyExc_AttributeError)){ + return 0; + } + // Intercept AttributeError exceptions and augment them to offer suggestions later. + PyObject *type, *value, *traceback; + PyErr_Fetch(&type, &value, &traceback); + PyErr_NormalizeException(&type, &value, &traceback); + // Check if the normalized exception is indeed an AttributeError + if (!PyErr_GivenExceptionMatches(value, PyExc_AttributeError)) { + goto restore; + } + PyAttributeErrorObject* the_exc = (PyAttributeErrorObject*) value; + // Check if this exception was already augmented + if (the_exc->name || the_exc->obj) { + goto restore; + } + // Augment the exception with the name and object + if (PyObject_SetAttr(value, &_Py_ID(name), name) || + PyObject_SetAttr(value, &_Py_ID(obj), v)) { + return 1; } +restore: + PyErr_Restore(type, value, traceback); return 0; } diff --git a/Python/ceval.c b/Python/ceval.c index 0743894c457a7..7439710ae47b7 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -7607,9 +7607,12 @@ format_exc_check_arg(PyThreadState *tstate, PyObject *exc, PyErr_Fetch(&type, &value, &traceback); PyErr_NormalizeException(&type, &value, &traceback); if (PyErr_GivenExceptionMatches(value, PyExc_NameError)) { - // We do not care if this fails because we are going to restore the - // NameError anyway. - (void)PyObject_SetAttr(value, &_Py_ID(name), obj); + PyNameErrorObject* exc = (PyNameErrorObject*) value; + if (exc->name == NULL) { + // We do not care if this fails because we are going to restore the + // NameError anyway. + (void)PyObject_SetAttr(value, &_Py_ID(name), obj); + } } PyErr_Restore(type, value, traceback); } From webhook-mailer at python.org Mon Mar 7 07:36:52 2022 From: webhook-mailer at python.org (tiran) Date: Mon, 07 Mar 2022 12:36:52 -0000 Subject: [Python-checkins] bpo-46933: Make pwd module optional (GH-31700) Message-ID: https://github.com/python/cpython/commit/ca9689f8dac01d27e041e1dbbdae146746d48ab3 commit: ca9689f8dac01d27e041e1dbbdae146746d48ab3 branch: main author: Christian Heimes committer: tiran date: 2022-03-07T13:36:47+01:00 summary: bpo-46933: Make pwd module optional (GH-31700) Co-authored-by: Erlend Egeberg Aasland files: A Misc/NEWS.d/next/Library/2022-03-05-21-51-31.bpo-46933.6yzWtb.rst A Modules/Setup.bootstrap.in D Modules/Setup.bootstrap M .gitignore M Lib/distutils/tests/test_util.py M Lib/posixpath.py M Lib/test/test_pathlib.py M Lib/test/test_posix.py M Makefile.pre.in M configure M configure.ac M pyconfig.h.in diff --git a/.gitignore b/.gitignore index 39de8410200ce..3c6adb4ab688c 100644 --- a/.gitignore +++ b/.gitignore @@ -75,6 +75,7 @@ Mac/pythonw Misc/python.pc Misc/python-embed.pc Misc/python-config.sh +Modules/Setup.bootstrap Modules/Setup.config Modules/Setup.local Modules/Setup.stdlib diff --git a/Lib/distutils/tests/test_util.py b/Lib/distutils/tests/test_util.py index 812d44ec9bb72..f9c223f06ec68 100644 --- a/Lib/distutils/tests/test_util.py +++ b/Lib/distutils/tests/test_util.py @@ -248,7 +248,10 @@ def test_check_environ_getpwuid(self): util._environ_checked = 0 os.environ.pop('HOME', None) - import pwd + try: + import pwd + except ImportError: + raise unittest.SkipTest("Test requires pwd module.") # only set pw_dir field, other fields are not used result = pwd.struct_passwd((None, None, None, None, None, diff --git a/Lib/posixpath.py b/Lib/posixpath.py index a46c667db5633..a7b2f2d64824f 100644 --- a/Lib/posixpath.py +++ b/Lib/posixpath.py @@ -241,7 +241,11 @@ def expanduser(path): i = len(path) if i == 1: if 'HOME' not in os.environ: - import pwd + try: + import pwd + except ImportError: + # pwd module unavailable, return path unchanged + return path try: userhome = pwd.getpwuid(os.getuid()).pw_dir except KeyError: @@ -251,7 +255,11 @@ def expanduser(path): else: userhome = os.environ['HOME'] else: - import pwd + try: + import pwd + except ImportError: + # pwd module unavailable, return path unchanged + return path name = path[1:i] if isinstance(name, bytes): name = str(name, 'ASCII') diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index f03fcbef1b0a0..713d27908e756 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -1486,6 +1486,9 @@ def _test_home(self, p): self.assertIs(type(p), type(q)) self.assertTrue(p.is_absolute()) + @unittest.skipIf( + pwd is None, reason="Test requires pwd module to get homedir." + ) def test_home(self): with os_helper.EnvironmentVarGuard() as env: self._test_home(self.cls.home()) diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 5cc04fd46dddb..eecddfed8c5c5 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -15,7 +15,6 @@ import time import os import platform -import pwd import stat import tempfile import unittest @@ -23,6 +22,11 @@ import textwrap from contextlib import contextmanager +try: + import pwd +except ImportError: + pwd = None + _DUMMY_SYMLINK = os.path.join(tempfile.gettempdir(), os_helper.TESTFN + '-dummy-symlink') @@ -126,6 +130,7 @@ def test_setresgid_exception(self): @unittest.skipUnless(hasattr(posix, 'initgroups'), "test needs os.initgroups()") + @unittest.skipUnless(hasattr(pwd, 'getpwuid'), "test needs pwd.getpwuid()") def test_initgroups(self): # It takes a string and an integer; check that it raises a TypeError # for other argument lists. diff --git a/Makefile.pre.in b/Makefile.pre.in index 7b6f54a9ae0a7..d2b1a7ce458d9 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -917,6 +917,9 @@ Modules/Setup.local: @# Create empty Setup.local when file was deleted by user echo "# Edit this file for local setup changes" > $@ +Modules/Setup.bootstrap: $(srcdir)/Modules/Setup.bootstrap.in config.status + ./config.status $@ + Modules/Setup.stdlib: $(srcdir)/Modules/Setup.stdlib.in config.status ./config.status $@ @@ -925,13 +928,13 @@ Makefile Modules/config.c: Makefile.pre \ $(MAKESETUP) \ $(srcdir)/Modules/Setup \ Modules/Setup.local \ - $(srcdir)/Modules/Setup.bootstrap \ + Modules/Setup.bootstrap \ Modules/Setup.stdlib $(SHELL) $(MAKESETUP) -c $(srcdir)/Modules/config.c.in \ -s Modules \ Modules/Setup.local \ @MODULES_SETUP_STDLIB@ \ - $(srcdir)/Modules/Setup.bootstrap \ + Modules/Setup.bootstrap \ $(srcdir)/Modules/Setup @mv config.c Modules @echo "The Makefile was updated, you may need to re-run make." @@ -2146,7 +2149,7 @@ libainstall: @DEF_MAKE_RULE@ python-config $(INSTALL_DATA) $(srcdir)/Modules/config.c.in $(DESTDIR)$(LIBPL)/config.c.in $(INSTALL_DATA) Makefile $(DESTDIR)$(LIBPL)/Makefile $(INSTALL_DATA) $(srcdir)/Modules/Setup $(DESTDIR)$(LIBPL)/Setup - $(INSTALL_DATA) $(srcdir)/Modules/Setup.bootstrap $(DESTDIR)$(LIBPL)/Setup.bootstrap + $(INSTALL_DATA) Modules/Setup.bootstrap $(DESTDIR)$(LIBPL)/Setup.bootstrap $(INSTALL_DATA) Modules/Setup.stdlib $(DESTDIR)$(LIBPL)/Setup.stdlib $(INSTALL_DATA) Modules/Setup.local $(DESTDIR)$(LIBPL)/Setup.local $(INSTALL_DATA) Misc/python.pc $(DESTDIR)$(LIBPC)/python-$(VERSION).pc @@ -2381,8 +2384,9 @@ distclean: clobber for file in $(srcdir)/Lib/test/data/* ; do \ if test "$$file" != "$(srcdir)/Lib/test/data/README"; then rm "$$file"; fi; \ done - -rm -f core Makefile Makefile.pre config.status Modules/Setup.local \ - Modules/Setup.stdlib Modules/ld_so_aix Modules/python.exp Misc/python.pc \ + -rm -f core Makefile Makefile.pre config.status Modules/Setup.local + Modules/Setup.bootstrap Modules/Setup.stdlib \ + Modules/ld_so_aix Modules/python.exp Misc/python.pc \ Misc/python-embed.pc Misc/python-config.sh -rm -f python*-gdb.py # Issue #28258: set LC_ALL to avoid issues with Estonian locale. diff --git a/Misc/NEWS.d/next/Library/2022-03-05-21-51-31.bpo-46933.6yzWtb.rst b/Misc/NEWS.d/next/Library/2022-03-05-21-51-31.bpo-46933.6yzWtb.rst new file mode 100644 index 0000000000000..c3d2e6b50c296 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-05-21-51-31.bpo-46933.6yzWtb.rst @@ -0,0 +1 @@ +The :mod:`pwd` module is now optional. :func:`os.path.expanduser` returns the path when the :mod:`pwd` module is not available. diff --git a/Modules/Setup.bootstrap b/Modules/Setup.bootstrap.in similarity index 96% rename from Modules/Setup.bootstrap rename to Modules/Setup.bootstrap.in index f23da60b37ad0..ec724978f319b 100644 --- a/Modules/Setup.bootstrap +++ b/Modules/Setup.bootstrap.in @@ -32,4 +32,4 @@ _stat _stat.c _symtable symtablemodule.c # for systems without $HOME env, used by site._getuserbase() -pwd pwdmodule.c + at MODULE_PWD_TRUE@pwd pwdmodule.c diff --git a/configure b/configure index 07ecb804c1bd0..a8e78ce73e708 100755 --- a/configure +++ b/configure @@ -708,6 +708,8 @@ MODULE__SCPROXY_FALSE MODULE__SCPROXY_TRUE MODULE_RESOURCE_FALSE MODULE_RESOURCE_TRUE +MODULE_PWD_FALSE +MODULE_PWD_TRUE MODULE_OSSAUDIODEV_FALSE MODULE_OSSAUDIODEV_TRUE MODULE_GRP_FALSE @@ -13767,7 +13769,7 @@ for ac_func in \ gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \ getgrnam_r getgrouplist getgroups getitimer getloadavg getlogin \ getpeername getpgid getpid getppid getpriority _getpty \ - getpwent getpwnam_r getpwuid_r getresgid getresuid getrusage getsid getspent \ + getpwent getpwnam_r getpwuid getpwuid_r getresgid getresuid getrusage getsid getspent \ getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \ lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \ mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \ @@ -21331,32 +21333,106 @@ $as_echo "yes" >&6; } fi + + +# stdlib not available case $ac_sys_system/$ac_sys_emscripten_target in #( AIX/*) : - py_stdlib_not_available="_scproxy spwd" ;; #( + + + py_cv_module__scproxy=n/a + py_cv_module_spwd=n/a + ;; #( VxWorks*/*) : - py_stdlib_not_available="_scproxy _crypt termios grp" ;; #( + + + py_cv_module__scproxy=n/a + py_cv_module__crypt=n/a + py_cv_module_termios=n/a + py_cv_module_grp=n/a + ;; #( Darwin/*) : - py_stdlib_not_available="ossaudiodev spwd" ;; #( + + + py_cv_module_ossaudiodev=n/a + py_cv_module_spwd=n/a + ;; #( CYGWIN*/*) : - py_stdlib_not_available="_scproxy nis" ;; #( + + + py_cv_module__scproxy=n/a + py_cv_module_nis=n/a + ;; #( QNX*/*) : - py_stdlib_not_available="_scproxy nis" ;; #( + + + py_cv_module__scproxy=n/a + py_cv_module_nis=n/a + ;; #( FreeBSD*/*) : - py_stdlib_not_available="_scproxy spwd" ;; #( + + + py_cv_module__scproxy=n/a + py_cv_module_spwd=n/a + ;; #( Emscripten/browser) : - py_stdlib_not_available="_ctypes _curses _curses_panel _dbm _gdbm _multiprocessing _posixshmem _posixsubprocess _scproxy _tkinter _xxsubinterpreters fcntl grp nis ossaudiodev resource readline spwd syslog termios" + + + py_cv_module__ctypes=n/a + py_cv_module__curses=n/a + py_cv_module__curses_panel=n/a + py_cv_module__dbm=n/a + py_cv_module__gdbm=n/a + py_cv_module__multiprocessing=n/a + py_cv_module__posixshmem=n/a + py_cv_module__posixsubprocess=n/a + py_cv_module__scproxy=n/a + py_cv_module__tkinter=n/a + py_cv_module__xxsubinterpreters=n/a + py_cv_module_fcntl=n/a + py_cv_module_grp=n/a + py_cv_module_nis=n/a + py_cv_module_ossaudiodev=n/a + py_cv_module_pwd=n/a + py_cv_module_resource=n/a + py_cv_module_readline=n/a + py_cv_module_spwd=n/a + py_cv_module_syslog=n/a + py_cv_module_termios=n/a + py_cv_module_=n/a + ;; #( Emscripten/node) : - py_stdlib_not_available="_ctypes _curses _curses_panel _dbm _gdbm _scproxy _tkinter _xxsubinterpreters grp nis ossaudiodev spwd syslog" + + + py_cv_module__ctypes=n/a + py_cv_module__curses=n/a + py_cv_module__curses_panel=n/a + py_cv_module__dbm=n/a + py_cv_module__gdbm=n/a + py_cv_module__scproxy=n/a + py_cv_module__tkinter=n/a + py_cv_module__xxsubinterpreters=n/a + py_cv_module_grp=n/a + py_cv_module_nis=n/a + py_cv_module_ossaudiodev=n/a + py_cv_module_pwd=n/a + py_cv_module_spwd=n/a + py_cv_module_syslog=n/a + py_cv_module_=n/a + ;; #( *) : - py_stdlib_not_available="_scproxy" + + + py_cv_module__scproxy=n/a + ;; esac + case $host_cpu in #( wasm32|wasm64) : MODULE_BUILDTYPE=static ;; #( @@ -21390,13 +21466,9 @@ MODULE_BLOCK= - case $py_stdlib_not_available in #( - *_io*) : - py_cv_module__io=n/a ;; #( - *) : - py_cv_module__io=yes - ;; -esac + if test "$py_cv_module__io" != "n/a"; then : + py_cv_module__io=yes +fi if test "$py_cv_module__io" = yes; then MODULE__IO_TRUE= MODULE__IO_FALSE='#' @@ -21414,13 +21486,9 @@ fi fi - case $py_stdlib_not_available in #( - *time*) : - py_cv_module_time=n/a ;; #( - *) : - py_cv_module_time=yes - ;; -esac + if test "$py_cv_module_time" != "n/a"; then : + py_cv_module_time=yes +fi if test "$py_cv_module_time" = yes; then MODULE_TIME_TRUE= MODULE_TIME_FALSE='#' @@ -21439,13 +21507,9 @@ fi - case $py_stdlib_not_available in #( - *array*) : - py_cv_module_array=n/a ;; #( - *) : - py_cv_module_array=yes - ;; -esac + if test "$py_cv_module_array" != "n/a"; then : + py_cv_module_array=yes +fi if test "$py_cv_module_array" = yes; then MODULE_ARRAY_TRUE= MODULE_ARRAY_FALSE='#' @@ -21463,13 +21527,9 @@ fi fi - case $py_stdlib_not_available in #( - *_asyncio*) : - py_cv_module__asyncio=n/a ;; #( - *) : - py_cv_module__asyncio=yes - ;; -esac + if test "$py_cv_module__asyncio" != "n/a"; then : + py_cv_module__asyncio=yes +fi if test "$py_cv_module__asyncio" = yes; then MODULE__ASYNCIO_TRUE= MODULE__ASYNCIO_FALSE='#' @@ -21487,13 +21547,9 @@ fi fi - case $py_stdlib_not_available in #( - *_bisect*) : - py_cv_module__bisect=n/a ;; #( - *) : - py_cv_module__bisect=yes - ;; -esac + if test "$py_cv_module__bisect" != "n/a"; then : + py_cv_module__bisect=yes +fi if test "$py_cv_module__bisect" = yes; then MODULE__BISECT_TRUE= MODULE__BISECT_FALSE='#' @@ -21511,13 +21567,9 @@ fi fi - case $py_stdlib_not_available in #( - *_contextvars*) : - py_cv_module__contextvars=n/a ;; #( - *) : - py_cv_module__contextvars=yes - ;; -esac + if test "$py_cv_module__contextvars" != "n/a"; then : + py_cv_module__contextvars=yes +fi if test "$py_cv_module__contextvars" = yes; then MODULE__CONTEXTVARS_TRUE= MODULE__CONTEXTVARS_FALSE='#' @@ -21535,13 +21587,9 @@ fi fi - case $py_stdlib_not_available in #( - *_csv*) : - py_cv_module__csv=n/a ;; #( - *) : - py_cv_module__csv=yes - ;; -esac + if test "$py_cv_module__csv" != "n/a"; then : + py_cv_module__csv=yes +fi if test "$py_cv_module__csv" = yes; then MODULE__CSV_TRUE= MODULE__CSV_FALSE='#' @@ -21559,13 +21607,9 @@ fi fi - case $py_stdlib_not_available in #( - *_heapq*) : - py_cv_module__heapq=n/a ;; #( - *) : - py_cv_module__heapq=yes - ;; -esac + if test "$py_cv_module__heapq" != "n/a"; then : + py_cv_module__heapq=yes +fi if test "$py_cv_module__heapq" = yes; then MODULE__HEAPQ_TRUE= MODULE__HEAPQ_FALSE='#' @@ -21583,13 +21627,9 @@ fi fi - case $py_stdlib_not_available in #( - *_json*) : - py_cv_module__json=n/a ;; #( - *) : - py_cv_module__json=yes - ;; -esac + if test "$py_cv_module__json" != "n/a"; then : + py_cv_module__json=yes +fi if test "$py_cv_module__json" = yes; then MODULE__JSON_TRUE= MODULE__JSON_FALSE='#' @@ -21607,13 +21647,9 @@ fi fi - case $py_stdlib_not_available in #( - *_lsprof*) : - py_cv_module__lsprof=n/a ;; #( - *) : - py_cv_module__lsprof=yes - ;; -esac + if test "$py_cv_module__lsprof" != "n/a"; then : + py_cv_module__lsprof=yes +fi if test "$py_cv_module__lsprof" = yes; then MODULE__LSPROF_TRUE= MODULE__LSPROF_FALSE='#' @@ -21631,13 +21667,9 @@ fi fi - case $py_stdlib_not_available in #( - *_opcode*) : - py_cv_module__opcode=n/a ;; #( - *) : - py_cv_module__opcode=yes - ;; -esac + if test "$py_cv_module__opcode" != "n/a"; then : + py_cv_module__opcode=yes +fi if test "$py_cv_module__opcode" = yes; then MODULE__OPCODE_TRUE= MODULE__OPCODE_FALSE='#' @@ -21655,13 +21687,9 @@ fi fi - case $py_stdlib_not_available in #( - *_pickle*) : - py_cv_module__pickle=n/a ;; #( - *) : - py_cv_module__pickle=yes - ;; -esac + if test "$py_cv_module__pickle" != "n/a"; then : + py_cv_module__pickle=yes +fi if test "$py_cv_module__pickle" = yes; then MODULE__PICKLE_TRUE= MODULE__PICKLE_FALSE='#' @@ -21679,13 +21707,9 @@ fi fi - case $py_stdlib_not_available in #( - *_posixsubprocess*) : - py_cv_module__posixsubprocess=n/a ;; #( - *) : - py_cv_module__posixsubprocess=yes - ;; -esac + if test "$py_cv_module__posixsubprocess" != "n/a"; then : + py_cv_module__posixsubprocess=yes +fi if test "$py_cv_module__posixsubprocess" = yes; then MODULE__POSIXSUBPROCESS_TRUE= MODULE__POSIXSUBPROCESS_FALSE='#' @@ -21703,13 +21727,9 @@ fi fi - case $py_stdlib_not_available in #( - *_queue*) : - py_cv_module__queue=n/a ;; #( - *) : - py_cv_module__queue=yes - ;; -esac + if test "$py_cv_module__queue" != "n/a"; then : + py_cv_module__queue=yes +fi if test "$py_cv_module__queue" = yes; then MODULE__QUEUE_TRUE= MODULE__QUEUE_FALSE='#' @@ -21727,13 +21747,9 @@ fi fi - case $py_stdlib_not_available in #( - *_random*) : - py_cv_module__random=n/a ;; #( - *) : - py_cv_module__random=yes - ;; -esac + if test "$py_cv_module__random" != "n/a"; then : + py_cv_module__random=yes +fi if test "$py_cv_module__random" = yes; then MODULE__RANDOM_TRUE= MODULE__RANDOM_FALSE='#' @@ -21751,13 +21767,9 @@ fi fi - case $py_stdlib_not_available in #( - *select*) : - py_cv_module_select=n/a ;; #( - *) : - py_cv_module_select=yes - ;; -esac + if test "$py_cv_module_select" != "n/a"; then : + py_cv_module_select=yes +fi if test "$py_cv_module_select" = yes; then MODULE_SELECT_TRUE= MODULE_SELECT_FALSE='#' @@ -21775,13 +21787,9 @@ fi fi - case $py_stdlib_not_available in #( - *_struct*) : - py_cv_module__struct=n/a ;; #( - *) : - py_cv_module__struct=yes - ;; -esac + if test "$py_cv_module__struct" != "n/a"; then : + py_cv_module__struct=yes +fi if test "$py_cv_module__struct" = yes; then MODULE__STRUCT_TRUE= MODULE__STRUCT_FALSE='#' @@ -21799,13 +21807,9 @@ fi fi - case $py_stdlib_not_available in #( - *_typing*) : - py_cv_module__typing=n/a ;; #( - *) : - py_cv_module__typing=yes - ;; -esac + if test "$py_cv_module__typing" != "n/a"; then : + py_cv_module__typing=yes +fi if test "$py_cv_module__typing" = yes; then MODULE__TYPING_TRUE= MODULE__TYPING_FALSE='#' @@ -21823,13 +21827,9 @@ fi fi - case $py_stdlib_not_available in #( - *_xxsubinterpreters*) : - py_cv_module__xxsubinterpreters=n/a ;; #( - *) : - py_cv_module__xxsubinterpreters=yes - ;; -esac + if test "$py_cv_module__xxsubinterpreters" != "n/a"; then : + py_cv_module__xxsubinterpreters=yes +fi if test "$py_cv_module__xxsubinterpreters" = yes; then MODULE__XXSUBINTERPRETERS_TRUE= MODULE__XXSUBINTERPRETERS_FALSE='#' @@ -21847,13 +21847,9 @@ fi fi - case $py_stdlib_not_available in #( - *_zoneinfo*) : - py_cv_module__zoneinfo=n/a ;; #( - *) : - py_cv_module__zoneinfo=yes - ;; -esac + if test "$py_cv_module__zoneinfo" != "n/a"; then : + py_cv_module__zoneinfo=yes +fi if test "$py_cv_module__zoneinfo" = yes; then MODULE__ZONEINFO_TRUE= MODULE__ZONEINFO_FALSE='#' @@ -21874,10 +21870,8 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _multiprocessing" >&5 $as_echo_n "checking for stdlib extension module _multiprocessing... " >&6; } - case $py_stdlib_not_available in #( - *_multiprocessing*) : - py_cv_module__multiprocessing=n/a ;; #( - *) : + if test "$py_cv_module__multiprocessing" != "n/a"; then : + if true; then : if test "$ac_cv_func_sem_unlink" = "yes"; then : py_cv_module__multiprocessing=yes @@ -21887,8 +21881,8 @@ fi else py_cv_module__multiprocessing=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__MULTIPROCESSING=$py_cv_module__multiprocessing$as_nl" if test "x$py_cv_module__multiprocessing" = xyes; then : @@ -21910,10 +21904,8 @@ $as_echo "$py_cv_module__multiprocessing" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _posixshmem" >&5 $as_echo_n "checking for stdlib extension module _posixshmem... " >&6; } - case $py_stdlib_not_available in #( - *_posixshmem*) : - py_cv_module__posixshmem=n/a ;; #( - *) : + if test "$py_cv_module__posixshmem" != "n/a"; then : + if true; then : if test "$have_posix_shmem" = "yes"; then : py_cv_module__posixshmem=yes @@ -21923,8 +21915,8 @@ fi else py_cv_module__posixshmem=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__POSIXSHMEM=$py_cv_module__posixshmem$as_nl" if test "x$py_cv_module__posixshmem" = xyes; then : @@ -21945,13 +21937,9 @@ $as_echo "$py_cv_module__posixshmem" >&6; } - case $py_stdlib_not_available in #( - *audioop*) : - py_cv_module_audioop=n/a ;; #( - *) : - py_cv_module_audioop=yes - ;; -esac + if test "$py_cv_module_audioop" != "n/a"; then : + py_cv_module_audioop=yes +fi if test "$py_cv_module_audioop" = yes; then MODULE_AUDIOOP_TRUE= MODULE_AUDIOOP_FALSE='#' @@ -21969,13 +21957,9 @@ fi fi - case $py_stdlib_not_available in #( - *_statistics*) : - py_cv_module__statistics=n/a ;; #( - *) : - py_cv_module__statistics=yes - ;; -esac + if test "$py_cv_module__statistics" != "n/a"; then : + py_cv_module__statistics=yes +fi if test "$py_cv_module__statistics" = yes; then MODULE__STATISTICS_TRUE= MODULE__STATISTICS_FALSE='#' @@ -21993,13 +21977,9 @@ fi fi - case $py_stdlib_not_available in #( - *cmath*) : - py_cv_module_cmath=n/a ;; #( - *) : - py_cv_module_cmath=yes - ;; -esac + if test "$py_cv_module_cmath" != "n/a"; then : + py_cv_module_cmath=yes +fi if test "$py_cv_module_cmath" = yes; then MODULE_CMATH_TRUE= MODULE_CMATH_FALSE='#' @@ -22017,13 +21997,9 @@ fi fi - case $py_stdlib_not_available in #( - *math*) : - py_cv_module_math=n/a ;; #( - *) : - py_cv_module_math=yes - ;; -esac + if test "$py_cv_module_math" != "n/a"; then : + py_cv_module_math=yes +fi if test "$py_cv_module_math" = yes; then MODULE_MATH_TRUE= MODULE_MATH_FALSE='#' @@ -22042,13 +22018,9 @@ fi - case $py_stdlib_not_available in #( - *_datetime*) : - py_cv_module__datetime=n/a ;; #( - *) : - py_cv_module__datetime=yes - ;; -esac + if test "$py_cv_module__datetime" != "n/a"; then : + py_cv_module__datetime=yes +fi if test "$py_cv_module__datetime" = yes; then MODULE__DATETIME_TRUE= MODULE__DATETIME_FALSE='#' @@ -22069,10 +22041,8 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module fcntl" >&5 $as_echo_n "checking for stdlib extension module fcntl... " >&6; } - case $py_stdlib_not_available in #( - *fcntl*) : - py_cv_module_fcntl=n/a ;; #( - *) : + if test "$py_cv_module_fcntl" != "n/a"; then : + if true; then : if test "$ac_cv_header_sys_ioctl_h" = "yes" -a "$ac_cv_header_fcntl_h" = "yes"; then : py_cv_module_fcntl=yes @@ -22082,8 +22052,8 @@ fi else py_cv_module_fcntl=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE_FCNTL=$py_cv_module_fcntl$as_nl" if test "x$py_cv_module_fcntl" = xyes; then : @@ -22105,10 +22075,8 @@ $as_echo "$py_cv_module_fcntl" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module mmap" >&5 $as_echo_n "checking for stdlib extension module mmap... " >&6; } - case $py_stdlib_not_available in #( - *mmap*) : - py_cv_module_mmap=n/a ;; #( - *) : + if test "$py_cv_module_mmap" != "n/a"; then : + if true; then : if test "$ac_cv_header_sys_mman_h" = "yes" -a "$ac_cv_header_sys_stat_h" = "yes"; then : py_cv_module_mmap=yes @@ -22118,8 +22086,8 @@ fi else py_cv_module_mmap=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE_MMAP=$py_cv_module_mmap$as_nl" if test "x$py_cv_module_mmap" = xyes; then : @@ -22141,10 +22109,8 @@ $as_echo "$py_cv_module_mmap" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _socket" >&5 $as_echo_n "checking for stdlib extension module _socket... " >&6; } - case $py_stdlib_not_available in #( - *_socket*) : - py_cv_module__socket=n/a ;; #( - *) : + if test "$py_cv_module__socket" != "n/a"; then : + if true; then : if test "$ac_cv_header_sys_socket_h" = "yes" -a "$ac_cv_header_sys_types_h" = "yes" -a "$ac_cv_header_netinet_in_h" = "yes"; then : py_cv_module__socket=yes @@ -22154,8 +22120,8 @@ fi else py_cv_module__socket=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__SOCKET=$py_cv_module__socket$as_nl" if test "x$py_cv_module__socket" = xyes; then : @@ -22178,10 +22144,8 @@ $as_echo "$py_cv_module__socket" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module grp" >&5 $as_echo_n "checking for stdlib extension module grp... " >&6; } - case $py_stdlib_not_available in #( - *grp*) : - py_cv_module_grp=n/a ;; #( - *) : + if test "$py_cv_module_grp" != "n/a"; then : + if true; then : if test "$ac_cv_func_getgrgid" = yes -o "$ac_cv_func_getgrgid_r" = yes; then : py_cv_module_grp=yes @@ -22191,8 +22155,8 @@ fi else py_cv_module_grp=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE_GRP=$py_cv_module_grp$as_nl" if test "x$py_cv_module_grp" = xyes; then : @@ -22214,10 +22178,8 @@ $as_echo "$py_cv_module_grp" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module ossaudiodev" >&5 $as_echo_n "checking for stdlib extension module ossaudiodev... " >&6; } - case $py_stdlib_not_available in #( - *ossaudiodev*) : - py_cv_module_ossaudiodev=n/a ;; #( - *) : + if test "$py_cv_module_ossaudiodev" != "n/a"; then : + if true; then : if test "$ac_cv_header_linux_soundcard_h" = yes -o "$ac_cv_header_sys_soundcard_h" = yes; then : py_cv_module_ossaudiodev=yes @@ -22227,8 +22189,8 @@ fi else py_cv_module_ossaudiodev=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE_OSSAUDIODEV=$py_cv_module_ossaudiodev$as_nl" if test "x$py_cv_module_ossaudiodev" = xyes; then : @@ -22248,12 +22210,44 @@ fi $as_echo "$py_cv_module_ossaudiodev" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module pwd" >&5 +$as_echo_n "checking for stdlib extension module pwd... " >&6; } + if test "$py_cv_module_pwd" != "n/a"; then : + + if true; then : + if test "$ac_cv_func_getpwuid" = yes -o "$ac_cv_func_getpwuid_r" = yes; then : + py_cv_module_pwd=yes +else + py_cv_module_pwd=missing +fi +else + py_cv_module_pwd=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE_PWD=$py_cv_module_pwd$as_nl" + if test "x$py_cv_module_pwd" = xyes; then : + + + + +fi + if test "$py_cv_module_pwd" = yes; then + MODULE_PWD_TRUE= + MODULE_PWD_FALSE='#' +else + MODULE_PWD_TRUE='#' + MODULE_PWD_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_pwd" >&5 +$as_echo "$py_cv_module_pwd" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module resource" >&5 $as_echo_n "checking for stdlib extension module resource... " >&6; } - case $py_stdlib_not_available in #( - *resource*) : - py_cv_module_resource=n/a ;; #( - *) : + if test "$py_cv_module_resource" != "n/a"; then : + if true; then : if test "$ac_cv_header_sys_resource_h" = yes; then : py_cv_module_resource=yes @@ -22263,8 +22257,8 @@ fi else py_cv_module_resource=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE_RESOURCE=$py_cv_module_resource$as_nl" if test "x$py_cv_module_resource" = xyes; then : @@ -22286,10 +22280,8 @@ $as_echo "$py_cv_module_resource" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _scproxy" >&5 $as_echo_n "checking for stdlib extension module _scproxy... " >&6; } - case $py_stdlib_not_available in #( - *_scproxy*) : - py_cv_module__scproxy=n/a ;; #( - *) : + if test "$py_cv_module__scproxy" != "n/a"; then : + if test "$ac_sys_system" = "Darwin"; then : if true; then : py_cv_module__scproxy=yes @@ -22299,8 +22291,8 @@ fi else py_cv_module__scproxy=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__SCPROXY=$py_cv_module__scproxy$as_nl" if test "x$py_cv_module__scproxy" = xyes; then : @@ -22322,10 +22314,8 @@ $as_echo "$py_cv_module__scproxy" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module spwd" >&5 $as_echo_n "checking for stdlib extension module spwd... " >&6; } - case $py_stdlib_not_available in #( - *spwd*) : - py_cv_module_spwd=n/a ;; #( - *) : + if test "$py_cv_module_spwd" != "n/a"; then : + if true; then : if test "$ac_cv_func_getspent" = yes -o "$ac_cv_func_getspnam" = yes; then : py_cv_module_spwd=yes @@ -22335,8 +22325,8 @@ fi else py_cv_module_spwd=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE_SPWD=$py_cv_module_spwd$as_nl" if test "x$py_cv_module_spwd" = xyes; then : @@ -22358,10 +22348,8 @@ $as_echo "$py_cv_module_spwd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module syslog" >&5 $as_echo_n "checking for stdlib extension module syslog... " >&6; } - case $py_stdlib_not_available in #( - *syslog*) : - py_cv_module_syslog=n/a ;; #( - *) : + if test "$py_cv_module_syslog" != "n/a"; then : + if true; then : if test "$ac_cv_header_syslog_h" = yes; then : py_cv_module_syslog=yes @@ -22371,8 +22359,8 @@ fi else py_cv_module_syslog=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE_SYSLOG=$py_cv_module_syslog$as_nl" if test "x$py_cv_module_syslog" = xyes; then : @@ -22394,10 +22382,8 @@ $as_echo "$py_cv_module_syslog" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module termios" >&5 $as_echo_n "checking for stdlib extension module termios... " >&6; } - case $py_stdlib_not_available in #( - *termios*) : - py_cv_module_termios=n/a ;; #( - *) : + if test "$py_cv_module_termios" != "n/a"; then : + if true; then : if test "$ac_cv_header_termios_h" = yes; then : py_cv_module_termios=yes @@ -22407,8 +22393,8 @@ fi else py_cv_module_termios=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE_TERMIOS=$py_cv_module_termios$as_nl" if test "x$py_cv_module_termios" = xyes; then : @@ -22431,10 +22417,8 @@ $as_echo "$py_cv_module_termios" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module pyexpat" >&5 $as_echo_n "checking for stdlib extension module pyexpat... " >&6; } - case $py_stdlib_not_available in #( - *pyexpat*) : - py_cv_module_pyexpat=n/a ;; #( - *) : + if test "$py_cv_module_pyexpat" != "n/a"; then : + if true; then : if true; then : py_cv_module_pyexpat=yes @@ -22444,8 +22428,8 @@ fi else py_cv_module_pyexpat=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE_PYEXPAT=$py_cv_module_pyexpat$as_nl" if test "x$py_cv_module_pyexpat" = xyes; then : @@ -22467,10 +22451,8 @@ $as_echo "$py_cv_module_pyexpat" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _elementtree" >&5 $as_echo_n "checking for stdlib extension module _elementtree... " >&6; } - case $py_stdlib_not_available in #( - *_elementtree*) : - py_cv_module__elementtree=n/a ;; #( - *) : + if test "$py_cv_module__elementtree" != "n/a"; then : + if true; then : if true; then : py_cv_module__elementtree=yes @@ -22480,8 +22462,8 @@ fi else py_cv_module__elementtree=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__ELEMENTTREE=$py_cv_module__elementtree$as_nl" if test "x$py_cv_module__elementtree" = xyes; then : @@ -22501,13 +22483,9 @@ fi $as_echo "$py_cv_module__elementtree" >&6; } - case $py_stdlib_not_available in #( - *_codecs_cn*) : - py_cv_module__codecs_cn=n/a ;; #( - *) : - py_cv_module__codecs_cn=yes - ;; -esac + if test "$py_cv_module__codecs_cn" != "n/a"; then : + py_cv_module__codecs_cn=yes +fi if test "$py_cv_module__codecs_cn" = yes; then MODULE__CODECS_CN_TRUE= MODULE__CODECS_CN_FALSE='#' @@ -22525,13 +22503,9 @@ fi fi - case $py_stdlib_not_available in #( - *_codecs_hk*) : - py_cv_module__codecs_hk=n/a ;; #( - *) : - py_cv_module__codecs_hk=yes - ;; -esac + if test "$py_cv_module__codecs_hk" != "n/a"; then : + py_cv_module__codecs_hk=yes +fi if test "$py_cv_module__codecs_hk" = yes; then MODULE__CODECS_HK_TRUE= MODULE__CODECS_HK_FALSE='#' @@ -22549,13 +22523,9 @@ fi fi - case $py_stdlib_not_available in #( - *_codecs_iso2022*) : - py_cv_module__codecs_iso2022=n/a ;; #( - *) : - py_cv_module__codecs_iso2022=yes - ;; -esac + if test "$py_cv_module__codecs_iso2022" != "n/a"; then : + py_cv_module__codecs_iso2022=yes +fi if test "$py_cv_module__codecs_iso2022" = yes; then MODULE__CODECS_ISO2022_TRUE= MODULE__CODECS_ISO2022_FALSE='#' @@ -22573,13 +22543,9 @@ fi fi - case $py_stdlib_not_available in #( - *_codecs_jp*) : - py_cv_module__codecs_jp=n/a ;; #( - *) : - py_cv_module__codecs_jp=yes - ;; -esac + if test "$py_cv_module__codecs_jp" != "n/a"; then : + py_cv_module__codecs_jp=yes +fi if test "$py_cv_module__codecs_jp" = yes; then MODULE__CODECS_JP_TRUE= MODULE__CODECS_JP_FALSE='#' @@ -22597,13 +22563,9 @@ fi fi - case $py_stdlib_not_available in #( - *_codecs_kr*) : - py_cv_module__codecs_kr=n/a ;; #( - *) : - py_cv_module__codecs_kr=yes - ;; -esac + if test "$py_cv_module__codecs_kr" != "n/a"; then : + py_cv_module__codecs_kr=yes +fi if test "$py_cv_module__codecs_kr" = yes; then MODULE__CODECS_KR_TRUE= MODULE__CODECS_KR_FALSE='#' @@ -22621,13 +22583,9 @@ fi fi - case $py_stdlib_not_available in #( - *_codecs_tw*) : - py_cv_module__codecs_tw=n/a ;; #( - *) : - py_cv_module__codecs_tw=yes - ;; -esac + if test "$py_cv_module__codecs_tw" != "n/a"; then : + py_cv_module__codecs_tw=yes +fi if test "$py_cv_module__codecs_tw" = yes; then MODULE__CODECS_TW_TRUE= MODULE__CODECS_TW_FALSE='#' @@ -22645,13 +22603,9 @@ fi fi - case $py_stdlib_not_available in #( - *_multibytecodec*) : - py_cv_module__multibytecodec=n/a ;; #( - *) : - py_cv_module__multibytecodec=yes - ;; -esac + if test "$py_cv_module__multibytecodec" != "n/a"; then : + py_cv_module__multibytecodec=yes +fi if test "$py_cv_module__multibytecodec" = yes; then MODULE__MULTIBYTECODEC_TRUE= MODULE__MULTIBYTECODEC_FALSE='#' @@ -22669,13 +22623,9 @@ fi fi - case $py_stdlib_not_available in #( - *unicodedata*) : - py_cv_module_unicodedata=n/a ;; #( - *) : - py_cv_module_unicodedata=yes - ;; -esac + if test "$py_cv_module_unicodedata" != "n/a"; then : + py_cv_module_unicodedata=yes +fi if test "$py_cv_module_unicodedata" = yes; then MODULE_UNICODEDATA_TRUE= MODULE_UNICODEDATA_FALSE='#' @@ -22696,10 +22646,8 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _md5" >&5 $as_echo_n "checking for stdlib extension module _md5... " >&6; } - case $py_stdlib_not_available in #( - *_md5*) : - py_cv_module__md5=n/a ;; #( - *) : + if test "$py_cv_module__md5" != "n/a"; then : + if test "$with_builtin_md5" = yes; then : if true; then : py_cv_module__md5=yes @@ -22709,8 +22657,8 @@ fi else py_cv_module__md5=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__MD5=$py_cv_module__md5$as_nl" if test "x$py_cv_module__md5" = xyes; then : @@ -22732,10 +22680,8 @@ $as_echo "$py_cv_module__md5" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _sha1" >&5 $as_echo_n "checking for stdlib extension module _sha1... " >&6; } - case $py_stdlib_not_available in #( - *_sha1*) : - py_cv_module__sha1=n/a ;; #( - *) : + if test "$py_cv_module__sha1" != "n/a"; then : + if test "$with_builtin_sha1" = yes; then : if true; then : py_cv_module__sha1=yes @@ -22745,8 +22691,8 @@ fi else py_cv_module__sha1=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__SHA1=$py_cv_module__sha1$as_nl" if test "x$py_cv_module__sha1" = xyes; then : @@ -22768,10 +22714,8 @@ $as_echo "$py_cv_module__sha1" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _sha256" >&5 $as_echo_n "checking for stdlib extension module _sha256... " >&6; } - case $py_stdlib_not_available in #( - *_sha256*) : - py_cv_module__sha256=n/a ;; #( - *) : + if test "$py_cv_module__sha256" != "n/a"; then : + if test "$with_builtin_sha256" = yes; then : if true; then : py_cv_module__sha256=yes @@ -22781,8 +22725,8 @@ fi else py_cv_module__sha256=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__SHA256=$py_cv_module__sha256$as_nl" if test "x$py_cv_module__sha256" = xyes; then : @@ -22804,10 +22748,8 @@ $as_echo "$py_cv_module__sha256" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _sha512" >&5 $as_echo_n "checking for stdlib extension module _sha512... " >&6; } - case $py_stdlib_not_available in #( - *_sha512*) : - py_cv_module__sha512=n/a ;; #( - *) : + if test "$py_cv_module__sha512" != "n/a"; then : + if test "$with_builtin_sha512" = yes; then : if true; then : py_cv_module__sha512=yes @@ -22817,8 +22759,8 @@ fi else py_cv_module__sha512=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__SHA512=$py_cv_module__sha512$as_nl" if test "x$py_cv_module__sha512" = xyes; then : @@ -22840,10 +22782,8 @@ $as_echo "$py_cv_module__sha512" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _sha3" >&5 $as_echo_n "checking for stdlib extension module _sha3... " >&6; } - case $py_stdlib_not_available in #( - *_sha3*) : - py_cv_module__sha3=n/a ;; #( - *) : + if test "$py_cv_module__sha3" != "n/a"; then : + if test "$with_builtin_sha3" = yes; then : if true; then : py_cv_module__sha3=yes @@ -22853,8 +22793,8 @@ fi else py_cv_module__sha3=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__SHA3=$py_cv_module__sha3$as_nl" if test "x$py_cv_module__sha3" = xyes; then : @@ -22876,10 +22816,8 @@ $as_echo "$py_cv_module__sha3" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _blake2" >&5 $as_echo_n "checking for stdlib extension module _blake2... " >&6; } - case $py_stdlib_not_available in #( - *_blake2*) : - py_cv_module__blake2=n/a ;; #( - *) : + if test "$py_cv_module__blake2" != "n/a"; then : + if test "$with_builtin_blake2" = yes; then : if true; then : py_cv_module__blake2=yes @@ -22889,8 +22827,8 @@ fi else py_cv_module__blake2=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__BLAKE2=$py_cv_module__blake2$as_nl" if test "x$py_cv_module__blake2" = xyes; then : @@ -22913,10 +22851,8 @@ $as_echo "$py_cv_module__blake2" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _crypt" >&5 $as_echo_n "checking for stdlib extension module _crypt... " >&6; } - case $py_stdlib_not_available in #( - *_crypt*) : - py_cv_module__crypt=n/a ;; #( - *) : + if test "$py_cv_module__crypt" != "n/a"; then : + if true; then : if test "$ac_cv_crypt_crypt" = yes; then : py_cv_module__crypt=yes @@ -22926,8 +22862,8 @@ fi else py_cv_module__crypt=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__CRYPT=$py_cv_module__crypt$as_nl" if test "x$py_cv_module__crypt" = xyes; then : @@ -22949,10 +22885,8 @@ $as_echo "$py_cv_module__crypt" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _decimal" >&5 $as_echo_n "checking for stdlib extension module _decimal... " >&6; } - case $py_stdlib_not_available in #( - *_decimal*) : - py_cv_module__decimal=n/a ;; #( - *) : + if test "$py_cv_module__decimal" != "n/a"; then : + if true; then : if true; then : py_cv_module__decimal=yes @@ -22962,8 +22896,8 @@ fi else py_cv_module__decimal=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__DECIMAL=$py_cv_module__decimal$as_nl" if test "x$py_cv_module__decimal" = xyes; then : @@ -22985,10 +22919,8 @@ $as_echo "$py_cv_module__decimal" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _gdbm" >&5 $as_echo_n "checking for stdlib extension module _gdbm... " >&6; } - case $py_stdlib_not_available in #( - *_gdbm*) : - py_cv_module__gdbm=n/a ;; #( - *) : + if test "$py_cv_module__gdbm" != "n/a"; then : + if test "$have_gdbm_dbmliborder" = yes; then : if test "$have_gdbm" = yes; then : py_cv_module__gdbm=yes @@ -22998,8 +22930,8 @@ fi else py_cv_module__gdbm=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__GDBM=$py_cv_module__gdbm$as_nl" if test "x$py_cv_module__gdbm" = xyes; then : @@ -23021,10 +22953,8 @@ $as_echo "$py_cv_module__gdbm" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module nis" >&5 $as_echo_n "checking for stdlib extension module nis... " >&6; } - case $py_stdlib_not_available in #( - *nis*) : - py_cv_module_nis=n/a ;; #( - *) : + if test "$py_cv_module_nis" != "n/a"; then : + if true; then : if test "$have_nis" = yes -a "$ac_cv_header_rpc_rpc_h" = yes; then : py_cv_module_nis=yes @@ -23034,8 +22964,8 @@ fi else py_cv_module_nis=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE_NIS=$py_cv_module_nis$as_nl" if test "x$py_cv_module_nis" = xyes; then : @@ -23057,10 +22987,8 @@ $as_echo "$py_cv_module_nis" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _sqlite3" >&5 $as_echo_n "checking for stdlib extension module _sqlite3... " >&6; } - case $py_stdlib_not_available in #( - *_sqlite3*) : - py_cv_module__sqlite3=n/a ;; #( - *) : + if test "$py_cv_module__sqlite3" != "n/a"; then : + if test "$have_sqlite3" = "yes"; then : if test "$have_supported_sqlite3" = "yes"; then : py_cv_module__sqlite3=yes @@ -23070,8 +22998,8 @@ fi else py_cv_module__sqlite3=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__SQLITE3=$py_cv_module__sqlite3$as_nl" if test "x$py_cv_module__sqlite3" = xyes; then : @@ -23093,10 +23021,8 @@ $as_echo "$py_cv_module__sqlite3" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _uuid" >&5 $as_echo_n "checking for stdlib extension module _uuid... " >&6; } - case $py_stdlib_not_available in #( - *_uuid*) : - py_cv_module__uuid=n/a ;; #( - *) : + if test "$py_cv_module__uuid" != "n/a"; then : + if true; then : if test "$have_uuid" = "yes"; then : py_cv_module__uuid=yes @@ -23106,8 +23032,8 @@ fi else py_cv_module__uuid=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__UUID=$py_cv_module__uuid$as_nl" if test "x$py_cv_module__uuid" = xyes; then : @@ -23130,10 +23056,8 @@ $as_echo "$py_cv_module__uuid" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module zlib" >&5 $as_echo_n "checking for stdlib extension module zlib... " >&6; } - case $py_stdlib_not_available in #( - *zlib*) : - py_cv_module_zlib=n/a ;; #( - *) : + if test "$py_cv_module_zlib" != "n/a"; then : + if true; then : if test "$have_zlib" = yes; then : py_cv_module_zlib=yes @@ -23143,8 +23067,8 @@ fi else py_cv_module_zlib=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE_ZLIB=$py_cv_module_zlib$as_nl" if test "x$py_cv_module_zlib" = xyes; then : @@ -23164,13 +23088,9 @@ fi $as_echo "$py_cv_module_zlib" >&6; } - case $py_stdlib_not_available in #( - *binascii*) : - py_cv_module_binascii=n/a ;; #( - *) : - py_cv_module_binascii=yes - ;; -esac + if test "$py_cv_module_binascii" != "n/a"; then : + py_cv_module_binascii=yes +fi if test "$py_cv_module_binascii" = yes; then MODULE_BINASCII_TRUE= MODULE_BINASCII_FALSE='#' @@ -23190,10 +23110,8 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _bz2" >&5 $as_echo_n "checking for stdlib extension module _bz2... " >&6; } - case $py_stdlib_not_available in #( - *_bz2*) : - py_cv_module__bz2=n/a ;; #( - *) : + if test "$py_cv_module__bz2" != "n/a"; then : + if true; then : if test "$have_bzip2" = yes; then : py_cv_module__bz2=yes @@ -23203,8 +23121,8 @@ fi else py_cv_module__bz2=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__BZ2=$py_cv_module__bz2$as_nl" if test "x$py_cv_module__bz2" = xyes; then : @@ -23226,10 +23144,8 @@ $as_echo "$py_cv_module__bz2" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _lzma" >&5 $as_echo_n "checking for stdlib extension module _lzma... " >&6; } - case $py_stdlib_not_available in #( - *_lzma*) : - py_cv_module__lzma=n/a ;; #( - *) : + if test "$py_cv_module__lzma" != "n/a"; then : + if true; then : if test "$have_liblzma" = yes; then : py_cv_module__lzma=yes @@ -23239,8 +23155,8 @@ fi else py_cv_module__lzma=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__LZMA=$py_cv_module__lzma$as_nl" if test "x$py_cv_module__lzma" = xyes; then : @@ -23263,10 +23179,8 @@ $as_echo "$py_cv_module__lzma" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _ssl" >&5 $as_echo_n "checking for stdlib extension module _ssl... " >&6; } - case $py_stdlib_not_available in #( - *_ssl*) : - py_cv_module__ssl=n/a ;; #( - *) : + if test "$py_cv_module__ssl" != "n/a"; then : + if true; then : if test "$ac_cv_working_openssl_ssl" = yes; then : py_cv_module__ssl=yes @@ -23276,8 +23190,8 @@ fi else py_cv_module__ssl=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__SSL=$py_cv_module__ssl$as_nl" if test "x$py_cv_module__ssl" = xyes; then : @@ -23299,10 +23213,8 @@ $as_echo "$py_cv_module__ssl" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _hashlib" >&5 $as_echo_n "checking for stdlib extension module _hashlib... " >&6; } - case $py_stdlib_not_available in #( - *_hashlib*) : - py_cv_module__hashlib=n/a ;; #( - *) : + if test "$py_cv_module__hashlib" != "n/a"; then : + if true; then : if test "$ac_cv_working_openssl_hashlib" = yes; then : py_cv_module__hashlib=yes @@ -23312,8 +23224,8 @@ fi else py_cv_module__hashlib=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__HASHLIB=$py_cv_module__hashlib$as_nl" if test "x$py_cv_module__hashlib" = xyes; then : @@ -23336,10 +23248,8 @@ $as_echo "$py_cv_module__hashlib" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testcapi" >&5 $as_echo_n "checking for stdlib extension module _testcapi... " >&6; } - case $py_stdlib_not_available in #( - *_testcapi*) : - py_cv_module__testcapi=n/a ;; #( - *) : + if test "$py_cv_module__testcapi" != "n/a"; then : + if test "$TEST_MODULES" = yes; then : if true; then : py_cv_module__testcapi=yes @@ -23349,8 +23259,8 @@ fi else py_cv_module__testcapi=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__TESTCAPI=$py_cv_module__testcapi$as_nl" if test "x$py_cv_module__testcapi" = xyes; then : @@ -23372,10 +23282,8 @@ $as_echo "$py_cv_module__testcapi" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testinternalcapi" >&5 $as_echo_n "checking for stdlib extension module _testinternalcapi... " >&6; } - case $py_stdlib_not_available in #( - *_testinternalcapi*) : - py_cv_module__testinternalcapi=n/a ;; #( - *) : + if test "$py_cv_module__testinternalcapi" != "n/a"; then : + if test "$TEST_MODULES" = yes; then : if true; then : py_cv_module__testinternalcapi=yes @@ -23385,8 +23293,8 @@ fi else py_cv_module__testinternalcapi=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__TESTINTERNALCAPI=$py_cv_module__testinternalcapi$as_nl" if test "x$py_cv_module__testinternalcapi" = xyes; then : @@ -23408,10 +23316,8 @@ $as_echo "$py_cv_module__testinternalcapi" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testbuffer" >&5 $as_echo_n "checking for stdlib extension module _testbuffer... " >&6; } - case $py_stdlib_not_available in #( - *_testbuffer*) : - py_cv_module__testbuffer=n/a ;; #( - *) : + if test "$py_cv_module__testbuffer" != "n/a"; then : + if test "$TEST_MODULES" = yes; then : if true; then : py_cv_module__testbuffer=yes @@ -23421,8 +23327,8 @@ fi else py_cv_module__testbuffer=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__TESTBUFFER=$py_cv_module__testbuffer$as_nl" if test "x$py_cv_module__testbuffer" = xyes; then : @@ -23444,10 +23350,8 @@ $as_echo "$py_cv_module__testbuffer" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testimportmultiple" >&5 $as_echo_n "checking for stdlib extension module _testimportmultiple... " >&6; } - case $py_stdlib_not_available in #( - *_testimportmultiple*) : - py_cv_module__testimportmultiple=n/a ;; #( - *) : + if test "$py_cv_module__testimportmultiple" != "n/a"; then : + if test "$TEST_MODULES" = yes; then : if test "$ac_cv_func_dlopen" = yes; then : py_cv_module__testimportmultiple=yes @@ -23457,8 +23361,8 @@ fi else py_cv_module__testimportmultiple=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__TESTIMPORTMULTIPLE=$py_cv_module__testimportmultiple$as_nl" if test "x$py_cv_module__testimportmultiple" = xyes; then : @@ -23480,10 +23384,8 @@ $as_echo "$py_cv_module__testimportmultiple" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testmultiphase" >&5 $as_echo_n "checking for stdlib extension module _testmultiphase... " >&6; } - case $py_stdlib_not_available in #( - *_testmultiphase*) : - py_cv_module__testmultiphase=n/a ;; #( - *) : + if test "$py_cv_module__testmultiphase" != "n/a"; then : + if test "$TEST_MODULES" = yes; then : if test "$ac_cv_func_dlopen" = yes; then : py_cv_module__testmultiphase=yes @@ -23493,8 +23395,8 @@ fi else py_cv_module__testmultiphase=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__TESTMULTIPHASE=$py_cv_module__testmultiphase$as_nl" if test "x$py_cv_module__testmultiphase" = xyes; then : @@ -23516,10 +23418,8 @@ $as_echo "$py_cv_module__testmultiphase" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _xxtestfuzz" >&5 $as_echo_n "checking for stdlib extension module _xxtestfuzz... " >&6; } - case $py_stdlib_not_available in #( - *_xxtestfuzz*) : - py_cv_module__xxtestfuzz=n/a ;; #( - *) : + if test "$py_cv_module__xxtestfuzz" != "n/a"; then : + if test "$TEST_MODULES" = yes; then : if true; then : py_cv_module__xxtestfuzz=yes @@ -23529,8 +23429,8 @@ fi else py_cv_module__xxtestfuzz=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__XXTESTFUZZ=$py_cv_module__xxtestfuzz$as_nl" if test "x$py_cv_module__xxtestfuzz" = xyes; then : @@ -23552,10 +23452,8 @@ $as_echo "$py_cv_module__xxtestfuzz" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _ctypes_test" >&5 $as_echo_n "checking for stdlib extension module _ctypes_test... " >&6; } - case $py_stdlib_not_available in #( - *_ctypes_test*) : - py_cv_module__ctypes_test=n/a ;; #( - *) : + if test "$py_cv_module__ctypes_test" != "n/a"; then : + if test "$TEST_MODULES" = yes; then : if true; then : py_cv_module__ctypes_test=yes @@ -23565,8 +23463,8 @@ fi else py_cv_module__ctypes_test=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE__CTYPES_TEST=$py_cv_module__ctypes_test$as_nl" if test "x$py_cv_module__ctypes_test" = xyes; then : @@ -23589,10 +23487,8 @@ $as_echo "$py_cv_module__ctypes_test" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module xxlimited" >&5 $as_echo_n "checking for stdlib extension module xxlimited... " >&6; } - case $py_stdlib_not_available in #( - *xxlimited*) : - py_cv_module_xxlimited=n/a ;; #( - *) : + if test "$py_cv_module_xxlimited" != "n/a"; then : + if test "$with_trace_refs" = "no"; then : if test "$ac_cv_func_dlopen" = yes; then : py_cv_module_xxlimited=yes @@ -23602,8 +23498,8 @@ fi else py_cv_module_xxlimited=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE_XXLIMITED=$py_cv_module_xxlimited$as_nl" if test "x$py_cv_module_xxlimited" = xyes; then : @@ -23625,10 +23521,8 @@ $as_echo "$py_cv_module_xxlimited" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module xxlimited_35" >&5 $as_echo_n "checking for stdlib extension module xxlimited_35... " >&6; } - case $py_stdlib_not_available in #( - *xxlimited_35*) : - py_cv_module_xxlimited_35=n/a ;; #( - *) : + if test "$py_cv_module_xxlimited_35" != "n/a"; then : + if test "$with_trace_refs" = "no"; then : if test "$ac_cv_func_dlopen" = yes; then : py_cv_module_xxlimited_35=yes @@ -23638,8 +23532,8 @@ fi else py_cv_module_xxlimited_35=disabled fi - ;; -esac + +fi as_fn_append MODULE_BLOCK "MODULE_XXLIMITED_35=$py_cv_module_xxlimited_35$as_nl" if test "x$py_cv_module_xxlimited_35" = xyes; then : @@ -23665,7 +23559,7 @@ $as_echo "$py_cv_module_xxlimited_35" >&6; } # generate output files ac_config_files="$ac_config_files Makefile.pre Misc/python.pc Misc/python-embed.pc Misc/python-config.sh" -ac_config_files="$ac_config_files Modules/Setup.stdlib" +ac_config_files="$ac_config_files Modules/Setup.bootstrap Modules/Setup.stdlib" ac_config_files="$ac_config_files Modules/ld_so_aix" @@ -23907,6 +23801,10 @@ if test -z "${MODULE_OSSAUDIODEV_TRUE}" && test -z "${MODULE_OSSAUDIODEV_FALSE}" as_fn_error $? "conditional \"MODULE_OSSAUDIODEV\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${MODULE_PWD_TRUE}" && test -z "${MODULE_PWD_FALSE}"; then + as_fn_error $? "conditional \"MODULE_PWD\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MODULE_RESOURCE_TRUE}" && test -z "${MODULE_RESOURCE_FALSE}"; then as_fn_error $? "conditional \"MODULE_RESOURCE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -24666,6 +24564,7 @@ do "Misc/python.pc") CONFIG_FILES="$CONFIG_FILES Misc/python.pc" ;; "Misc/python-embed.pc") CONFIG_FILES="$CONFIG_FILES Misc/python-embed.pc" ;; "Misc/python-config.sh") CONFIG_FILES="$CONFIG_FILES Misc/python-config.sh" ;; + "Modules/Setup.bootstrap") CONFIG_FILES="$CONFIG_FILES Modules/Setup.bootstrap" ;; "Modules/Setup.stdlib") CONFIG_FILES="$CONFIG_FILES Modules/Setup.stdlib" ;; "Modules/ld_so_aix") CONFIG_FILES="$CONFIG_FILES Modules/ld_so_aix" ;; @@ -25277,7 +25176,7 @@ fi $as_echo "$as_me: creating Makefile" >&6;} $SHELL $srcdir/Modules/makesetup -c $srcdir/Modules/config.c.in \ -s Modules \ - Modules/Setup.local $MODULES_SETUP_STDLIB $srcdir/Modules/Setup.bootstrap $srcdir/Modules/Setup + Modules/Setup.local $MODULES_SETUP_STDLIB Modules/Setup.bootstrap $srcdir/Modules/Setup mv config.c Modules if test -z "$PKG_CONFIG"; then diff --git a/configure.ac b/configure.ac index fedec52f05a75..3e7d04b8eae62 100644 --- a/configure.ac +++ b/configure.ac @@ -4153,7 +4153,7 @@ AC_CHECK_FUNCS([ \ gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \ getgrnam_r getgrouplist getgroups getitimer getloadavg getlogin \ getpeername getpgid getpid getppid getpriority _getpty \ - getpwent getpwnam_r getpwuid_r getresgid getresuid getrusage getsid getspent \ + getpwent getpwnam_r getpwuid getpwuid_r getresgid getresuid getrusage getsid getspent \ getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \ lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \ mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \ @@ -6369,62 +6369,72 @@ AS_VAR_IF([TEST_MODULES], [yes], ) AC_SUBST(TEST_MODULES) +AC_DEFUN([PY_STDLIB_MOD_SET_NA], [ + m4_foreach([mod], [$@], [ + AS_VAR_SET([py_cv_module_]mod, [n/a])]) +]) + +# stdlib not available dnl Modules that are not available on some platforms dnl AIX has shadow passwords, but access is not via getspent() dnl VxWorks does not provide crypt() function AS_CASE([$ac_sys_system/$ac_sys_emscripten_target], - [AIX/*], [py_stdlib_not_available="_scproxy spwd"], - [VxWorks*/*], [py_stdlib_not_available="_scproxy _crypt termios grp"], - [Darwin/*], [py_stdlib_not_available="ossaudiodev spwd"], - [CYGWIN*/*], [py_stdlib_not_available="_scproxy nis"], - [QNX*/*], [py_stdlib_not_available="_scproxy nis"], - [FreeBSD*/*], [py_stdlib_not_available="_scproxy spwd"], + [AIX/*], [PY_STDLIB_MOD_SET_NA([_scproxy], [spwd])], + [VxWorks*/*], [PY_STDLIB_MOD_SET_NA([_scproxy], [_crypt], [termios], [grp])], + [Darwin/*], [PY_STDLIB_MOD_SET_NA([ossaudiodev], [spwd])], + [CYGWIN*/*], [PY_STDLIB_MOD_SET_NA([_scproxy], [nis])], + [QNX*/*], [PY_STDLIB_MOD_SET_NA([_scproxy], [nis])], + [FreeBSD*/*], [PY_STDLIB_MOD_SET_NA([_scproxy], [spwd])], [Emscripten/browser], [ - py_stdlib_not_available="m4_normalize([ - _ctypes - _curses - _curses_panel - _dbm - _gdbm - _multiprocessing - _posixshmem - _posixsubprocess - _scproxy - _tkinter - _xxsubinterpreters - fcntl - grp - nis - ossaudiodev - resource - readline - spwd - syslog - termios - ])" + PY_STDLIB_MOD_SET_NA( + [_ctypes], + [_curses], + [_curses_panel], + [_dbm], + [_gdbm], + [_multiprocessing], + [_posixshmem], + [_posixsubprocess], + [_scproxy], + [_tkinter], + [_xxsubinterpreters], + [fcntl], + [grp], + [nis], + [ossaudiodev], + [pwd], + [resource], + [readline], + [spwd], + [syslog], + [termios], + ) ], dnl Some modules like _posixsubprocess do not work. We build them anyway dnl so imports in tests do not fail. [Emscripten/node], [ - py_stdlib_not_available="m4_normalize([ - _ctypes - _curses - _curses_panel - _dbm - _gdbm - _scproxy - _tkinter - _xxsubinterpreters - grp - nis - ossaudiodev - spwd - syslog - ])" + PY_STDLIB_MOD_SET_NA( + [_ctypes], + [_curses], + [_curses_panel], + [_dbm], + [_gdbm], + [_scproxy], + [_tkinter], + [_xxsubinterpreters], + [grp], + [nis], + [ossaudiodev], + [pwd], + [spwd], + [syslog], + ) ], - [py_stdlib_not_available="_scproxy"] + [PY_STDLIB_MOD_SET_NA([_scproxy])] ) +dnl AC_MSG_NOTICE([m4_set_list([_PY_STDLIB_MOD_SET_NA])]) + dnl Default value for Modules/Setup.stdlib build type AS_CASE([$host_cpu], [wasm32|wasm64], [MODULE_BUILDTYPE=static], @@ -6450,10 +6460,10 @@ MODULE_BLOCK= dnl Check for stdlib extension modules dnl PY_STDLIB_MOD([NAME], [ENABLED-TEST], [SUPPORTED-TEST], [CFLAGS], [LDFLAGS]) -dnl sets MODULE_$NAME based on $py_stdlib_not_available, ENABLED-TEST, +dnl sets MODULE_$NAME based on PY_STDLIB_MOD_SET_NA(), ENABLED-TEST, dnl and SUPPORTED_TEST. ENABLED-TEST and SUPPORTED-TEST default to true if dnl empty. -dnl n/a: $NAME in $py_stdlib_not_available (not available on platform) +dnl n/a: marked unavailable on platform by PY_STDLIB_MOD_SET_NA() dnl yes: enabled and supported dnl missing: enabled and not supported dnl disabled: not enabled @@ -6462,12 +6472,12 @@ AC_DEFUN([PY_STDLIB_MOD], [ AC_MSG_CHECKING([for stdlib extension module $1]) m4_pushdef([modcond], [MODULE_]m4_toupper([$1]))dnl m4_pushdef([modstate], [py_cv_module_$1])dnl - AS_CASE([$py_stdlib_not_available], - [*$1*], [modstate=n/a], - [AS_IF(m4_ifblank([$2], [true], [$2]), - [AS_IF([m4_ifblank([$3], [true], [$3])], [modstate=yes], [modstate=missing])], - [modstate=disabled])] - ) + dnl Check if module has been disabled by PY_STDLIB_MOD_SET_NA() + AS_IF([test "$modstate" != "n/a"], [ + AS_IF(m4_ifblank([$2], [true], [$2]), + [AS_IF([m4_ifblank([$3], [true], [$3])], [modstate=yes], [modstate=missing])], + [modstate=disabled]) + ]) _MODULE_BLOCK_ADD(modcond, [$modstate]) AS_VAR_IF([modstate], [yes], [ m4_ifblank([$4], [], [_MODULE_BLOCK_ADD([MODULE_]m4_toupper([$1])[_CFLAGS], [$4])]) @@ -6480,16 +6490,14 @@ AC_DEFUN([PY_STDLIB_MOD], [ ]) dnl Define simple stdlib extension module -dnl Always enable unless the module is listed in py_stdlib_not_available +dnl Always enable unless the module is disabled by PY_STDLIB_MOD_SET_NA dnl PY_STDLIB_MOD_SIMPLE([NAME], [CFLAGS], [LDFLAGS]) dnl cflags and ldflags are optional AC_DEFUN([PY_STDLIB_MOD_SIMPLE], [ m4_pushdef([modcond], [MODULE_]m4_toupper([$1]))dnl m4_pushdef([modstate], [py_cv_module_$1])dnl - AS_CASE([$py_stdlib_not_available], - [*$1*], [modstate=n/a], - [modstate=yes] - ) + dnl Check if module has been disabled by PY_STDLIB_MOD_SET_NA() + AS_IF([test "$modstate" != "n/a"], [modstate=yes]) AM_CONDITIONAL(modcond, [test "$modstate" = yes]) _MODULE_BLOCK_ADD(modcond, [$modstate]) AS_VAR_IF([modstate], [yes], [ @@ -6556,6 +6564,7 @@ dnl platform specific extensions PY_STDLIB_MOD([grp], [], [test "$ac_cv_func_getgrgid" = yes -o "$ac_cv_func_getgrgid_r" = yes]) PY_STDLIB_MOD([ossaudiodev], [], [test "$ac_cv_header_linux_soundcard_h" = yes -o "$ac_cv_header_sys_soundcard_h" = yes]) +PY_STDLIB_MOD([pwd], [], [test "$ac_cv_func_getpwuid" = yes -o "$ac_cv_func_getpwuid_r" = yes]) PY_STDLIB_MOD([resource], [], [test "$ac_cv_header_sys_resource_h" = yes]) PY_STDLIB_MOD([_scproxy], [test "$ac_sys_system" = "Darwin"], [], @@ -6645,7 +6654,7 @@ AC_SUBST([MODULE_BLOCK]) # generate output files AC_CONFIG_FILES(Makefile.pre Misc/python.pc Misc/python-embed.pc Misc/python-config.sh) -AC_CONFIG_FILES([Modules/Setup.stdlib]) +AC_CONFIG_FILES([Modules/Setup.bootstrap Modules/Setup.stdlib]) AC_CONFIG_FILES([Modules/ld_so_aix], [chmod +x Modules/ld_so_aix]) AC_OUTPUT @@ -6658,7 +6667,7 @@ fi AC_MSG_NOTICE([creating Makefile]) $SHELL $srcdir/Modules/makesetup -c $srcdir/Modules/config.c.in \ -s Modules \ - Modules/Setup.local $MODULES_SETUP_STDLIB $srcdir/Modules/Setup.bootstrap $srcdir/Modules/Setup + Modules/Setup.local $MODULES_SETUP_STDLIB Modules/Setup.bootstrap $srcdir/Modules/Setup mv config.c Modules if test -z "$PKG_CONFIG"; then diff --git a/pyconfig.h.in b/pyconfig.h.in index a1bf9502e9268..40057e0ff87d9 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -522,6 +522,9 @@ /* Define to 1 if you have the `getpwnam_r' function. */ #undef HAVE_GETPWNAM_R +/* Define to 1 if you have the `getpwuid' function. */ +#undef HAVE_GETPWUID + /* Define to 1 if you have the `getpwuid_r' function. */ #undef HAVE_GETPWUID_R From webhook-mailer at python.org Mon Mar 7 08:18:41 2022 From: webhook-mailer at python.org (pablogsal) Date: Mon, 07 Mar 2022 13:18:41 -0000 Subject: [Python-checkins] [3.10] bpo-46940: Don't override existing AttributeError suggestion information (GH-31710) (GH-31724) Message-ID: https://github.com/python/cpython/commit/3594ebca2cacf5d9b5212d2c487fd017cd00e283 commit: 3594ebca2cacf5d9b5212d2c487fd017cd00e283 branch: 3.10 author: Pablo Galindo Salgado committer: pablogsal date: 2022-03-07T13:18:36Z summary: [3.10] bpo-46940: Don't override existing AttributeError suggestion information (GH-31710) (GH-31724) When an exception is created in a nested call to PyObject_GetAttr, any external calls will override the context information of the AttributeError that we have already placed in the most internal call. This will cause the suggestions we create to nor work properly as the attribute name and object that we will be using are the incorrect ones. To avoid this, we need to check first if these attributes are already set and bail out if that's the case.. (cherry picked from commit 3b3be05a164da43f201e35b6dafbc840993a4d18) Co-authored-by: Pablo Galindo Salgado files: A Misc/NEWS.d/next/Core and Builtins/2022-03-06-20-16-13.bpo-46940._X47Hx.rst M Lib/test/test_exceptions.py M Objects/object.c M Python/ceval.c diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 49739723ee473..2bdd7214b0505 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -2201,6 +2201,24 @@ def test_attribute_error_with_bad_name(self): self.assertNotIn("?", err.getvalue()) + def test_attribute_error_inside_nested_getattr(self): + class A: + bluch = 1 + + class B: + def __getattribute__(self, attr): + a = A() + return a.blich + + try: + B().something + except AttributeError as exc: + with support.captured_stderr() as err: + sys.__excepthook__(*sys.exc_info()) + + self.assertIn("Did you mean", err.getvalue()) + self.assertIn("bluch", err.getvalue()) + class ImportErrorTests(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-06-20-16-13.bpo-46940._X47Hx.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-06-20-16-13.bpo-46940._X47Hx.rst new file mode 100644 index 0000000000000..fabc946019758 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-06-20-16-13.bpo-46940._X47Hx.rst @@ -0,0 +1,2 @@ +Avoid overriding :exc:`AttributeError` metadata information for nested +attribute access calls. Patch by Pablo Galindo. diff --git a/Objects/object.c b/Objects/object.c index ff816cd5b9a60..47c352e3d6405 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -890,19 +890,29 @@ set_attribute_error_context(PyObject* v, PyObject* name) assert(PyErr_Occurred()); _Py_IDENTIFIER(name); _Py_IDENTIFIER(obj); - // Intercept AttributeError exceptions and augment them to offer - // suggestions later. - if (PyErr_ExceptionMatches(PyExc_AttributeError)){ - PyObject *type, *value, *traceback; - PyErr_Fetch(&type, &value, &traceback); - PyErr_NormalizeException(&type, &value, &traceback); - if (PyErr_GivenExceptionMatches(value, PyExc_AttributeError) && - (_PyObject_SetAttrId(value, &PyId_name, name) || - _PyObject_SetAttrId(value, &PyId_obj, v))) { - return 1; - } - PyErr_Restore(type, value, traceback); + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { + return 0; + } + // Intercept AttributeError exceptions and augment them to offer suggestions later. + PyObject *type, *value, *traceback; + PyErr_Fetch(&type, &value, &traceback); + PyErr_NormalizeException(&type, &value, &traceback); + // Check if the normalized exception is indeed an AttributeError + if (!PyErr_GivenExceptionMatches(value, PyExc_AttributeError)) { + goto restore; + } + PyAttributeErrorObject* the_exc = (PyAttributeErrorObject*) value; + // Check if this exception was already augmented + if (the_exc->name || the_exc->obj) { + goto restore; + } + // Augment the exception with the name and object + if (_PyObject_SetAttrId(value, &PyId_name, name) || + _PyObject_SetAttrId(value, &PyId_obj, v)) { + return 1; } +restore: + PyErr_Restore(type, value, traceback); return 0; } diff --git a/Python/ceval.c b/Python/ceval.c index ab10b4166d6d2..21674e0be1324 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -6261,9 +6261,12 @@ format_exc_check_arg(PyThreadState *tstate, PyObject *exc, PyErr_Fetch(&type, &value, &traceback); PyErr_NormalizeException(&type, &value, &traceback); if (PyErr_GivenExceptionMatches(value, PyExc_NameError)) { - // We do not care if this fails because we are going to restore the - // NameError anyway. - (void)_PyObject_SetAttrId(value, &PyId_name, obj); + PyNameErrorObject* exc = (PyNameErrorObject*) value; + if (exc->name == NULL) { + // We do not care if this fails because we are going to restore the + // NameError anyway. + (void)_PyObject_SetAttrId(value, &PyId_name, obj); + } } PyErr_Restore(type, value, traceback); } From webhook-mailer at python.org Mon Mar 7 09:54:39 2022 From: webhook-mailer at python.org (pablogsal) Date: Mon, 07 Mar 2022 14:54:39 -0000 Subject: [Python-checkins] [3.10] Update grammar_grapher with the new forced (&&) directive (GH-31704) (GH-31719) Message-ID: https://github.com/python/cpython/commit/0ff033b859f29b6230f6d2262f08b31c2ba11921 commit: 0ff033b859f29b6230f6d2262f08b31c2ba11921 branch: 3.10 author: Luca Chiodini committer: pablogsal date: 2022-03-07T14:54:08Z summary: [3.10] Update grammar_grapher with the new forced (&&) directive (GH-31704) (GH-31719) (cherry picked from commit 7f07b5ee9c2d17f837c44440bf066c73f92dac14) Co-authored-by: Luca Chiodini files: M Tools/peg_generator/scripts/grammar_grapher.py diff --git a/Tools/peg_generator/scripts/grammar_grapher.py b/Tools/peg_generator/scripts/grammar_grapher.py index 4afdbce8f966f..c527e19b20997 100755 --- a/Tools/peg_generator/scripts/grammar_grapher.py +++ b/Tools/peg_generator/scripts/grammar_grapher.py @@ -29,6 +29,7 @@ from pegen.grammar import ( Alt, Cut, + Forced, Grammar, Group, Leaf, @@ -57,6 +58,8 @@ def references_for_item(item: Any) -> List[Any]: return [_ref for _item in item.items for _ref in references_for_item(_item)] elif isinstance(item, Cut): return [] + elif isinstance(item, Forced): + return references_for_item(item.node) elif isinstance(item, Group): return references_for_item(item.rhs) elif isinstance(item, Lookahead): From webhook-mailer at python.org Mon Mar 7 12:23:31 2022 From: webhook-mailer at python.org (zooba) Date: Mon, 07 Mar 2022 17:23:31 -0000 Subject: [Python-checkins] bpo-46948: Fix CVE-2022-26488 by ensuring the Windows Installer correctly uses the install path during repair (GH-31727) Message-ID: https://github.com/python/cpython/commit/136842c91b5783e205e217c4855baa9dadd4ad41 commit: 136842c91b5783e205e217c4855baa9dadd4ad41 branch: 3.10 author: Steve Dower committer: zooba date: 2022-03-07T17:23:20Z summary: bpo-46948: Fix CVE-2022-26488 by ensuring the Windows Installer correctly uses the install path during repair (GH-31727) files: A Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst M Tools/msi/bundle/bundle.wxs M Tools/msi/common.wxs M Tools/msi/dev/dev.wxs M Tools/msi/doc/doc.wxs M Tools/msi/lib/lib.wxs M Tools/msi/path/path.wxs M Tools/msi/tcltk/tcltk.wxs M Tools/msi/test/test.wxs M Tools/msi/tools/tools.wxs M Tools/msi/ucrt/ucrt.wxs diff --git a/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst b/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst new file mode 100644 index 0000000000000..cfc4827882ded --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst @@ -0,0 +1,2 @@ +Prevent CVE-2022-26488 by ensuring the Add to PATH option in the Windows +installer uses the correct path when being repaired. diff --git a/Tools/msi/bundle/bundle.wxs b/Tools/msi/bundle/bundle.wxs index e2f871889340f..0c28db6f90b72 100644 --- a/Tools/msi/bundle/bundle.wxs +++ b/Tools/msi/bundle/bundle.wxs @@ -95,8 +95,8 @@ - + diff --git a/Tools/msi/common.wxs b/Tools/msi/common.wxs index 398d94a24d554..d8f3cde99ab52 100644 --- a/Tools/msi/common.wxs +++ b/Tools/msi/common.wxs @@ -53,11 +53,23 @@ - + + - + + + + + + + + + + + + diff --git a/Tools/msi/dev/dev.wxs b/Tools/msi/dev/dev.wxs index 23a710df87d55..2ddeb31afc770 100644 --- a/Tools/msi/dev/dev.wxs +++ b/Tools/msi/dev/dev.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/doc/doc.wxs b/Tools/msi/doc/doc.wxs index cd1a68cc2601a..cc5bdb493e5fe 100644 --- a/Tools/msi/doc/doc.wxs +++ b/Tools/msi/doc/doc.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/lib/lib.wxs b/Tools/msi/lib/lib.wxs index 2a3b9ecfeef8d..b38cd9114be74 100644 --- a/Tools/msi/lib/lib.wxs +++ b/Tools/msi/lib/lib.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/path/path.wxs b/Tools/msi/path/path.wxs index 8b37936cc938f..017b812270c5b 100644 --- a/Tools/msi/path/path.wxs +++ b/Tools/msi/path/path.wxs @@ -2,7 +2,8 @@ - + + diff --git a/Tools/msi/tcltk/tcltk.wxs b/Tools/msi/tcltk/tcltk.wxs index eeae8e8b0dfa5..bbf6ac70fadf6 100644 --- a/Tools/msi/tcltk/tcltk.wxs +++ b/Tools/msi/tcltk/tcltk.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/test/test.wxs b/Tools/msi/test/test.wxs index f2ed64f07bf28..e8f514a222366 100644 --- a/Tools/msi/test/test.wxs +++ b/Tools/msi/test/test.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/tools/tools.wxs b/Tools/msi/tools/tools.wxs index 7a805d0612e08..133a743efccae 100644 --- a/Tools/msi/tools/tools.wxs +++ b/Tools/msi/tools/tools.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/ucrt/ucrt.wxs b/Tools/msi/ucrt/ucrt.wxs index 76e56820c53b2..94fd3f0e97488 100644 --- a/Tools/msi/ucrt/ucrt.wxs +++ b/Tools/msi/ucrt/ucrt.wxs @@ -4,6 +4,7 @@ + From webhook-mailer at python.org Mon Mar 7 12:23:32 2022 From: webhook-mailer at python.org (zooba) Date: Mon, 07 Mar 2022 17:23:32 -0000 Subject: [Python-checkins] bpo-46948: Fix CVE-2022-26488 by ensuring the Windows Installer correctly uses the install path during repair (GH-31726) Message-ID: https://github.com/python/cpython/commit/77446d2aa56e9e3262d9d2247342bbbb0ff5e907 commit: 77446d2aa56e9e3262d9d2247342bbbb0ff5e907 branch: main author: Steve Dower committer: zooba date: 2022-03-07T17:23:11Z summary: bpo-46948: Fix CVE-2022-26488 by ensuring the Windows Installer correctly uses the install path during repair (GH-31726) files: A Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst M Tools/msi/appendpath/appendpath.wxs M Tools/msi/bundle/bundle.wxs M Tools/msi/common.wxs M Tools/msi/dev/dev.wxs M Tools/msi/doc/doc.wxs M Tools/msi/lib/lib.wxs M Tools/msi/path/path.wxs M Tools/msi/tcltk/tcltk.wxs M Tools/msi/test/test.wxs M Tools/msi/tools/tools.wxs M Tools/msi/ucrt/ucrt.wxs diff --git a/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst b/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst new file mode 100644 index 0000000000000..cfc4827882ded --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst @@ -0,0 +1,2 @@ +Prevent CVE-2022-26488 by ensuring the Add to PATH option in the Windows +installer uses the correct path when being repaired. diff --git a/Tools/msi/appendpath/appendpath.wxs b/Tools/msi/appendpath/appendpath.wxs index e8d7a9d0a31ae..bba186cf60fd1 100644 --- a/Tools/msi/appendpath/appendpath.wxs +++ b/Tools/msi/appendpath/appendpath.wxs @@ -3,6 +3,7 @@ + diff --git a/Tools/msi/bundle/bundle.wxs b/Tools/msi/bundle/bundle.wxs index 0683f87cb0586..ac4b7a6d75308 100644 --- a/Tools/msi/bundle/bundle.wxs +++ b/Tools/msi/bundle/bundle.wxs @@ -108,8 +108,8 @@ - + diff --git a/Tools/msi/common.wxs b/Tools/msi/common.wxs index 398d94a24d554..d8f3cde99ab52 100644 --- a/Tools/msi/common.wxs +++ b/Tools/msi/common.wxs @@ -53,11 +53,23 @@ - + + - + + + + + + + + + + + + diff --git a/Tools/msi/dev/dev.wxs b/Tools/msi/dev/dev.wxs index cfc4c449d17cf..15a08364bead0 100644 --- a/Tools/msi/dev/dev.wxs +++ b/Tools/msi/dev/dev.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/doc/doc.wxs b/Tools/msi/doc/doc.wxs index d05936fd85055..1d7706bb4d50a 100644 --- a/Tools/msi/doc/doc.wxs +++ b/Tools/msi/doc/doc.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/lib/lib.wxs b/Tools/msi/lib/lib.wxs index 5c67420978927..e417e31b33783 100644 --- a/Tools/msi/lib/lib.wxs +++ b/Tools/msi/lib/lib.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/path/path.wxs b/Tools/msi/path/path.wxs index 496f9d08a470c..32854392e8bee 100644 --- a/Tools/msi/path/path.wxs +++ b/Tools/msi/path/path.wxs @@ -2,7 +2,8 @@ - + + diff --git a/Tools/msi/tcltk/tcltk.wxs b/Tools/msi/tcltk/tcltk.wxs index fdd6da384bf0c..bad56d55cce37 100644 --- a/Tools/msi/tcltk/tcltk.wxs +++ b/Tools/msi/tcltk/tcltk.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/test/test.wxs b/Tools/msi/test/test.wxs index bf601f42a7283..9e497e73a94f5 100644 --- a/Tools/msi/test/test.wxs +++ b/Tools/msi/test/test.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/tools/tools.wxs b/Tools/msi/tools/tools.wxs index bb6436c7a0f81..c06b3c27f6970 100644 --- a/Tools/msi/tools/tools.wxs +++ b/Tools/msi/tools/tools.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/ucrt/ucrt.wxs b/Tools/msi/ucrt/ucrt.wxs index 525130c8bec3a..e9e2a9a904511 100644 --- a/Tools/msi/ucrt/ucrt.wxs +++ b/Tools/msi/ucrt/ucrt.wxs @@ -4,6 +4,7 @@ + From webhook-mailer at python.org Mon Mar 7 12:23:36 2022 From: webhook-mailer at python.org (zooba) Date: Mon, 07 Mar 2022 17:23:36 -0000 Subject: [Python-checkins] bpo-46948: Fix CVE-2022-26488 by ensuring the Windows Installer correctly uses the install path during repair (GH-31728) Message-ID: https://github.com/python/cpython/commit/101a1bee1953b82339115c5e648e1717359c78eb commit: 101a1bee1953b82339115c5e648e1717359c78eb branch: 3.9 author: Steve Dower committer: zooba date: 2022-03-07T17:23:31Z summary: bpo-46948: Fix CVE-2022-26488 by ensuring the Windows Installer correctly uses the install path during repair (GH-31728) files: A Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst M Tools/msi/bundle/bundle.wxs M Tools/msi/common.wxs M Tools/msi/dev/dev.wxs M Tools/msi/doc/doc.wxs M Tools/msi/lib/lib.wxs M Tools/msi/path/path.wxs M Tools/msi/tcltk/tcltk.wxs M Tools/msi/test/test.wxs M Tools/msi/tools/tools.wxs M Tools/msi/ucrt/ucrt.wxs diff --git a/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst b/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst new file mode 100644 index 0000000000000..cfc4827882ded --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst @@ -0,0 +1,2 @@ +Prevent CVE-2022-26488 by ensuring the Add to PATH option in the Windows +installer uses the correct path when being repaired. diff --git a/Tools/msi/bundle/bundle.wxs b/Tools/msi/bundle/bundle.wxs index e2f871889340f..0c28db6f90b72 100644 --- a/Tools/msi/bundle/bundle.wxs +++ b/Tools/msi/bundle/bundle.wxs @@ -95,8 +95,8 @@ - + diff --git a/Tools/msi/common.wxs b/Tools/msi/common.wxs index 398d94a24d554..d8f3cde99ab52 100644 --- a/Tools/msi/common.wxs +++ b/Tools/msi/common.wxs @@ -53,11 +53,23 @@ - + + - + + + + + + + + + + + + diff --git a/Tools/msi/dev/dev.wxs b/Tools/msi/dev/dev.wxs index 23a710df87d55..2ddeb31afc770 100644 --- a/Tools/msi/dev/dev.wxs +++ b/Tools/msi/dev/dev.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/doc/doc.wxs b/Tools/msi/doc/doc.wxs index cd1a68cc2601a..cc5bdb493e5fe 100644 --- a/Tools/msi/doc/doc.wxs +++ b/Tools/msi/doc/doc.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/lib/lib.wxs b/Tools/msi/lib/lib.wxs index 2a3b9ecfeef8d..b38cd9114be74 100644 --- a/Tools/msi/lib/lib.wxs +++ b/Tools/msi/lib/lib.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/path/path.wxs b/Tools/msi/path/path.wxs index 8b37936cc938f..017b812270c5b 100644 --- a/Tools/msi/path/path.wxs +++ b/Tools/msi/path/path.wxs @@ -2,7 +2,8 @@ - + + diff --git a/Tools/msi/tcltk/tcltk.wxs b/Tools/msi/tcltk/tcltk.wxs index eeae8e8b0dfa5..bbf6ac70fadf6 100644 --- a/Tools/msi/tcltk/tcltk.wxs +++ b/Tools/msi/tcltk/tcltk.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/test/test.wxs b/Tools/msi/test/test.wxs index f2ed64f07bf28..e8f514a222366 100644 --- a/Tools/msi/test/test.wxs +++ b/Tools/msi/test/test.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/tools/tools.wxs b/Tools/msi/tools/tools.wxs index 7a805d0612e08..133a743efccae 100644 --- a/Tools/msi/tools/tools.wxs +++ b/Tools/msi/tools/tools.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/ucrt/ucrt.wxs b/Tools/msi/ucrt/ucrt.wxs index 76e56820c53b2..94fd3f0e97488 100644 --- a/Tools/msi/ucrt/ucrt.wxs +++ b/Tools/msi/ucrt/ucrt.wxs @@ -4,6 +4,7 @@ + From webhook-mailer at python.org Mon Mar 7 12:37:38 2022 From: webhook-mailer at python.org (ned-deily) Date: Mon, 07 Mar 2022 17:37:38 -0000 Subject: [Python-checkins] bpo-46948: Fix CVE-2022-26488 by ensuring the Windows Installer correctly uses the install path during repair (GH-31730) Message-ID: https://github.com/python/cpython/commit/97476271275a4bd1340230677b7301d7b78b3317 commit: 97476271275a4bd1340230677b7301d7b78b3317 branch: 3.7 author: Steve Dower committer: ned-deily date: 2022-03-07T12:37:20-05:00 summary: bpo-46948: Fix CVE-2022-26488 by ensuring the Windows Installer correctly uses the install path during repair (GH-31730) files: A Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst M Tools/msi/bundle/bundle.wxs M Tools/msi/common.wxs M Tools/msi/dev/dev.wxs M Tools/msi/doc/doc.wxs M Tools/msi/lib/lib.wxs M Tools/msi/path/path.wxs M Tools/msi/tcltk/tcltk.wxs M Tools/msi/test/test.wxs M Tools/msi/tools/tools.wxs M Tools/msi/ucrt/ucrt.wxs diff --git a/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst b/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst new file mode 100644 index 0000000000000..cfc4827882ded --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst @@ -0,0 +1,2 @@ +Prevent CVE-2022-26488 by ensuring the Add to PATH option in the Windows +installer uses the correct path when being repaired. diff --git a/Tools/msi/bundle/bundle.wxs b/Tools/msi/bundle/bundle.wxs index ddd6870f62552..12f2a46c8c7e9 100644 --- a/Tools/msi/bundle/bundle.wxs +++ b/Tools/msi/bundle/bundle.wxs @@ -95,8 +95,8 @@ - + diff --git a/Tools/msi/common.wxs b/Tools/msi/common.wxs index 398d94a24d554..d8f3cde99ab52 100644 --- a/Tools/msi/common.wxs +++ b/Tools/msi/common.wxs @@ -53,11 +53,23 @@ - + + - + + + + + + + + + + + + diff --git a/Tools/msi/dev/dev.wxs b/Tools/msi/dev/dev.wxs index a09e139c428bf..fee68e1912c8c 100644 --- a/Tools/msi/dev/dev.wxs +++ b/Tools/msi/dev/dev.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/doc/doc.wxs b/Tools/msi/doc/doc.wxs index cd1a68cc2601a..cc5bdb493e5fe 100644 --- a/Tools/msi/doc/doc.wxs +++ b/Tools/msi/doc/doc.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/lib/lib.wxs b/Tools/msi/lib/lib.wxs index 2a3b9ecfeef8d..b38cd9114be74 100644 --- a/Tools/msi/lib/lib.wxs +++ b/Tools/msi/lib/lib.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/path/path.wxs b/Tools/msi/path/path.wxs index 8b37936cc938f..017b812270c5b 100644 --- a/Tools/msi/path/path.wxs +++ b/Tools/msi/path/path.wxs @@ -2,7 +2,8 @@ - + + diff --git a/Tools/msi/tcltk/tcltk.wxs b/Tools/msi/tcltk/tcltk.wxs index eeae8e8b0dfa5..bbf6ac70fadf6 100644 --- a/Tools/msi/tcltk/tcltk.wxs +++ b/Tools/msi/tcltk/tcltk.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/test/test.wxs b/Tools/msi/test/test.wxs index f2ed64f07bf28..e8f514a222366 100644 --- a/Tools/msi/test/test.wxs +++ b/Tools/msi/test/test.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/tools/tools.wxs b/Tools/msi/tools/tools.wxs index 7a805d0612e08..133a743efccae 100644 --- a/Tools/msi/tools/tools.wxs +++ b/Tools/msi/tools/tools.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/ucrt/ucrt.wxs b/Tools/msi/ucrt/ucrt.wxs index 76e56820c53b2..94fd3f0e97488 100644 --- a/Tools/msi/ucrt/ucrt.wxs +++ b/Tools/msi/ucrt/ucrt.wxs @@ -4,6 +4,7 @@ + From webhook-mailer at python.org Mon Mar 7 13:03:08 2022 From: webhook-mailer at python.org (gvanrossum) Date: Mon, 07 Mar 2022 18:03:08 -0000 Subject: [Python-checkins] bpo-41370: Evaluate strings as forward refs in PEP 585 generics (GH-30900) Message-ID: https://github.com/python/cpython/commit/b465b606049f6f7dd0711cb031fdaa251818741a commit: b465b606049f6f7dd0711cb031fdaa251818741a branch: main author: Niklas Rosenstein committer: gvanrossum date: 2022-03-07T10:02:59-08:00 summary: bpo-41370: Evaluate strings as forward refs in PEP 585 generics (GH-30900) This removes discrepancy between list["int"] and List["int"]. Co-authored-by: Jelle Zijlstra Co-authored-by: Alex Waygood files: A Misc/NEWS.d/next/Library/2022-01-27-11-54-16.bpo-41370.gYxCPE.rst M Lib/test/test_typing.py M Lib/typing.py diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 86baed98fcab1..17d78cffcb4fa 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -32,6 +32,7 @@ from typing import ParamSpec, Concatenate, ParamSpecArgs, ParamSpecKwargs from typing import TypeGuard import abc +import textwrap import typing import weakref import types @@ -2156,6 +2157,45 @@ def barfoo(x: AT): ... def barfoo2(x: CT): ... self.assertIs(get_type_hints(barfoo2, globals(), locals())['x'], CT) + def test_generic_pep585_forward_ref(self): + # See https://bugs.python.org/issue41370 + + class C1: + a: list['C1'] + self.assertEqual( + get_type_hints(C1, globals(), locals()), + {'a': list[C1]} + ) + + class C2: + a: dict['C1', list[List[list['C2']]]] + self.assertEqual( + get_type_hints(C2, globals(), locals()), + {'a': dict[C1, list[List[list[C2]]]]} + ) + + # Test stringified annotations + scope = {} + exec(textwrap.dedent(''' + from __future__ import annotations + class C3: + a: List[list["C2"]] + '''), scope) + C3 = scope['C3'] + self.assertEqual(C3.__annotations__['a'], "List[list['C2']]") + self.assertEqual( + get_type_hints(C3, globals(), locals()), + {'a': List[list[C2]]} + ) + + # Test recursive types + X = list["X"] + def f(x: X): ... + self.assertEqual( + get_type_hints(f, globals(), locals()), + {'x': list[list[ForwardRef('X')]]} + ) + def test_extended_generic_rules_subclassing(self): class T1(Tuple[T, KT]): ... class T2(Tuple[T, ...]): ... @@ -3556,7 +3596,7 @@ def foobar(x: list[ForwardRef('X')]): ... BA = Tuple[Annotated[T, (1, 0)], ...] def barfoo(x: BA): ... self.assertEqual(get_type_hints(barfoo, globals(), locals())['x'], Tuple[T, ...]) - self.assertIs( + self.assertEqual( get_type_hints(barfoo, globals(), locals(), include_extras=True)['x'], BA ) @@ -3564,7 +3604,7 @@ def barfoo(x: BA): ... BA = tuple[Annotated[T, (1, 0)], ...] def barfoo(x: BA): ... self.assertEqual(get_type_hints(barfoo, globals(), locals())['x'], tuple[T, ...]) - self.assertIs( + self.assertEqual( get_type_hints(barfoo, globals(), locals(), include_extras=True)['x'], BA ) diff --git a/Lib/typing.py b/Lib/typing.py index 27d83c5105fa4..360129e3db34e 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -336,6 +336,12 @@ def _eval_type(t, globalns, localns, recursive_guard=frozenset()): if isinstance(t, ForwardRef): return t._evaluate(globalns, localns, recursive_guard) if isinstance(t, (_GenericAlias, GenericAlias, types.UnionType)): + if isinstance(t, GenericAlias): + args = tuple( + ForwardRef(arg) if isinstance(arg, str) else arg + for arg in t.__args__ + ) + t = t.__origin__[args] ev_args = tuple(_eval_type(a, globalns, localns, recursive_guard) for a in t.__args__) if ev_args == t.__args__: return t diff --git a/Misc/NEWS.d/next/Library/2022-01-27-11-54-16.bpo-41370.gYxCPE.rst b/Misc/NEWS.d/next/Library/2022-01-27-11-54-16.bpo-41370.gYxCPE.rst new file mode 100644 index 0000000000000..d9ad2af156a4d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-01-27-11-54-16.bpo-41370.gYxCPE.rst @@ -0,0 +1 @@ +:func:`typing.get_type_hints` now supports evaluating strings as forward references in :ref:`PEP 585 generic aliases `. From webhook-mailer at python.org Mon Mar 7 13:20:06 2022 From: webhook-mailer at python.org (pablogsal) Date: Mon, 07 Mar 2022 18:20:06 -0000 Subject: [Python-checkins] Python 3.11.0a6 Message-ID: https://github.com/python/cpython/commit/3ddfa55df48a67a5972feac32eaeb85effeda8e3 commit: 3ddfa55df48a67a5972feac32eaeb85effeda8e3 branch: main author: Pablo Galindo committer: pablogsal date: 2022-03-07T12:32:18Z summary: Python 3.11.0a6 files: A Misc/NEWS.d/3.11.0a6.rst D Misc/NEWS.d/next/Build/2022-01-19-11-08-32.bpo-46430.k403m_.rst D Misc/NEWS.d/next/Build/2022-01-31-15-15-08.bpo-40280.r1AYNW.rst D Misc/NEWS.d/next/Build/2022-02-02-11-26-46.bpo-46608.cXH9po.rst D Misc/NEWS.d/next/Build/2022-02-04-21-26-50.bpo-46640.HXUmQp.rst D Misc/NEWS.d/next/Build/2022-02-06-14-04-20.bpo-46656.ajJjkh.rst D Misc/NEWS.d/next/Build/2022-02-25-00-51-16.bpo-46656.MD783M.rst D Misc/NEWS.d/next/Build/2022-02-25-16-19-40.bpo-46860.jfciLG.rst D Misc/NEWS.d/next/C API/2022-02-02-17-58-49.bpo-46613.__ZdpH.rst D Misc/NEWS.d/next/C API/2022-02-06-20-14-21.bpo-45412.XJVaGW.rst D Misc/NEWS.d/next/C API/2022-02-07-18-47-00.bpo-45459.0FCWM8.rst D Misc/NEWS.d/next/C API/2022-02-23-16-13-17.bpo-46836.ZYyPF_.rst D Misc/NEWS.d/next/C API/2022-02-24-13-13-16.bpo-46748.aG1zb3.rst D Misc/NEWS.d/next/Core and Builtins/2022-01-09-11-59-04.bpo-30496.KvuuGT.rst D Misc/NEWS.d/next/Core and Builtins/2022-01-27-14-20-18.bpo-45828.kzk4fl.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-04-04-33-18.bpo-46615.puArY9.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-05-14-46-21.bpo-46323.FC1OJg.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-06-23-08-30.bpo-40479.zED3Zu.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-07-14-33-45.bpo-46675.ZPbdMp.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-07-14-38-54.bpo-46072.6ebLyN.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-09-16-36-11.bpo-46702.LcaEuC.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-09-20-21-43.bpo-45923.tJ4gDX.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-10-02-29-12.bpo-46323.HK_cs0.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-10-03-13-18.bpo-46707.xeSEh0.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-11-13-47-58.bpo-46072.PDS6Ke.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-12-11-16-40.bpo-46732.3Z_qxd.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-14-14-44-06.bpo-46724.jym_K6.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-14-21-04-43.bpo-46730.rYJ1w5.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-15-20-26-46.bpo-46762.1H7vab.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-16-13-15-16.bpo-46329.8aIuz9.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-20-23-10-14.bpo-46808.vouNSF.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-21-10-29-20.bpo-46329.cbkt7u.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-21-21-55-23.bpo-46820.4RfUZh.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-22-05-14-25.bpo-46823.z9NZC9.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-22-12-07-53.bpo-46794.6WvJ9o.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-22-14-03-56.bpo-46329.RX_AzJ.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-22-15-48-32.bpo-45885.W2vkaI.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-22-17-18-36.bpo-46729.ZwGTFq.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-22-17-19-45.bpo-44337.XA-egu.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-23-15-26-02.bpo-45107.axcgHn.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-23-18-17-30.bpo-46841.fns8HB.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-24-07-33-29.bpo-46430.c91TAg.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-24-07-50-43.bpo-46712.pw7vQV.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-24-16-34-17.bpo-40116.AeVGG2.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-25-01-42-45.bpo-46852.nkRDvV.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-25-02-01-42.bpo-46852._3zg8D.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-25-13-18-18.bpo-46841.86QiQu.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-25-14-57-21.bpo-46845.TUvaMG.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-25-15-18-40.bpo-46841.tmLpgC.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-26-19-26-36.bpo-46864.EmLgFp.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-28-12-01-04.bpo-46841.r60AMJ.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-28-15-46-36.bpo-46841.MDQoty.rst D Misc/NEWS.d/next/Core and Builtins/2022-03-01-17-47-58.bpo-46841.inYQlU.rst D Misc/NEWS.d/next/Core and Builtins/2022-03-02-15-04-08.bpo-46891.aIAgTD.rst D Misc/NEWS.d/next/Core and Builtins/2022-03-03-10-46-13.bpo-46841.7CkuZx.rst D Misc/NEWS.d/next/Core and Builtins/2022-03-03-12-02-41.bpo-46903.OzgaFZ.rst D Misc/NEWS.d/next/Core and Builtins/2022-03-03-12-36-15.bpo-46841.apPev2.rst D Misc/NEWS.d/next/Core and Builtins/2022-03-03-14-31-53.bpo-46841.agf-3X.rst D Misc/NEWS.d/next/Core and Builtins/2022-03-05-00-43-22.bpo-46921.tyuPeB.rst D Misc/NEWS.d/next/Core and Builtins/2022-03-05-12-23-58.bpo-46927.URbHBi.rst D Misc/NEWS.d/next/Core and Builtins/2022-03-06-20-16-13.bpo-46940._X47Hx.rst D Misc/NEWS.d/next/Documentation/2022-02-03-11-24-59.bpo-42238.yJcMa8.rst D Misc/NEWS.d/next/IDLE/2021-10-14-16-55-03.bpo-45447.FhiH5P.rst D Misc/NEWS.d/next/IDLE/2022-02-03-15-47-53.bpo-46630.tREOjo.rst D Misc/NEWS.d/next/Library/2019-05-07-14-25-45.bpo-14156.0FaHXE.rst D Misc/NEWS.d/next/Library/2020-03-31-20-53-11.bpo-29418.8Qa9cQ.rst D Misc/NEWS.d/next/Library/2020-06-23-01-50-24.bpo-41086.YnOvpS.rst D Misc/NEWS.d/next/Library/2021-05-02-23-44-21.bpo-44011.hd8iUO.rst D Misc/NEWS.d/next/Library/2021-06-02-19-47-46.bpo-44289.xC5kuV.rst D Misc/NEWS.d/next/Library/2021-08-19-09-29-43.bpo-44953.27ZyUd.rst D Misc/NEWS.d/next/Library/2021-11-26-10-46-09.bpo-45898.UIfhsb.rst D Misc/NEWS.d/next/Library/2021-12-27-18-28-44.bpo-31369.b9yM94.rst D Misc/NEWS.d/next/Library/2021-12-30-21-38-51.bpo-46195.jFKGq_.rst D Misc/NEWS.d/next/Library/2022-01-03-09-46-44.bpo-46232.s0KlyI.rst D Misc/NEWS.d/next/Library/2022-01-07-13-27-53.bpo-46246.CTLx32.rst D Misc/NEWS.d/next/Library/2022-01-11-15-54-15.bpo-46333.B1faiF.rst D Misc/NEWS.d/next/Library/2022-01-23-15-35-07.bpo-46475.UCe18S.rst D Misc/NEWS.d/next/Library/2022-01-25-15-31-04.bpo-46522.tYAlX4.rst D Misc/NEWS.d/next/Library/2022-01-26-18-06-08.bpo-46534.vhzUM4.rst D Misc/NEWS.d/next/Library/2022-01-27-23-20-30.bpo-46556.tlpAgS.rst D Misc/NEWS.d/next/Library/2022-01-30-15-16-12.bpo-46400.vweUiO.rst D Misc/NEWS.d/next/Library/2022-02-01-11-21-34.bpo-46571.L40xUJ.rst D Misc/NEWS.d/next/Library/2022-02-01-19-34-28.bpo-46521.IMUIrs.rst D Misc/NEWS.d/next/Library/2022-02-03-10-22-42.bpo-46626.r2e-n_.rst D Misc/NEWS.d/next/Library/2022-02-05-18-22-05.bpo-45948.w4mCnE.rst D Misc/NEWS.d/next/Library/2022-02-06-08-54-03.bpo-46655.DiLzYv.rst D Misc/NEWS.d/next/Library/2022-02-06-17-57-45.bpo-46659.zTmkoQ.rst D Misc/NEWS.d/next/Library/2022-02-06-19-13-02.bpo-46659.q-vNL9.rst D Misc/NEWS.d/next/Library/2022-02-07-13-15-16.bpo-46672.4swIjx.rst D Misc/NEWS.d/next/Library/2022-02-07-13-27-59.bpo-46323.7UENAj.rst D Misc/NEWS.d/next/Library/2022-02-07-19-20-42.bpo-46676.3Aws1o.rst D Misc/NEWS.d/next/Library/2022-02-08-16-42-20.bpo-46066.m32Hl0.rst D Misc/NEWS.d/next/Library/2022-02-09-00-53-23.bpo-45863.zqQXVv.rst D Misc/NEWS.d/next/Library/2022-02-09-22-40-11.bpo-46643.aBlIx1.rst D Misc/NEWS.d/next/Library/2022-02-11-20-01-49.bpo-46333.PMTBY9.rst D Misc/NEWS.d/next/Library/2022-02-11-20-41-17.bpo-46724.eU52_N.rst D Misc/NEWS.d/next/Library/2022-02-14-21-21-49.bpo-46752.m6ldTm.rst D Misc/NEWS.d/next/Library/2022-02-15-07-39-43.bpo-46737.6Pnblt.rst D Misc/NEWS.d/next/Library/2022-02-15-11-57-53.bpo-46756.AigSPi.rst D Misc/NEWS.d/next/Library/2022-02-17-11-00-16.bpo-45390.sVhG6M.rst D Misc/NEWS.d/next/Library/2022-02-17-13-10-50.bpo-39327.ytIT7Z.rst D Misc/NEWS.d/next/Library/2022-02-18-12-10-26.bpo-46786.P0xRvS.rst D Misc/NEWS.d/next/Library/2022-02-18-22-10-30.bpo-46784.SVOQJx.rst D Misc/NEWS.d/next/Library/2022-02-20-12-59-46.bpo-46252.KG1SqA.rst D Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst D Misc/NEWS.d/next/Library/2022-02-22-15-08-30.bpo-46827.hvj38S.rst D Misc/NEWS.d/next/Library/2022-02-23-00-55-59.bpo-44886.I40Mbr.rst D Misc/NEWS.d/next/Library/2022-02-24-01-49-38.bpo-46736.NJcoWO.rst D Misc/NEWS.d/next/Library/2022-03-01-01-16-13.bpo-46848.BB01Fr.rst D Misc/NEWS.d/next/Library/2022-03-03-06-58-52.bpo-46877.BKgjpD.rst D Misc/NEWS.d/next/Library/2022-03-05-09-43-53.bpo-25707.gTlclP.rst D Misc/NEWS.d/next/Tests/2022-02-03-09-45-26.bpo-46623.vxzuhV.rst D Misc/NEWS.d/next/Tests/2022-02-07-12-40-45.bpo-46678.zfOrgL.rst D Misc/NEWS.d/next/Tests/2022-02-10-14-33-47.bpo-46708.avLfCb.rst D Misc/NEWS.d/next/Tests/2022-02-16-10-38-18.bpo-46760.O3ovJo.rst D Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst D Misc/NEWS.d/next/Windows/2022-02-04-18-02-33.bpo-46638.mSJOSX.rst D Misc/NEWS.d/next/Windows/2022-02-25-01-22-31.bpo-46567.37WEue.rst D Misc/NEWS.d/next/Windows/2022-03-04-00-24-55.bpo-46744.tneWFr.rst M Include/patchlevel.h M Lib/pydoc_data/topics.py M README.rst diff --git a/Include/patchlevel.h b/Include/patchlevel.h index a0cca238e23dfa..5668fc025ad563 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -20,10 +20,10 @@ #define PY_MINOR_VERSION 11 #define PY_MICRO_VERSION 0 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA -#define PY_RELEASE_SERIAL 5 +#define PY_RELEASE_SERIAL 6 /* Version as a string */ -#define PY_VERSION "3.11.0a5+" +#define PY_VERSION "3.11.0a6" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index cd47603e6cf248..433c905096e9eb 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Thu Feb 3 18:35:23 2022 +# Autogenerated by Sphinx on Mon Mar 7 12:29:42 2022 topics = {'assert': 'The "assert" statement\n' '**********************\n' '\n' @@ -2325,15 +2325,18 @@ 'sequence\n' '(such as a string, tuple or list) or other iterable object:\n' '\n' - ' for_stmt ::= "for" target_list "in" expression_list ":" ' - 'suite\n' + ' for_stmt ::= "for" target_list "in" starred_list ":" suite\n' ' ["else" ":" suite]\n' '\n' 'The expression list is evaluated once; it should yield an ' 'iterable\n' - 'object. An iterator is created for the result of the\n' - '"expression_list". The suite is then executed once for each ' - 'item\n' + 'object. An iterator is created for the result of the ' + '"starred_list".\n' + 'The expression list can contain starred elements ("*x, *y") that ' + 'will\n' + 'be unpacked in the final iterator (as when constructing a ' + '"tuple" or\n' + '"list" literal). The suite is then executed once for each item\n' 'provided by the iterator, in the order returned by the ' 'iterator. Each\n' 'item in turn is assigned to the target list using the standard ' @@ -2382,6 +2385,10 @@ ':= a to b do"; e.g., "list(range(3))" returns the list "[0, 1, ' '2]".\n' '\n' + 'Changed in version 3.11: Starred elements are now allowed in ' + 'the\n' + 'expression list.\n' + '\n' '\n' 'The "try" statement\n' '===================\n' @@ -5891,12 +5898,16 @@ 'sequence\n' '(such as a string, tuple or list) or other iterable object:\n' '\n' - ' for_stmt ::= "for" target_list "in" expression_list ":" suite\n' + ' for_stmt ::= "for" target_list "in" starred_list ":" suite\n' ' ["else" ":" suite]\n' '\n' 'The expression list is evaluated once; it should yield an iterable\n' - 'object. An iterator is created for the result of the\n' - '"expression_list". The suite is then executed once for each item\n' + 'object. An iterator is created for the result of the ' + '"starred_list".\n' + 'The expression list can contain starred elements ("*x, *y") that ' + 'will\n' + 'be unpacked in the final iterator (as when constructing a "tuple" or\n' + '"list" literal). The suite is then executed once for each item\n' 'provided by the iterator, in the order returned by the iterator. ' 'Each\n' 'item in turn is assigned to the target list using the standard rules\n' @@ -5933,7 +5944,10 @@ 'all by the loop. Hint: the built-in function "range()" returns an\n' 'iterator of integers suitable to emulate the effect of Pascal?s "for ' 'i\n' - ':= a to b do"; e.g., "list(range(3))" returns the list "[0, 1, 2]".\n', + ':= a to b do"; e.g., "list(range(3))" returns the list "[0, 1, 2]".\n' + '\n' + 'Changed in version 3.11: Starred elements are now allowed in the\n' + 'expression list.\n', 'formatstrings': 'Format String Syntax\n' '********************\n' '\n' @@ -6293,19 +6307,19 @@ '"\'0\'" no\n' 'longer affects the default alignment for strings.\n' '\n' - 'The *precision* is a decimal number indicating how many ' + 'The *precision* is a decimal integer indicating how many ' 'digits should\n' - 'be displayed after the decimal point for a floating point ' - 'value\n' - 'formatted with "\'f\'" and "\'F\'", or before and after the ' - 'decimal point\n' - 'for a floating point value formatted with "\'g\'" or ' - '"\'G\'". For non-\n' - 'number types the field indicates the maximum field size - ' - 'in other\n' - 'words, how many characters will be used from the field ' - 'content. The\n' - '*precision* is not allowed for integer values.\n' + 'be displayed after the decimal point for presentation types ' + '"\'f\'" and\n' + '"\'F\'", or before and after the decimal point for ' + 'presentation types\n' + '"\'g\'" or "\'G\'". For string presentation types the ' + 'field indicates the\n' + 'maximum field size - in other words, how many characters ' + 'will be used\n' + 'from the field content. The *precision* is not allowed for ' + 'integer\n' + 'presentation types.\n' '\n' 'Finally, the *type* determines how the data should be ' 'presented.\n' diff --git a/Misc/NEWS.d/3.11.0a6.rst b/Misc/NEWS.d/3.11.0a6.rst new file mode 100644 index 00000000000000..24fc5f05666a63 --- /dev/null +++ b/Misc/NEWS.d/3.11.0a6.rst @@ -0,0 +1,1205 @@ +.. bpo: 46940 +.. date: 2022-03-06-20-16-13 +.. nonce: _X47Hx +.. release date: 2022-03-07 +.. section: Core and Builtins + +Avoid overriding :exc:`AttributeError` metadata information for nested +attribute access calls. Patch by Pablo Galindo. + +.. + +.. bpo: 46927 +.. date: 2022-03-05-12-23-58 +.. nonce: URbHBi +.. section: Core and Builtins + +Include the type's name in the error message for subscripting non-generic +types. + +.. + +.. bpo: 46921 +.. date: 2022-03-05-00-43-22 +.. nonce: tyuPeB +.. section: Core and Builtins + +Support vectorcall for ``super()``. Patch by Ken Jin. + +.. + +.. bpo: 46841 +.. date: 2022-03-03-14-31-53 +.. nonce: agf-3X +.. section: Core and Builtins + +Fix incorrect handling of inline cache entries when specializing +:opcode:`BINARY_OP`. + +.. + +.. bpo: 46841 +.. date: 2022-03-03-12-36-15 +.. nonce: apPev2 +.. section: Core and Builtins + +Use an oparg to simplify the construction of helpful error messages in +:opcode:`GET_AWAITABLE`. + +.. + +.. bpo: 46903 +.. date: 2022-03-03-12-02-41 +.. nonce: OzgaFZ +.. section: Core and Builtins + +Make sure that str subclasses can be used as attribute names for instances +with virtual dictionaries. Fixes regression in 3.11alpha + +.. + +.. bpo: 46841 +.. date: 2022-03-03-10-46-13 +.. nonce: 7CkuZx +.. section: Core and Builtins + +Add more detailed specialization failure stats for :opcode:`COMPARE_OP` +followed by :opcode:`EXTENDED_ARG`. + +.. + +.. bpo: 46891 +.. date: 2022-03-02-15-04-08 +.. nonce: aIAgTD +.. section: Core and Builtins + +Fix bug introduced during 3.11alpha where subclasses of ``types.ModuleType`` +with ``__slots__`` were not initialized correctly, resulting in an +interpreter crash. + +.. + +.. bpo: 46841 +.. date: 2022-03-01-17-47-58 +.. nonce: inYQlU +.. section: Core and Builtins + +Use inline caching for :opcode:`LOAD_ATTR`, :opcode:`LOAD_METHOD`, and +:opcode:`STORE_ATTR`. + +.. + +.. bpo: 46841 +.. date: 2022-02-28-15-46-36 +.. nonce: MDQoty +.. section: Core and Builtins + +Use inline cache for :opcode:`BINARY_SUBSCR`. + +.. + +.. bpo: 46841 +.. date: 2022-02-28-12-01-04 +.. nonce: r60AMJ +.. section: Core and Builtins + +Use inline caching for :opcode:`COMPARE_OP`. + +.. + +.. bpo: 46864 +.. date: 2022-02-26-19-26-36 +.. nonce: EmLgFp +.. section: Core and Builtins + +Deprecate ``PyBytesObject.ob_shash``. It will be removed in Python 3.13. + +.. + +.. bpo: 46841 +.. date: 2022-02-25-15-18-40 +.. nonce: tmLpgC +.. section: Core and Builtins + +Use inline caching for :opcode:`UNPACK_SEQUENCE`. + +.. + +.. bpo: 46845 +.. date: 2022-02-25-14-57-21 +.. nonce: TUvaMG +.. section: Core and Builtins + +Reduces dict size by removing hash value from hash table when all inserted +keys are Unicode. For example, ``sys.getsizeof(dict.fromkeys("abcdefg"))`` +becomes 272 bytes from 352 bytes on 64bit platform. + +.. + +.. bpo: 46841 +.. date: 2022-02-25-13-18-18 +.. nonce: 86QiQu +.. section: Core and Builtins + +Use inline cache for :opcode:`LOAD_GLOBAL`. + +.. + +.. bpo: 46852 +.. date: 2022-02-25-02-01-42 +.. nonce: _3zg8D +.. section: Core and Builtins + +Rename the private undocumented ``float.__set_format__()`` method to +``float.__setformat__()`` to fix a typo introduced in Python 3.7. The method +is only used by test_float. Patch by Victor Stinner. + +.. + +.. bpo: 46852 +.. date: 2022-02-25-01-42-45 +.. nonce: nkRDvV +.. section: Core and Builtins + +Remove the undocumented private ``float.__set_format__()`` method, +previously known as ``float.__setformat__()`` in Python 3.7. Its docstring +said: "You probably don't want to use this function. It exists mainly to be +used in Python's test suite." Patch by Victor Stinner. + +.. + +.. bpo: 40116 +.. date: 2022-02-24-16-34-17 +.. nonce: AeVGG2 +.. section: Core and Builtins + +Fix regression that dict.update(other) may don't respect iterate order of +other when other is key sharing dict. + +.. + +.. bpo: 46712 +.. date: 2022-02-24-07-50-43 +.. nonce: pw7vQV +.. section: Core and Builtins + +Share global string identifiers in deep-frozen modules. + +.. + +.. bpo: 46430 +.. date: 2022-02-24-07-33-29 +.. nonce: c91TAg +.. section: Core and Builtins + +Fix memory leak in interned strings of deep-frozen modules. + +.. + +.. bpo: 46841 +.. date: 2022-02-23-18-17-30 +.. nonce: fns8HB +.. section: Core and Builtins + +Store :opcode:`BINARY_OP` caches inline using a new :opcode:`CACHE` +instruction. + +.. + +.. bpo: 45107 +.. date: 2022-02-23-15-26-02 +.. nonce: axcgHn +.. section: Core and Builtins + +Specialize ``LOAD_METHOD`` for instances with a dict. + +.. + +.. bpo: 44337 +.. date: 2022-02-22-17-19-45 +.. nonce: XA-egu +.. section: Core and Builtins + +Reduce the memory usage of specialized :opcode:`LOAD_ATTR` and +:opcode:`STORE_ATTR` instructions. + +.. + +.. bpo: 46729 +.. date: 2022-02-22-17-18-36 +.. nonce: ZwGTFq +.. section: Core and Builtins + +Add number of sub-exceptions to :meth:`BaseException.__str__`. + +.. + +.. bpo: 45885 +.. date: 2022-02-22-15-48-32 +.. nonce: W2vkaI +.. section: Core and Builtins + +Don't un-adapt :opcode:`COMPARE_OP` when collecting specialization stats. + +.. + +.. bpo: 46329 +.. date: 2022-02-22-14-03-56 +.. nonce: RX_AzJ +.. section: Core and Builtins + +Fix specialization stats gathering for :opcode:`PRECALL` instructions. + +.. + +.. bpo: 46794 +.. date: 2022-02-22-12-07-53 +.. nonce: 6WvJ9o +.. section: Core and Builtins + +Bump up the libexpat version into 2.4.6 + +.. + +.. bpo: 46823 +.. date: 2022-02-22-05-14-25 +.. nonce: z9NZC9 +.. section: Core and Builtins + +Implement a specialized combined opcode +``LOAD_FAST__LOAD_ATTR_INSTANCE_VALUE``. Patch by Dennis Sweeney. + +.. + +.. bpo: 46820 +.. date: 2022-02-21-21-55-23 +.. nonce: 4RfUZh +.. section: Core and Builtins + +Fix parsing a numeric literal immediately (without spaces) followed by "not +in" keywords, like in ``1not in x``. Now the parser only emits a warning, +not a syntax error. + +.. + +.. bpo: 46329 +.. date: 2022-02-21-10-29-20 +.. nonce: cbkt7u +.. section: Core and Builtins + +Move ``KW_NAMES`` before ``PRECALL`` instruction in call sequence. Change +``operand`` of ``CALL`` to match ``PRECALL`` for easier specialization. + +.. + +.. bpo: 46808 +.. date: 2022-02-20-23-10-14 +.. nonce: vouNSF +.. section: Core and Builtins + +Remove the ``NEXT_BLOCK`` macro from compile.c, and make the compiler +automatically generate implicit blocks when they are needed. + +.. + +.. bpo: 46329 +.. date: 2022-02-16-13-15-16 +.. nonce: 8aIuz9 +.. section: Core and Builtins + +Add ``PUSH_NULL`` instruction. This is used as a prefix when evaluating a +callable, so that the stack has the same shape for methods and other calls. +``PRECALL_FUNCTION`` and ``PRECALL_METHOD`` are merged into a single +``PRECALL`` instruction. + +There is no change in semantics. + +.. + +.. bpo: 46762 +.. date: 2022-02-15-20-26-46 +.. nonce: 1H7vab +.. section: Core and Builtins + +Fix an assert failure in debug builds when a '<', '>', or '=' is the last +character in an f-string that's missing a closing right brace. + +.. + +.. bpo: 46730 +.. date: 2022-02-14-21-04-43 +.. nonce: rYJ1w5 +.. section: Core and Builtins + +Message of AttributeError caused by getting, setting or deleting a property +without the corresponding function now mentions that the attribute is in +fact a property and also specifies type of the class that it belongs to. + +.. + +.. bpo: 46724 +.. date: 2022-02-14-14-44-06 +.. nonce: jym_K6 +.. section: Core and Builtins + +Make sure that all backwards jumps use the ``JUMP_ABSOLUTE`` instruction, +rather than ``JUMP_FORWARD`` with an argument of ``(2**32)+offset``. + +.. + +.. bpo: 46732 +.. date: 2022-02-12-11-16-40 +.. nonce: 3Z_qxd +.. section: Core and Builtins + +Correct the docstring for the :meth:`__bool__` method. Patch by Jelle +Zijlstra. + +.. + +.. bpo: 46072 +.. date: 2022-02-11-13-47-58 +.. nonce: PDS6Ke +.. section: Core and Builtins + +Add more detailed specialization failure statistics for :opcode:`BINARY_OP`. + +.. + +.. bpo: 46707 +.. date: 2022-02-10-03-13-18 +.. nonce: xeSEh0 +.. section: Core and Builtins + +Avoid potential exponential backtracking when producing some syntax errors +involving lots of brackets. Patch by Pablo Galindo. + +.. + +.. bpo: 46323 +.. date: 2022-02-10-02-29-12 +.. nonce: HK_cs0 +.. section: Core and Builtins + +:mod:`ctypes` now allocates memory on the stack instead of on the heap to +pass arguments while calling a Python callback function. Patch by Dong-hee +Na. + +.. + +.. bpo: 45923 +.. date: 2022-02-09-20-21-43 +.. nonce: tJ4gDX +.. section: Core and Builtins + +Add a quickened form of :opcode:`RESUME` that skips quickening checks. + +.. + +.. bpo: 46702 +.. date: 2022-02-09-16-36-11 +.. nonce: LcaEuC +.. section: Core and Builtins + +Specialize :opcode:`UNPACK_SEQUENCE` for :class:`tuple` and :class:`list` +unpackings. + +.. + +.. bpo: 46072 +.. date: 2022-02-07-14-38-54 +.. nonce: 6ebLyN +.. section: Core and Builtins + +Opcode pair stats are now gathered with ``--enable-pystats``. Defining +``DYNAMIC_EXECUTION_PROFILE`` or ``DXPAIRS`` no longer has any effect. + +.. + +.. bpo: 46675 +.. date: 2022-02-07-14-33-45 +.. nonce: ZPbdMp +.. section: Core and Builtins + +Allow more than 16 items in a split dict before it is combined. The limit is +now 254. + +.. + +.. bpo: 40479 +.. date: 2022-02-06-23-08-30 +.. nonce: zED3Zu +.. section: Core and Builtins + +Add a missing call to ``va_end()`` in ``Modules/_hashopenssl.c``. + +.. + +.. bpo: 46323 +.. date: 2022-02-05-14-46-21 +.. nonce: FC1OJg +.. section: Core and Builtins + +Use :c:func:`PyObject_Vectorcall` while calling ctypes callback function. +Patch by Dong-hee Na. + +.. + +.. bpo: 46615 +.. date: 2022-02-04-04-33-18 +.. nonce: puArY9 +.. section: Core and Builtins + +When iterating over sets internally in ``setobject.c``, acquire strong +references to the resulting items from the set. This prevents crashes in +corner-cases of various set operations where the set gets mutated. + +.. + +.. bpo: 45828 +.. date: 2022-01-27-14-20-18 +.. nonce: kzk4fl +.. section: Core and Builtins + +The bytecode compiler now attempts to apply runtime stack manipulations at +compile-time (whenever it is feasible to do so). + +.. + +.. bpo: 30496 +.. date: 2022-01-09-11-59-04 +.. nonce: KvuuGT +.. section: Core and Builtins + +Fixed a minor portability issue in the implementation of +:c:func:`PyLong_FromLong`, and added a fast path for single-digit integers +to :c:func:`PyLong_FromLongLong`. + +.. + +.. bpo: 25707 +.. date: 2022-03-05-09-43-53 +.. nonce: gTlclP +.. section: Library + +Fixed a file leak in :func:`xml.etree.ElementTree.iterparse` when the +iterator is not exhausted. Patch by Jacob Walls. + +.. + +.. bpo: 46877 +.. date: 2022-03-03-06-58-52 +.. nonce: BKgjpD +.. section: Library + +Export :func:`unittest.doModuleCleanups` in :mod:`unittest`. Patch by Kumar +Aditya. + +.. + +.. bpo: 46848 +.. date: 2022-03-01-01-16-13 +.. nonce: BB01Fr +.. section: Library + +For performance, use the optimized string-searching implementations from +:meth:`~bytes.find` and :meth:`~bytes.rfind` for :meth:`~mmap.find` and +:meth:`~mmap.rfind`. + +.. + +.. bpo: 46736 +.. date: 2022-02-24-01-49-38 +.. nonce: NJcoWO +.. section: Library + +:class:`~http.server.SimpleHTTPRequestHandler` now uses HTML5 grammar. Patch +by Dong-hee Na. + +.. + +.. bpo: 44886 +.. date: 2022-02-23-00-55-59 +.. nonce: I40Mbr +.. section: Library + +Inherit asyncio proactor datagram transport from +:class:`asyncio.DatagramTransport`. + +.. + +.. bpo: 46827 +.. date: 2022-02-22-15-08-30 +.. nonce: hvj38S +.. section: Library + +Support UDP sockets in :meth:`asyncio.loop.sock_connect` for selector-based +event loops. Patch by Thomas Grainger. + +.. + +.. bpo: 46811 +.. date: 2022-02-20-21-03-31 +.. nonce: 8BxgdQ +.. section: Library + +Make test suite support Expat >=2.4.5 + +.. + +.. bpo: 46252 +.. date: 2022-02-20-12-59-46 +.. nonce: KG1SqA +.. section: Library + +Raise :exc:`TypeError` if :class:`ssl.SSLSocket` is passed to +transport-based APIs. + +.. + +.. bpo: 46784 +.. date: 2022-02-18-22-10-30 +.. nonce: SVOQJx +.. section: Library + +Fix libexpat symbols collisions with user dynamically loaded or statically +linked libexpat in embedded Python. + +.. + +.. bpo: 46786 +.. date: 2022-02-18-12-10-26 +.. nonce: P0xRvS +.. section: Library + +The HTML serialisation in xml.etree.ElementTree now writes ``embed``, +``source``, ``track`` and ``wbr`` as empty tags, as defined in HTML 5. + +.. + +.. bpo: 39327 +.. date: 2022-02-17-13-10-50 +.. nonce: ytIT7Z +.. section: Library + +:func:`shutil.rmtree` can now work with VirtualBox shared folders when +running from the guest operating-system. + +.. + +.. bpo: 45390 +.. date: 2022-02-17-11-00-16 +.. nonce: sVhG6M +.. section: Library + +Propagate :exc:`asyncio.CancelledError` message from inner task to outer +awaiter. + +.. + +.. bpo: 46756 +.. date: 2022-02-15-11-57-53 +.. nonce: AigSPi +.. section: Library + +Fix a bug in :meth:`urllib.request.HTTPPasswordMgr.find_user_password` and +:meth:`urllib.request.HTTPPasswordMgrWithPriorAuth.is_authenticated` which +allowed to bypass authorization. For example, access to URI +``example.org/foobar`` was allowed if the user was authorized for URI +``example.org/foo``. + +.. + +.. bpo: 46737 +.. date: 2022-02-15-07-39-43 +.. nonce: 6Pnblt +.. section: Library + +:func:`random.gauss` and :func:`random.normalvariate` now have default +arguments. + +.. + +.. bpo: 46752 +.. date: 2022-02-14-21-21-49 +.. nonce: m6ldTm +.. section: Library + +Add task groups to asyncio (structured concurrency, inspired by Trio's +nurseries). This also introduces a change to task cancellation, where a +cancelled task can't be cancelled again until it calls .uncancel(). + +.. + +.. bpo: 46724 +.. date: 2022-02-11-20-41-17 +.. nonce: eU52_N +.. section: Library + +Fix :mod:`dis` behavior on negative jump offsets. + +.. + +.. bpo: 46333 +.. date: 2022-02-11-20-01-49 +.. nonce: PMTBY9 +.. section: Library + +The :meth:`__repr__` method of :class:`typing.ForwardRef` now includes the +``module`` parameter of :class:`typing.ForwardRef` when it is set. + +.. + +.. bpo: 46643 +.. date: 2022-02-09-22-40-11 +.. nonce: aBlIx1 +.. section: Library + +In :func:`typing.get_type_hints`, support evaluating stringified +``ParamSpecArgs`` and ``ParamSpecKwargs`` annotations. Patch by Gregory +Beauregard. + +.. + +.. bpo: 45863 +.. date: 2022-02-09-00-53-23 +.. nonce: zqQXVv +.. section: Library + +When the :mod:`tarfile` module creates a pax format archive, it will put an +integer representation of timestamps in the ustar header (if possible) for +the benefit of older unarchivers, in addition to the existing full-precision +timestamps in the pax extended header. + +.. + +.. bpo: 46066 +.. date: 2022-02-08-16-42-20 +.. nonce: m32Hl0 +.. section: Library + +Deprecate kwargs-based syntax for :class:`typing.TypedDict` definitions. It +had confusing semantics when specifying totality, and was largely unused. +Patch by Jingchen Ye. + +.. + +.. bpo: 46676 +.. date: 2022-02-07-19-20-42 +.. nonce: 3Aws1o +.. section: Library + +Make :data:`typing.ParamSpec` args and kwargs equal to themselves. Patch by +Gregory Beauregard. + +.. + +.. bpo: 46323 +.. date: 2022-02-07-13-27-59 +.. nonce: 7UENAj +.. section: Library + +``ctypes.CFUNCTYPE()`` and ``ctypes.WINFUNCTYPE()`` now fail to create the +type if its ``_argtypes_`` member contains too many arguments. Previously, +the error was only raised when calling a function. Patch by Victor Stinner. + +.. + +.. bpo: 46672 +.. date: 2022-02-07-13-15-16 +.. nonce: 4swIjx +.. section: Library + +Fix ``NameError`` in :func:`asyncio.gather` when initial type check fails. + +.. + +.. bpo: 46659 +.. date: 2022-02-06-19-13-02 +.. nonce: q-vNL9 +.. section: Library + +The :class:`calendar.LocaleTextCalendar` and +:class:`calendar.LocaleHTMLCalendar` classes now use +:func:`locale.getlocale`, instead of using :func:`locale.getdefaultlocale`, +if no locale is specified. Patch by Victor Stinner. + +.. + +.. bpo: 46659 +.. date: 2022-02-06-17-57-45 +.. nonce: zTmkoQ +.. section: Library + +The :func:`locale.getdefaultlocale` function is deprecated and will be +removed in Python 3.13. Use :func:`locale.setlocale`, +:func:`locale.getpreferredencoding(False) ` and +:func:`locale.getlocale` functions instead. Patch by Victor Stinner. + +.. + +.. bpo: 46655 +.. date: 2022-02-06-08-54-03 +.. nonce: DiLzYv +.. section: Library + +In :func:`typing.get_type_hints`, support evaluating bare stringified +``TypeAlias`` annotations. Patch by Gregory Beauregard. + +.. + +.. bpo: 45948 +.. date: 2022-02-05-18-22-05 +.. nonce: w4mCnE +.. section: Library + +Fixed a discrepancy in the C implementation of the +:mod:`xml.etree.ElementTree` module. Now, instantiating an +:class:`xml.etree.ElementTree.XMLParser` with a ``target=None`` keyword +provides a default :class:`xml.etree.ElementTree.TreeBuilder` target as the +Python implementation does. + +.. + +.. bpo: 46626 +.. date: 2022-02-03-10-22-42 +.. nonce: r2e-n_ +.. section: Library + +Expose Linux's ``IP_BIND_ADDRESS_NO_PORT`` option in :mod:`socket`. + +.. + +.. bpo: 46521 +.. date: 2022-02-01-19-34-28 +.. nonce: IMUIrs +.. section: Library + +Fix a bug in the :mod:`codeop` module that was incorrectly identifying +invalid code involving string quotes as valid code. + +.. + +.. bpo: 46571 +.. date: 2022-02-01-11-21-34 +.. nonce: L40xUJ +.. section: Library + +Improve :func:`typing.no_type_check`. + +Now it does not modify external classes and functions. We also now correctly +mark classmethods as not to be type checked. + +.. + +.. bpo: 46400 +.. date: 2022-01-30-15-16-12 +.. nonce: vweUiO +.. section: Library + +expat: Update libexpat from 2.4.1 to 2.4.4 + +.. + +.. bpo: 46556 +.. date: 2022-01-27-23-20-30 +.. nonce: tlpAgS +.. section: Library + +Deprecate undocumented support for using a :class:`pathlib.Path` object as a +context manager. + +.. + +.. bpo: 46534 +.. date: 2022-01-26-18-06-08 +.. nonce: vhzUM4 +.. section: Library + +Implement :pep:`673` :class:`typing.Self`. Patch by James Hilton-Balfe. + +.. + +.. bpo: 46522 +.. date: 2022-01-25-15-31-04 +.. nonce: tYAlX4 +.. section: Library + +Make various module ``__getattr__`` AttributeErrors more closely match a +typical AttributeError + +.. + +.. bpo: 46475 +.. date: 2022-01-23-15-35-07 +.. nonce: UCe18S +.. section: Library + +Add :data:`typing.Never` and :func:`typing.assert_never`. Patch by Jelle +Zijlstra. + +.. + +.. bpo: 46333 +.. date: 2022-01-11-15-54-15 +.. nonce: B1faiF +.. section: Library + +The :meth:`__eq__` and :meth:`__hash__` methods of +:class:`typing.ForwardRef` now honor the ``module`` parameter of +:class:`typing.ForwardRef`. Forward references from different modules are +now differentiated. + +.. + +.. bpo: 46246 +.. date: 2022-01-07-13-27-53 +.. nonce: CTLx32 +.. section: Library + +Add missing ``__slots__`` to ``importlib.metadata.DeprecatedList``. Patch by +Arie Bovenberg. + +.. + +.. bpo: 46232 +.. date: 2022-01-03-09-46-44 +.. nonce: s0KlyI +.. section: Library + +The :mod:`ssl` module now handles certificates with bit strings in DN +correctly. + +.. + +.. bpo: 46195 +.. date: 2021-12-30-21-38-51 +.. nonce: jFKGq_ +.. section: Library + +:func:`typing.get_type_hints` no longer adds ``Optional`` to parameters with +``None`` as a default. This aligns to changes to PEP 484 in +https://github.com/python/peps/pull/689 + +.. + +.. bpo: 31369 +.. date: 2021-12-27-18-28-44 +.. nonce: b9yM94 +.. section: Library + +Add :class:`~re.RegexFlag` to ``re.__all__`` and documented it. Add +:data:`~re.RegexFlag.NOFLAG` to indicate no flags being set. + +.. + +.. bpo: 45898 +.. date: 2021-11-26-10-46-09 +.. nonce: UIfhsb +.. section: Library + +:mod:`ctypes` no longer defines ``ffi_type_*`` symbols in ``cfield.c``. The +symbols have been provided by libffi for over a decade. + +.. + +.. bpo: 44953 +.. date: 2021-08-19-09-29-43 +.. nonce: 27ZyUd +.. section: Library + +Calling ``operator.itemgetter`` objects and ``operator.attrgetter`` objects +is now faster due to use of the vectorcall calling convention. + +.. + +.. bpo: 44289 +.. date: 2021-06-02-19-47-46 +.. nonce: xC5kuV +.. section: Library + +Fix an issue with :meth:`~tarfile.is_tarfile` method when using *fileobj* +argument: position in the *fileobj* was advanced forward which made it +unreadable with :meth:`tarfile.TarFile.open`. + +.. + +.. bpo: 44011 +.. date: 2021-05-02-23-44-21 +.. nonce: hd8iUO +.. section: Library + +Reimplement SSL/TLS support in asyncio, borrow the implementation from +uvloop library. + +.. + +.. bpo: 41086 +.. date: 2020-06-23-01-50-24 +.. nonce: YnOvpS +.. section: Library + +Make the :class:`configparser.ConfigParser` constructor raise +:exc:`TypeError` if the ``interpolation`` parameter is not of type +:class:`configparser.Interpolation` + +.. + +.. bpo: 29418 +.. date: 2020-03-31-20-53-11 +.. nonce: 8Qa9cQ +.. section: Library + +Implement :func:`inspect.ismethodwrapper` and fix :func:`inspect.isroutine` +for cases where methodwrapper is given. Patch by Hakan ?elik. + +.. + +.. bpo: 14156 +.. date: 2019-05-07-14-25-45 +.. nonce: 0FaHXE +.. section: Library + +argparse.FileType now supports an argument of '-' in binary mode, returning +the .buffer attribute of sys.stdin/sys.stdout as appropriate. Modes +including 'x' and 'a' are treated equivalently to 'w' when argument is '-'. +Patch contributed by Josh Rosenberg + +.. + +.. bpo: 42238 +.. date: 2022-02-03-11-24-59 +.. nonce: yJcMa8 +.. section: Documentation + +``Doc/tools/rstlint.py`` has moved to its own repository and is now packaged +on PyPI as ``sphinx-lint``. + +.. + +.. bpo: 46913 +.. date: 2022-03-03-17-36-24 +.. nonce: vxETIE +.. section: Tests + +Fix test_faulthandler.test_sigfpe() if Python is built with undefined +behavior sanitizer (UBSAN): disable UBSAN on the faulthandler_sigfpe() +function. Patch by Victor Stinner. + +.. + +.. bpo: 46760 +.. date: 2022-02-16-10-38-18 +.. nonce: O3ovJo +.. section: Tests + +Remove bytecode offsets from expected values in test.test_dis module. +Reduces the obstacles to modifying the VM or compiler. + +.. + +.. bpo: 46708 +.. date: 2022-02-10-14-33-47 +.. nonce: avLfCb +.. section: Tests + +Prevent default asyncio event loop policy modification warning after +``test_asyncio`` execution. + +.. + +.. bpo: 46678 +.. date: 2022-02-07-12-40-45 +.. nonce: zfOrgL +.. section: Tests + +The function ``make_legacy_pyc`` in ``Lib/test/support/import_helper.py`` no +longer fails when ``PYTHONPYCACHEPREFIX`` is set to a directory on a +different device from where tempfiles are stored. + +.. + +.. bpo: 46623 +.. date: 2022-02-03-09-45-26 +.. nonce: vxzuhV +.. section: Tests + +Skip test_pair() and test_speech128() of test_zlib on s390x since they fail +if zlib uses the s390x hardware accelerator. Patch by Victor Stinner. + +.. + +.. bpo: 46860 +.. date: 2022-02-25-16-19-40 +.. nonce: jfciLG +.. section: Build + +Respect `--with-suffix` when building on case-insensitive file systems. + +.. + +.. bpo: 46656 +.. date: 2022-02-25-00-51-16 +.. nonce: MD783M +.. section: Build + +Building Python now requires a C11 compiler without optional C11 features. +Patch by Victor Stinner. + +.. + +.. bpo: 46656 +.. date: 2022-02-06-14-04-20 +.. nonce: ajJjkh +.. section: Build + +Building Python now requires support for floating point Not-a-Number (NaN): +remove the ``Py_NO_NAN`` macro. Patch by by Victor Stinner. + +.. + +.. bpo: 46640 +.. date: 2022-02-04-21-26-50 +.. nonce: HXUmQp +.. section: Build + +Building Python now requires a C99 ```` header file providing a +``NAN`` constant, or the ``__builtin_nan()`` built-in function. Patch by +Victor Stinner. + +.. + +.. bpo: 46608 +.. date: 2022-02-02-11-26-46 +.. nonce: cXH9po +.. section: Build + +Exclude marshalled-frozen data if deep-freezing to save 300 KB disk space. +This includes adding a new ``is_package`` field to :c:struct:`_frozen`. +Patch by Kumar Aditya. + +.. + +.. bpo: 40280 +.. date: 2022-01-31-15-15-08 +.. nonce: r1AYNW +.. section: Build + +Fix wasm32-emscripten test failures and platform issues. - Disable syscalls +that are not supported or don't work, e.g. wait, getrusage, prlimit, +mkfifo, mknod, setres[gu]id, setgroups. - Use fd_count to cound open fds. - +Add more checks for subprocess and fork. - Add workarounds for missing +_multiprocessing and failing socket.accept(). - Enable bzip2. - Disable +large file support. - Disable signal.alarm. + +.. + +.. bpo: 46430 +.. date: 2022-01-19-11-08-32 +.. nonce: k403m_ +.. section: Build + +Intern strings in deep-frozen modules. Patch by Kumar Aditya. + +.. + +.. bpo: 46744 +.. date: 2022-03-04-00-24-55 +.. nonce: tneWFr +.. section: Windows + +The default all users install directory for ARM64 is now under the native +``Program Files`` folder, rather than ``Program Files (Arm)`` which is +intended for ARM (32-bit) files. + +.. + +.. bpo: 46567 +.. date: 2022-02-25-01-22-31 +.. nonce: 37WEue +.. section: Windows + +Adds Tcl and Tk support for Windows ARM64. This also adds IDLE to the +installation. + +.. + +.. bpo: 46638 +.. date: 2022-02-04-18-02-33 +.. nonce: mSJOSX +.. section: Windows + +Ensures registry virtualization is consistently disabled. For 3.10 and +earlier, it remains enabled (some registry writes are protected), while for +3.11 and later it is disabled (registry modifications affect all +applications). + +.. + +.. bpo: 46630 +.. date: 2022-02-03-15-47-53 +.. nonce: tREOjo +.. section: IDLE + +Make query dialogs on Windows start with a cursor in the entry box. + +.. + +.. bpo: 45447 +.. date: 2021-10-14-16-55-03 +.. nonce: FhiH5P +.. section: IDLE + +Apply IDLE syntax highlighting to `.pyi` files. Patch by Alex Waygood and +Terry Jan Reedy. + +.. + +.. bpo: 46748 +.. date: 2022-02-24-13-13-16 +.. nonce: aG1zb3 +.. section: C API + +Python's public headers no longer import ````, leaving code that +embedd/extends Python free to define ``bool``, ``true`` and ``false``. + +.. + +.. bpo: 46836 +.. date: 2022-02-23-16-13-17 +.. nonce: ZYyPF_ +.. section: C API + +Move the :c:type:`PyFrameObject` type definition (``struct _frame``) to the +internal C API ``pycore_frame.h`` header file. Patch by Victor Stinner. + +.. + +.. bpo: 45459 +.. date: 2022-02-07-18-47-00 +.. nonce: 0FCWM8 +.. section: C API + +Rename ``Include/buffer.h`` header file to ``Include/pybuffer.h`` to avoid +conflits with projects having an existing ``buffer.h`` header file. Patch by +Victor Stinner. + +.. + +.. bpo: 45412 +.. date: 2022-02-06-20-14-21 +.. nonce: XJVaGW +.. section: C API + +Remove the ``HAVE_PY_SET_53BIT_PRECISION`` macro (moved to the internal C +API). Patch by Victor Stinner. + +.. + +.. bpo: 46613 +.. date: 2022-02-02-17-58-49 +.. nonce: __ZdpH +.. section: C API + +Added function :c:func:`PyType_GetModuleByDef`, which allows accesss to +module state when a method's defining class is not available. diff --git a/Misc/NEWS.d/next/Build/2022-01-19-11-08-32.bpo-46430.k403m_.rst b/Misc/NEWS.d/next/Build/2022-01-19-11-08-32.bpo-46430.k403m_.rst deleted file mode 100644 index 21be6fc7a4691e..00000000000000 --- a/Misc/NEWS.d/next/Build/2022-01-19-11-08-32.bpo-46430.k403m_.rst +++ /dev/null @@ -1 +0,0 @@ -Intern strings in deep-frozen modules. Patch by Kumar Aditya. diff --git a/Misc/NEWS.d/next/Build/2022-01-31-15-15-08.bpo-40280.r1AYNW.rst b/Misc/NEWS.d/next/Build/2022-01-31-15-15-08.bpo-40280.r1AYNW.rst deleted file mode 100644 index bb4878c6b0ac2e..00000000000000 --- a/Misc/NEWS.d/next/Build/2022-01-31-15-15-08.bpo-40280.r1AYNW.rst +++ /dev/null @@ -1,9 +0,0 @@ -Fix wasm32-emscripten test failures and platform issues. -- Disable syscalls that are not supported or don't work, e.g. - wait, getrusage, prlimit, mkfifo, mknod, setres[gu]id, setgroups. -- Use fd_count to cound open fds. -- Add more checks for subprocess and fork. -- Add workarounds for missing _multiprocessing and failing socket.accept(). -- Enable bzip2. -- Disable large file support. -- Disable signal.alarm. diff --git a/Misc/NEWS.d/next/Build/2022-02-02-11-26-46.bpo-46608.cXH9po.rst b/Misc/NEWS.d/next/Build/2022-02-02-11-26-46.bpo-46608.cXH9po.rst deleted file mode 100644 index 13c73a614e5e86..00000000000000 --- a/Misc/NEWS.d/next/Build/2022-02-02-11-26-46.bpo-46608.cXH9po.rst +++ /dev/null @@ -1,2 +0,0 @@ -Exclude marshalled-frozen data if deep-freezing to save 300 KB disk space. This includes adding -a new ``is_package`` field to :c:struct:`_frozen`. Patch by Kumar Aditya. diff --git a/Misc/NEWS.d/next/Build/2022-02-04-21-26-50.bpo-46640.HXUmQp.rst b/Misc/NEWS.d/next/Build/2022-02-04-21-26-50.bpo-46640.HXUmQp.rst deleted file mode 100644 index 9f11c72f131eb7..00000000000000 --- a/Misc/NEWS.d/next/Build/2022-02-04-21-26-50.bpo-46640.HXUmQp.rst +++ /dev/null @@ -1,3 +0,0 @@ -Building Python now requires a C99 ```` header file providing a ``NAN`` -constant, or the ``__builtin_nan()`` built-in function. -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Build/2022-02-06-14-04-20.bpo-46656.ajJjkh.rst b/Misc/NEWS.d/next/Build/2022-02-06-14-04-20.bpo-46656.ajJjkh.rst deleted file mode 100644 index 98e37862daea7c..00000000000000 --- a/Misc/NEWS.d/next/Build/2022-02-06-14-04-20.bpo-46656.ajJjkh.rst +++ /dev/null @@ -1,2 +0,0 @@ -Building Python now requires support for floating point Not-a-Number (NaN): -remove the ``Py_NO_NAN`` macro. Patch by by Victor Stinner. diff --git a/Misc/NEWS.d/next/Build/2022-02-25-00-51-16.bpo-46656.MD783M.rst b/Misc/NEWS.d/next/Build/2022-02-25-00-51-16.bpo-46656.MD783M.rst deleted file mode 100644 index f5b789b23eea18..00000000000000 --- a/Misc/NEWS.d/next/Build/2022-02-25-00-51-16.bpo-46656.MD783M.rst +++ /dev/null @@ -1,2 +0,0 @@ -Building Python now requires a C11 compiler without optional C11 features. -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Build/2022-02-25-16-19-40.bpo-46860.jfciLG.rst b/Misc/NEWS.d/next/Build/2022-02-25-16-19-40.bpo-46860.jfciLG.rst deleted file mode 100644 index 7eab15db335e4e..00000000000000 --- a/Misc/NEWS.d/next/Build/2022-02-25-16-19-40.bpo-46860.jfciLG.rst +++ /dev/null @@ -1 +0,0 @@ -Respect `--with-suffix` when building on case-insensitive file systems. diff --git a/Misc/NEWS.d/next/C API/2022-02-02-17-58-49.bpo-46613.__ZdpH.rst b/Misc/NEWS.d/next/C API/2022-02-02-17-58-49.bpo-46613.__ZdpH.rst deleted file mode 100644 index 9d0fca7a06b89b..00000000000000 --- a/Misc/NEWS.d/next/C API/2022-02-02-17-58-49.bpo-46613.__ZdpH.rst +++ /dev/null @@ -1,2 +0,0 @@ -Added function :c:func:`PyType_GetModuleByDef`, which allows accesss to -module state when a method's defining class is not available. diff --git a/Misc/NEWS.d/next/C API/2022-02-06-20-14-21.bpo-45412.XJVaGW.rst b/Misc/NEWS.d/next/C API/2022-02-06-20-14-21.bpo-45412.XJVaGW.rst deleted file mode 100644 index 5c0cde1f2b087a..00000000000000 --- a/Misc/NEWS.d/next/C API/2022-02-06-20-14-21.bpo-45412.XJVaGW.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove the ``HAVE_PY_SET_53BIT_PRECISION`` macro (moved to the internal C API). -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2022-02-07-18-47-00.bpo-45459.0FCWM8.rst b/Misc/NEWS.d/next/C API/2022-02-07-18-47-00.bpo-45459.0FCWM8.rst deleted file mode 100644 index 711c107746d643..00000000000000 --- a/Misc/NEWS.d/next/C API/2022-02-07-18-47-00.bpo-45459.0FCWM8.rst +++ /dev/null @@ -1,3 +0,0 @@ -Rename ``Include/buffer.h`` header file to ``Include/pybuffer.h`` to avoid -conflits with projects having an existing ``buffer.h`` header file. Patch by -Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2022-02-23-16-13-17.bpo-46836.ZYyPF_.rst b/Misc/NEWS.d/next/C API/2022-02-23-16-13-17.bpo-46836.ZYyPF_.rst deleted file mode 100644 index 2867bfd518c332..00000000000000 --- a/Misc/NEWS.d/next/C API/2022-02-23-16-13-17.bpo-46836.ZYyPF_.rst +++ /dev/null @@ -1,2 +0,0 @@ -Move the :c:type:`PyFrameObject` type definition (``struct _frame``) to the -internal C API ``pycore_frame.h`` header file. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/C API/2022-02-24-13-13-16.bpo-46748.aG1zb3.rst b/Misc/NEWS.d/next/C API/2022-02-24-13-13-16.bpo-46748.aG1zb3.rst deleted file mode 100644 index b6b2db1e8ba330..00000000000000 --- a/Misc/NEWS.d/next/C API/2022-02-24-13-13-16.bpo-46748.aG1zb3.rst +++ /dev/null @@ -1,2 +0,0 @@ -Python's public headers no longer import ````, leaving code that -embedd/extends Python free to define ``bool``, ``true`` and ``false``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-01-09-11-59-04.bpo-30496.KvuuGT.rst b/Misc/NEWS.d/next/Core and Builtins/2022-01-09-11-59-04.bpo-30496.KvuuGT.rst deleted file mode 100644 index cc296841c4a4be..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-01-09-11-59-04.bpo-30496.KvuuGT.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fixed a minor portability issue in the implementation of -:c:func:`PyLong_FromLong`, and added a fast path for single-digit integers -to :c:func:`PyLong_FromLongLong`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-01-27-14-20-18.bpo-45828.kzk4fl.rst b/Misc/NEWS.d/next/Core and Builtins/2022-01-27-14-20-18.bpo-45828.kzk4fl.rst deleted file mode 100644 index 687fef035d66f8..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-01-27-14-20-18.bpo-45828.kzk4fl.rst +++ /dev/null @@ -1,2 +0,0 @@ -The bytecode compiler now attempts to apply runtime stack manipulations at -compile-time (whenever it is feasible to do so). diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-04-04-33-18.bpo-46615.puArY9.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-04-04-33-18.bpo-46615.puArY9.rst deleted file mode 100644 index 6dee92a546e339..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-04-04-33-18.bpo-46615.puArY9.rst +++ /dev/null @@ -1 +0,0 @@ -When iterating over sets internally in ``setobject.c``, acquire strong references to the resulting items from the set. This prevents crashes in corner-cases of various set operations where the set gets mutated. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-05-14-46-21.bpo-46323.FC1OJg.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-05-14-46-21.bpo-46323.FC1OJg.rst deleted file mode 100644 index 893c9589eb54bf..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-05-14-46-21.bpo-46323.FC1OJg.rst +++ /dev/null @@ -1,2 +0,0 @@ -Use :c:func:`PyObject_Vectorcall` while calling ctypes callback function. -Patch by Dong-hee Na. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-06-23-08-30.bpo-40479.zED3Zu.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-06-23-08-30.bpo-40479.zED3Zu.rst deleted file mode 100644 index 52701d53d8fe21..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-06-23-08-30.bpo-40479.zED3Zu.rst +++ /dev/null @@ -1 +0,0 @@ -Add a missing call to ``va_end()`` in ``Modules/_hashopenssl.c``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-07-14-33-45.bpo-46675.ZPbdMp.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-07-14-33-45.bpo-46675.ZPbdMp.rst deleted file mode 100644 index c3fd3fba947f8e..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-07-14-33-45.bpo-46675.ZPbdMp.rst +++ /dev/null @@ -1,2 +0,0 @@ -Allow more than 16 items in a split dict before it is combined. The limit is -now 254. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-07-14-38-54.bpo-46072.6ebLyN.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-07-14-38-54.bpo-46072.6ebLyN.rst deleted file mode 100644 index 288cb56cc205f2..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-07-14-38-54.bpo-46072.6ebLyN.rst +++ /dev/null @@ -1,2 +0,0 @@ -Opcode pair stats are now gathered with ``--enable-pystats``. Defining -``DYNAMIC_EXECUTION_PROFILE`` or ``DXPAIRS`` no longer has any effect. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-09-16-36-11.bpo-46702.LcaEuC.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-09-16-36-11.bpo-46702.LcaEuC.rst deleted file mode 100644 index 8fe758528960f7..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-09-16-36-11.bpo-46702.LcaEuC.rst +++ /dev/null @@ -1,2 +0,0 @@ -Specialize :opcode:`UNPACK_SEQUENCE` for :class:`tuple` and :class:`list` -unpackings. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-09-20-21-43.bpo-45923.tJ4gDX.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-09-20-21-43.bpo-45923.tJ4gDX.rst deleted file mode 100644 index 5ab5d59e50f009..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-09-20-21-43.bpo-45923.tJ4gDX.rst +++ /dev/null @@ -1 +0,0 @@ -Add a quickened form of :opcode:`RESUME` that skips quickening checks. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-10-02-29-12.bpo-46323.HK_cs0.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-10-02-29-12.bpo-46323.HK_cs0.rst deleted file mode 100644 index 16db7c5eaea71f..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-10-02-29-12.bpo-46323.HK_cs0.rst +++ /dev/null @@ -1,3 +0,0 @@ -:mod:`ctypes` now allocates memory on the stack instead of on the heap -to pass arguments while calling a Python callback function. -Patch by Dong-hee Na. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-10-03-13-18.bpo-46707.xeSEh0.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-10-03-13-18.bpo-46707.xeSEh0.rst deleted file mode 100644 index 4b156c4d5f68b1..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-10-03-13-18.bpo-46707.xeSEh0.rst +++ /dev/null @@ -1,2 +0,0 @@ -Avoid potential exponential backtracking when producing some syntax errors -involving lots of brackets. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-11-13-47-58.bpo-46072.PDS6Ke.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-11-13-47-58.bpo-46072.PDS6Ke.rst deleted file mode 100644 index aa9ea64c129f6f..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-11-13-47-58.bpo-46072.PDS6Ke.rst +++ /dev/null @@ -1 +0,0 @@ -Add more detailed specialization failure statistics for :opcode:`BINARY_OP`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-12-11-16-40.bpo-46732.3Z_qxd.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-12-11-16-40.bpo-46732.3Z_qxd.rst deleted file mode 100644 index 9937116bb2e7ba..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-12-11-16-40.bpo-46732.3Z_qxd.rst +++ /dev/null @@ -1,2 +0,0 @@ -Correct the docstring for the :meth:`__bool__` method. Patch by Jelle -Zijlstra. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-14-14-44-06.bpo-46724.jym_K6.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-14-14-44-06.bpo-46724.jym_K6.rst deleted file mode 100644 index 7324182677abfd..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-14-14-44-06.bpo-46724.jym_K6.rst +++ /dev/null @@ -1,2 +0,0 @@ -Make sure that all backwards jumps use the ``JUMP_ABSOLUTE`` instruction, rather -than ``JUMP_FORWARD`` with an argument of ``(2**32)+offset``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-14-21-04-43.bpo-46730.rYJ1w5.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-14-21-04-43.bpo-46730.rYJ1w5.rst deleted file mode 100644 index 473b595545370b..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-14-21-04-43.bpo-46730.rYJ1w5.rst +++ /dev/null @@ -1,3 +0,0 @@ -Message of AttributeError caused by getting, setting or deleting a property -without the corresponding function now mentions that the attribute is in fact -a property and also specifies type of the class that it belongs to. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-15-20-26-46.bpo-46762.1H7vab.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-15-20-26-46.bpo-46762.1H7vab.rst deleted file mode 100644 index cd53eb4ffaddd9..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-15-20-26-46.bpo-46762.1H7vab.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix an assert failure in debug builds when a '<', '>', or '=' is the last -character in an f-string that's missing a closing right brace. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-16-13-15-16.bpo-46329.8aIuz9.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-16-13-15-16.bpo-46329.8aIuz9.rst deleted file mode 100644 index 7a2dc99c6c79c7..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-16-13-15-16.bpo-46329.8aIuz9.rst +++ /dev/null @@ -1,6 +0,0 @@ -Add ``PUSH_NULL`` instruction. This is used as a prefix when evaluating a -callable, so that the stack has the same shape for methods and other calls. -``PRECALL_FUNCTION`` and ``PRECALL_METHOD`` are merged into a single -``PRECALL`` instruction. - -There is no change in semantics. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-20-23-10-14.bpo-46808.vouNSF.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-20-23-10-14.bpo-46808.vouNSF.rst deleted file mode 100644 index 9b6009021d63a9..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-20-23-10-14.bpo-46808.vouNSF.rst +++ /dev/null @@ -1 +0,0 @@ -Remove the ``NEXT_BLOCK`` macro from compile.c, and make the compiler automatically generate implicit blocks when they are needed. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-21-10-29-20.bpo-46329.cbkt7u.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-21-10-29-20.bpo-46329.cbkt7u.rst deleted file mode 100644 index c04db9460283e5..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-21-10-29-20.bpo-46329.cbkt7u.rst +++ /dev/null @@ -1,2 +0,0 @@ -Move ``KW_NAMES`` before ``PRECALL`` instruction in call sequence. Change -``operand`` of ``CALL`` to match ``PRECALL`` for easier specialization. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-21-21-55-23.bpo-46820.4RfUZh.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-21-21-55-23.bpo-46820.4RfUZh.rst deleted file mode 100644 index 117a84d0cbfafd..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-21-21-55-23.bpo-46820.4RfUZh.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix parsing a numeric literal immediately (without spaces) followed by "not -in" keywords, like in ``1not in x``. Now the parser only emits a warning, -not a syntax error. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-22-05-14-25.bpo-46823.z9NZC9.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-22-05-14-25.bpo-46823.z9NZC9.rst deleted file mode 100644 index 908f48d33f285f..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-22-05-14-25.bpo-46823.z9NZC9.rst +++ /dev/null @@ -1 +0,0 @@ -Implement a specialized combined opcode ``LOAD_FAST__LOAD_ATTR_INSTANCE_VALUE``. Patch by Dennis Sweeney. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-22-12-07-53.bpo-46794.6WvJ9o.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-22-12-07-53.bpo-46794.6WvJ9o.rst deleted file mode 100644 index 127387d32cb7a4..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-22-12-07-53.bpo-46794.6WvJ9o.rst +++ /dev/null @@ -1 +0,0 @@ -Bump up the libexpat version into 2.4.6 diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-22-14-03-56.bpo-46329.RX_AzJ.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-22-14-03-56.bpo-46329.RX_AzJ.rst deleted file mode 100644 index 8d1d5027ca9cdc..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-22-14-03-56.bpo-46329.RX_AzJ.rst +++ /dev/null @@ -1 +0,0 @@ -Fix specialization stats gathering for :opcode:`PRECALL` instructions. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-22-15-48-32.bpo-45885.W2vkaI.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-22-15-48-32.bpo-45885.W2vkaI.rst deleted file mode 100644 index 4339f501fd3fb2..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-22-15-48-32.bpo-45885.W2vkaI.rst +++ /dev/null @@ -1 +0,0 @@ -Don't un-adapt :opcode:`COMPARE_OP` when collecting specialization stats. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-22-17-18-36.bpo-46729.ZwGTFq.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-22-17-18-36.bpo-46729.ZwGTFq.rst deleted file mode 100644 index dbfb05fcfd9eb5..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-22-17-18-36.bpo-46729.ZwGTFq.rst +++ /dev/null @@ -1 +0,0 @@ -Add number of sub-exceptions to :meth:`BaseException.__str__`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-22-17-19-45.bpo-44337.XA-egu.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-22-17-19-45.bpo-44337.XA-egu.rst deleted file mode 100644 index 5037aa13398649..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-22-17-19-45.bpo-44337.XA-egu.rst +++ /dev/null @@ -1,2 +0,0 @@ -Reduce the memory usage of specialized :opcode:`LOAD_ATTR` and -:opcode:`STORE_ATTR` instructions. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-23-15-26-02.bpo-45107.axcgHn.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-23-15-26-02.bpo-45107.axcgHn.rst deleted file mode 100644 index 2f85e8c7017970..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-23-15-26-02.bpo-45107.axcgHn.rst +++ /dev/null @@ -1 +0,0 @@ -Specialize ``LOAD_METHOD`` for instances with a dict. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-23-18-17-30.bpo-46841.fns8HB.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-23-18-17-30.bpo-46841.fns8HB.rst deleted file mode 100644 index 5eedd34d26d575..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-23-18-17-30.bpo-46841.fns8HB.rst +++ /dev/null @@ -1,2 +0,0 @@ -Store :opcode:`BINARY_OP` caches inline using a new :opcode:`CACHE` -instruction. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-24-07-33-29.bpo-46430.c91TAg.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-24-07-33-29.bpo-46430.c91TAg.rst deleted file mode 100644 index 0ae128ba7b73b8..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-24-07-33-29.bpo-46430.c91TAg.rst +++ /dev/null @@ -1 +0,0 @@ -Fix memory leak in interned strings of deep-frozen modules. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-24-07-50-43.bpo-46712.pw7vQV.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-24-07-50-43.bpo-46712.pw7vQV.rst deleted file mode 100644 index 9dbf7e074dc615..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-24-07-50-43.bpo-46712.pw7vQV.rst +++ /dev/null @@ -1 +0,0 @@ -Share global string identifiers in deep-frozen modules. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-24-16-34-17.bpo-40116.AeVGG2.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-24-16-34-17.bpo-40116.AeVGG2.rst deleted file mode 100644 index fb3f82e880d0a7..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-24-16-34-17.bpo-40116.AeVGG2.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix regression that dict.update(other) may don't respect iterate order of -other when other is key sharing dict. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-25-01-42-45.bpo-46852.nkRDvV.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-25-01-42-45.bpo-46852.nkRDvV.rst deleted file mode 100644 index cd0049a46e5428..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-25-01-42-45.bpo-46852.nkRDvV.rst +++ /dev/null @@ -1,4 +0,0 @@ -Remove the undocumented private ``float.__set_format__()`` method, previously -known as ``float.__setformat__()`` in Python 3.7. Its docstring said: "You -probably don't want to use this function. It exists mainly to be used in -Python's test suite." Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-25-02-01-42.bpo-46852._3zg8D.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-25-02-01-42.bpo-46852._3zg8D.rst deleted file mode 100644 index 65b826473b9155..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-25-02-01-42.bpo-46852._3zg8D.rst +++ /dev/null @@ -1,3 +0,0 @@ -Rename the private undocumented ``float.__set_format__()`` method to -``float.__setformat__()`` to fix a typo introduced in Python 3.7. The method -is only used by test_float. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-25-13-18-18.bpo-46841.86QiQu.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-25-13-18-18.bpo-46841.86QiQu.rst deleted file mode 100644 index de8261fe4784ea..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-25-13-18-18.bpo-46841.86QiQu.rst +++ /dev/null @@ -1 +0,0 @@ -Use inline cache for :opcode:`LOAD_GLOBAL`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-25-14-57-21.bpo-46845.TUvaMG.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-25-14-57-21.bpo-46845.TUvaMG.rst deleted file mode 100644 index 518a67c4dd5270..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-25-14-57-21.bpo-46845.TUvaMG.rst +++ /dev/null @@ -1,3 +0,0 @@ -Reduces dict size by removing hash value from hash table when all inserted -keys are Unicode. For example, ``sys.getsizeof(dict.fromkeys("abcdefg"))`` -becomes 272 bytes from 352 bytes on 64bit platform. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-25-15-18-40.bpo-46841.tmLpgC.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-25-15-18-40.bpo-46841.tmLpgC.rst deleted file mode 100644 index fec18aa51369d4..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-25-15-18-40.bpo-46841.tmLpgC.rst +++ /dev/null @@ -1 +0,0 @@ -Use inline caching for :opcode:`UNPACK_SEQUENCE`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-26-19-26-36.bpo-46864.EmLgFp.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-26-19-26-36.bpo-46864.EmLgFp.rst deleted file mode 100644 index 82657155d72289..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-26-19-26-36.bpo-46864.EmLgFp.rst +++ /dev/null @@ -1 +0,0 @@ -Deprecate ``PyBytesObject.ob_shash``. It will be removed in Python 3.13. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-28-12-01-04.bpo-46841.r60AMJ.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-28-12-01-04.bpo-46841.r60AMJ.rst deleted file mode 100644 index bc885be5174e87..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-28-12-01-04.bpo-46841.r60AMJ.rst +++ /dev/null @@ -1 +0,0 @@ -Use inline caching for :opcode:`COMPARE_OP`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-28-15-46-36.bpo-46841.MDQoty.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-28-15-46-36.bpo-46841.MDQoty.rst deleted file mode 100644 index 97b03debcf092d..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-28-15-46-36.bpo-46841.MDQoty.rst +++ /dev/null @@ -1 +0,0 @@ -Use inline cache for :opcode:`BINARY_SUBSCR`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-01-17-47-58.bpo-46841.inYQlU.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-01-17-47-58.bpo-46841.inYQlU.rst deleted file mode 100644 index 0e7beb019f46a2..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-03-01-17-47-58.bpo-46841.inYQlU.rst +++ /dev/null @@ -1,2 +0,0 @@ -Use inline caching for :opcode:`LOAD_ATTR`, :opcode:`LOAD_METHOD`, and -:opcode:`STORE_ATTR`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-02-15-04-08.bpo-46891.aIAgTD.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-02-15-04-08.bpo-46891.aIAgTD.rst deleted file mode 100644 index 6834b08a885c12..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-03-02-15-04-08.bpo-46891.aIAgTD.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix bug introduced during 3.11alpha where subclasses of ``types.ModuleType`` -with ``__slots__`` were not initialized correctly, resulting in an -interpreter crash. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-03-10-46-13.bpo-46841.7CkuZx.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-03-10-46-13.bpo-46841.7CkuZx.rst deleted file mode 100644 index 8be83bcab3c8ec..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-03-03-10-46-13.bpo-46841.7CkuZx.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add more detailed specialization failure stats for :opcode:`COMPARE_OP` -followed by :opcode:`EXTENDED_ARG`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-03-12-02-41.bpo-46903.OzgaFZ.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-03-12-02-41.bpo-46903.OzgaFZ.rst deleted file mode 100644 index f6120ef4b8d58e..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-03-03-12-02-41.bpo-46903.OzgaFZ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Make sure that str subclasses can be used as attribute names for instances -with virtual dictionaries. Fixes regression in 3.11alpha diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-03-12-36-15.bpo-46841.apPev2.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-03-12-36-15.bpo-46841.apPev2.rst deleted file mode 100644 index 6a45e6e88241be..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-03-03-12-36-15.bpo-46841.apPev2.rst +++ /dev/null @@ -1,2 +0,0 @@ -Use an oparg to simplify the construction of helpful error messages in -:opcode:`GET_AWAITABLE`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-03-14-31-53.bpo-46841.agf-3X.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-03-14-31-53.bpo-46841.agf-3X.rst deleted file mode 100644 index 690293e97dcc37..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-03-03-14-31-53.bpo-46841.agf-3X.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix incorrect handling of inline cache entries when specializing -:opcode:`BINARY_OP`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-05-00-43-22.bpo-46921.tyuPeB.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-05-00-43-22.bpo-46921.tyuPeB.rst deleted file mode 100644 index 4ccd00b87f591e..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-03-05-00-43-22.bpo-46921.tyuPeB.rst +++ /dev/null @@ -1 +0,0 @@ -Support vectorcall for ``super()``. Patch by Ken Jin. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-05-12-23-58.bpo-46927.URbHBi.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-05-12-23-58.bpo-46927.URbHBi.rst deleted file mode 100644 index cd59fb89c3654a..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-03-05-12-23-58.bpo-46927.URbHBi.rst +++ /dev/null @@ -1,2 +0,0 @@ -Include the type's name in the error message for subscripting non-generic -types. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-06-20-16-13.bpo-46940._X47Hx.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-06-20-16-13.bpo-46940._X47Hx.rst deleted file mode 100644 index fabc9460197582..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-03-06-20-16-13.bpo-46940._X47Hx.rst +++ /dev/null @@ -1,2 +0,0 @@ -Avoid overriding :exc:`AttributeError` metadata information for nested -attribute access calls. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Documentation/2022-02-03-11-24-59.bpo-42238.yJcMa8.rst b/Misc/NEWS.d/next/Documentation/2022-02-03-11-24-59.bpo-42238.yJcMa8.rst deleted file mode 100644 index a8dffff3fcf289..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2022-02-03-11-24-59.bpo-42238.yJcMa8.rst +++ /dev/null @@ -1,2 +0,0 @@ -``Doc/tools/rstlint.py`` has moved to its own repository and is now packaged -on PyPI as ``sphinx-lint``. diff --git a/Misc/NEWS.d/next/IDLE/2021-10-14-16-55-03.bpo-45447.FhiH5P.rst b/Misc/NEWS.d/next/IDLE/2021-10-14-16-55-03.bpo-45447.FhiH5P.rst deleted file mode 100644 index 2b5170c7631d24..00000000000000 --- a/Misc/NEWS.d/next/IDLE/2021-10-14-16-55-03.bpo-45447.FhiH5P.rst +++ /dev/null @@ -1,2 +0,0 @@ -Apply IDLE syntax highlighting to `.pyi` files. Patch by Alex Waygood -and Terry Jan Reedy. diff --git a/Misc/NEWS.d/next/IDLE/2022-02-03-15-47-53.bpo-46630.tREOjo.rst b/Misc/NEWS.d/next/IDLE/2022-02-03-15-47-53.bpo-46630.tREOjo.rst deleted file mode 100644 index 81e35486eaf21e..00000000000000 --- a/Misc/NEWS.d/next/IDLE/2022-02-03-15-47-53.bpo-46630.tREOjo.rst +++ /dev/null @@ -1 +0,0 @@ -Make query dialogs on Windows start with a cursor in the entry box. diff --git a/Misc/NEWS.d/next/Library/2019-05-07-14-25-45.bpo-14156.0FaHXE.rst b/Misc/NEWS.d/next/Library/2019-05-07-14-25-45.bpo-14156.0FaHXE.rst deleted file mode 100644 index 7bfc917a2a7501..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-07-14-25-45.bpo-14156.0FaHXE.rst +++ /dev/null @@ -1,4 +0,0 @@ -argparse.FileType now supports an argument of '-' in binary mode, returning -the .buffer attribute of sys.stdin/sys.stdout as appropriate. Modes -including 'x' and 'a' are treated equivalently to 'w' when argument is '-'. -Patch contributed by Josh Rosenberg diff --git a/Misc/NEWS.d/next/Library/2020-03-31-20-53-11.bpo-29418.8Qa9cQ.rst b/Misc/NEWS.d/next/Library/2020-03-31-20-53-11.bpo-29418.8Qa9cQ.rst deleted file mode 100644 index b188ac3992d5a0..00000000000000 --- a/Misc/NEWS.d/next/Library/2020-03-31-20-53-11.bpo-29418.8Qa9cQ.rst +++ /dev/null @@ -1 +0,0 @@ -Implement :func:`inspect.ismethodwrapper` and fix :func:`inspect.isroutine` for cases where methodwrapper is given. Patch by Hakan ?elik. diff --git a/Misc/NEWS.d/next/Library/2020-06-23-01-50-24.bpo-41086.YnOvpS.rst b/Misc/NEWS.d/next/Library/2020-06-23-01-50-24.bpo-41086.YnOvpS.rst deleted file mode 100644 index 1041c0490fab73..00000000000000 --- a/Misc/NEWS.d/next/Library/2020-06-23-01-50-24.bpo-41086.YnOvpS.rst +++ /dev/null @@ -1 +0,0 @@ -Make the :class:`configparser.ConfigParser` constructor raise :exc:`TypeError` if the ``interpolation`` parameter is not of type :class:`configparser.Interpolation` diff --git a/Misc/NEWS.d/next/Library/2021-05-02-23-44-21.bpo-44011.hd8iUO.rst b/Misc/NEWS.d/next/Library/2021-05-02-23-44-21.bpo-44011.hd8iUO.rst deleted file mode 100644 index 1a48aa5ebae0c8..00000000000000 --- a/Misc/NEWS.d/next/Library/2021-05-02-23-44-21.bpo-44011.hd8iUO.rst +++ /dev/null @@ -1,2 +0,0 @@ -Reimplement SSL/TLS support in asyncio, borrow the implementation from -uvloop library. diff --git a/Misc/NEWS.d/next/Library/2021-06-02-19-47-46.bpo-44289.xC5kuV.rst b/Misc/NEWS.d/next/Library/2021-06-02-19-47-46.bpo-44289.xC5kuV.rst deleted file mode 100644 index 164138f47ae3bd..00000000000000 --- a/Misc/NEWS.d/next/Library/2021-06-02-19-47-46.bpo-44289.xC5kuV.rst +++ /dev/null @@ -1 +0,0 @@ -Fix an issue with :meth:`~tarfile.is_tarfile` method when using *fileobj* argument: position in the *fileobj* was advanced forward which made it unreadable with :meth:`tarfile.TarFile.open`. diff --git a/Misc/NEWS.d/next/Library/2021-08-19-09-29-43.bpo-44953.27ZyUd.rst b/Misc/NEWS.d/next/Library/2021-08-19-09-29-43.bpo-44953.27ZyUd.rst deleted file mode 100644 index 0eb235eca4fc01..00000000000000 --- a/Misc/NEWS.d/next/Library/2021-08-19-09-29-43.bpo-44953.27ZyUd.rst +++ /dev/null @@ -1 +0,0 @@ -Calling ``operator.itemgetter`` objects and ``operator.attrgetter`` objects is now faster due to use of the vectorcall calling convention. diff --git a/Misc/NEWS.d/next/Library/2021-11-26-10-46-09.bpo-45898.UIfhsb.rst b/Misc/NEWS.d/next/Library/2021-11-26-10-46-09.bpo-45898.UIfhsb.rst deleted file mode 100644 index 9da5c258ab7fd8..00000000000000 --- a/Misc/NEWS.d/next/Library/2021-11-26-10-46-09.bpo-45898.UIfhsb.rst +++ /dev/null @@ -1,2 +0,0 @@ -:mod:`ctypes` no longer defines ``ffi_type_*`` symbols in ``cfield.c``. The -symbols have been provided by libffi for over a decade. diff --git a/Misc/NEWS.d/next/Library/2021-12-27-18-28-44.bpo-31369.b9yM94.rst b/Misc/NEWS.d/next/Library/2021-12-27-18-28-44.bpo-31369.b9yM94.rst deleted file mode 100644 index 2bb9e62de1f40e..00000000000000 --- a/Misc/NEWS.d/next/Library/2021-12-27-18-28-44.bpo-31369.b9yM94.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add :class:`~re.RegexFlag` to ``re.__all__`` and documented it. Add -:data:`~re.RegexFlag.NOFLAG` to indicate no flags being set. diff --git a/Misc/NEWS.d/next/Library/2021-12-30-21-38-51.bpo-46195.jFKGq_.rst b/Misc/NEWS.d/next/Library/2021-12-30-21-38-51.bpo-46195.jFKGq_.rst deleted file mode 100644 index 03ea46c3a83f13..00000000000000 --- a/Misc/NEWS.d/next/Library/2021-12-30-21-38-51.bpo-46195.jFKGq_.rst +++ /dev/null @@ -1,3 +0,0 @@ -:func:`typing.get_type_hints` no longer adds ``Optional`` to parameters with -``None`` as a default. This aligns to changes to PEP 484 in -https://github.com/python/peps/pull/689 diff --git a/Misc/NEWS.d/next/Library/2022-01-03-09-46-44.bpo-46232.s0KlyI.rst b/Misc/NEWS.d/next/Library/2022-01-03-09-46-44.bpo-46232.s0KlyI.rst deleted file mode 100644 index e252449199a057..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-03-09-46-44.bpo-46232.s0KlyI.rst +++ /dev/null @@ -1,2 +0,0 @@ -The :mod:`ssl` module now handles certificates with bit strings in DN -correctly. diff --git a/Misc/NEWS.d/next/Library/2022-01-07-13-27-53.bpo-46246.CTLx32.rst b/Misc/NEWS.d/next/Library/2022-01-07-13-27-53.bpo-46246.CTLx32.rst deleted file mode 100644 index 48501714394594..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-07-13-27-53.bpo-46246.CTLx32.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add missing ``__slots__`` to ``importlib.metadata.DeprecatedList``. Patch by -Arie Bovenberg. diff --git a/Misc/NEWS.d/next/Library/2022-01-11-15-54-15.bpo-46333.B1faiF.rst b/Misc/NEWS.d/next/Library/2022-01-11-15-54-15.bpo-46333.B1faiF.rst deleted file mode 100644 index ec3c6d54ee499c..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-11-15-54-15.bpo-46333.B1faiF.rst +++ /dev/null @@ -1,4 +0,0 @@ -The :meth:`__eq__` and :meth:`__hash__` methods of -:class:`typing.ForwardRef` now honor the ``module`` parameter of -:class:`typing.ForwardRef`. Forward references from different -modules are now differentiated. diff --git a/Misc/NEWS.d/next/Library/2022-01-23-15-35-07.bpo-46475.UCe18S.rst b/Misc/NEWS.d/next/Library/2022-01-23-15-35-07.bpo-46475.UCe18S.rst deleted file mode 100644 index 99d5e2b42c4f68..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-23-15-35-07.bpo-46475.UCe18S.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add :data:`typing.Never` and :func:`typing.assert_never`. Patch by Jelle -Zijlstra. diff --git a/Misc/NEWS.d/next/Library/2022-01-25-15-31-04.bpo-46522.tYAlX4.rst b/Misc/NEWS.d/next/Library/2022-01-25-15-31-04.bpo-46522.tYAlX4.rst deleted file mode 100644 index 999863adb9b314..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-25-15-31-04.bpo-46522.tYAlX4.rst +++ /dev/null @@ -1 +0,0 @@ -Make various module ``__getattr__`` AttributeErrors more closely match a typical AttributeError diff --git a/Misc/NEWS.d/next/Library/2022-01-26-18-06-08.bpo-46534.vhzUM4.rst b/Misc/NEWS.d/next/Library/2022-01-26-18-06-08.bpo-46534.vhzUM4.rst deleted file mode 100644 index 35a70aae170045..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-26-18-06-08.bpo-46534.vhzUM4.rst +++ /dev/null @@ -1,2 +0,0 @@ -Implement :pep:`673` :class:`typing.Self`. -Patch by James Hilton-Balfe. diff --git a/Misc/NEWS.d/next/Library/2022-01-27-23-20-30.bpo-46556.tlpAgS.rst b/Misc/NEWS.d/next/Library/2022-01-27-23-20-30.bpo-46556.tlpAgS.rst deleted file mode 100644 index 1209e0e2bd8b0e..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-27-23-20-30.bpo-46556.tlpAgS.rst +++ /dev/null @@ -1,2 +0,0 @@ -Deprecate undocumented support for using a :class:`pathlib.Path` object as a -context manager. diff --git a/Misc/NEWS.d/next/Library/2022-01-30-15-16-12.bpo-46400.vweUiO.rst b/Misc/NEWS.d/next/Library/2022-01-30-15-16-12.bpo-46400.vweUiO.rst deleted file mode 100644 index 9c1f24c0e5171b..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-30-15-16-12.bpo-46400.vweUiO.rst +++ /dev/null @@ -1 +0,0 @@ -expat: Update libexpat from 2.4.1 to 2.4.4 diff --git a/Misc/NEWS.d/next/Library/2022-02-01-11-21-34.bpo-46571.L40xUJ.rst b/Misc/NEWS.d/next/Library/2022-02-01-11-21-34.bpo-46571.L40xUJ.rst deleted file mode 100644 index f56c9e4fd76d34..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-01-11-21-34.bpo-46571.L40xUJ.rst +++ /dev/null @@ -1,4 +0,0 @@ -Improve :func:`typing.no_type_check`. - -Now it does not modify external classes and functions. -We also now correctly mark classmethods as not to be type checked. diff --git a/Misc/NEWS.d/next/Library/2022-02-01-19-34-28.bpo-46521.IMUIrs.rst b/Misc/NEWS.d/next/Library/2022-02-01-19-34-28.bpo-46521.IMUIrs.rst deleted file mode 100644 index 4e9fa08d4dfbc2..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-01-19-34-28.bpo-46521.IMUIrs.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a bug in the :mod:`codeop` module that was incorrectly identifying -invalid code involving string quotes as valid code. diff --git a/Misc/NEWS.d/next/Library/2022-02-03-10-22-42.bpo-46626.r2e-n_.rst b/Misc/NEWS.d/next/Library/2022-02-03-10-22-42.bpo-46626.r2e-n_.rst deleted file mode 100644 index aaca73d36cdc62..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-03-10-22-42.bpo-46626.r2e-n_.rst +++ /dev/null @@ -1 +0,0 @@ -Expose Linux's ``IP_BIND_ADDRESS_NO_PORT`` option in :mod:`socket`. diff --git a/Misc/NEWS.d/next/Library/2022-02-05-18-22-05.bpo-45948.w4mCnE.rst b/Misc/NEWS.d/next/Library/2022-02-05-18-22-05.bpo-45948.w4mCnE.rst deleted file mode 100644 index 42dc114b5ad60b..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-05-18-22-05.bpo-45948.w4mCnE.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fixed a discrepancy in the C implementation of the -:mod:`xml.etree.ElementTree` module. Now, instantiating an -:class:`xml.etree.ElementTree.XMLParser` with a ``target=None`` -keyword provides a default :class:`xml.etree.ElementTree.TreeBuilder` -target as the Python implementation does. diff --git a/Misc/NEWS.d/next/Library/2022-02-06-08-54-03.bpo-46655.DiLzYv.rst b/Misc/NEWS.d/next/Library/2022-02-06-08-54-03.bpo-46655.DiLzYv.rst deleted file mode 100644 index 183e064b8308ef..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-06-08-54-03.bpo-46655.DiLzYv.rst +++ /dev/null @@ -1 +0,0 @@ -In :func:`typing.get_type_hints`, support evaluating bare stringified ``TypeAlias`` annotations. Patch by Gregory Beauregard. diff --git a/Misc/NEWS.d/next/Library/2022-02-06-17-57-45.bpo-46659.zTmkoQ.rst b/Misc/NEWS.d/next/Library/2022-02-06-17-57-45.bpo-46659.zTmkoQ.rst deleted file mode 100644 index 6fd9a53c260f4b..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-06-17-57-45.bpo-46659.zTmkoQ.rst +++ /dev/null @@ -1,4 +0,0 @@ -The :func:`locale.getdefaultlocale` function is deprecated and will be removed -in Python 3.13. Use :func:`locale.setlocale`, -:func:`locale.getpreferredencoding(False) ` and -:func:`locale.getlocale` functions instead. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2022-02-06-19-13-02.bpo-46659.q-vNL9.rst b/Misc/NEWS.d/next/Library/2022-02-06-19-13-02.bpo-46659.q-vNL9.rst deleted file mode 100644 index 2e30de17626b2e..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-06-19-13-02.bpo-46659.q-vNL9.rst +++ /dev/null @@ -1,4 +0,0 @@ -The :class:`calendar.LocaleTextCalendar` and -:class:`calendar.LocaleHTMLCalendar` classes now use :func:`locale.getlocale`, -instead of using :func:`locale.getdefaultlocale`, if no locale is specified. -Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2022-02-07-13-15-16.bpo-46672.4swIjx.rst b/Misc/NEWS.d/next/Library/2022-02-07-13-15-16.bpo-46672.4swIjx.rst deleted file mode 100644 index 9a76c29a334d8c..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-07-13-15-16.bpo-46672.4swIjx.rst +++ /dev/null @@ -1 +0,0 @@ -Fix ``NameError`` in :func:`asyncio.gather` when initial type check fails. diff --git a/Misc/NEWS.d/next/Library/2022-02-07-13-27-59.bpo-46323.7UENAj.rst b/Misc/NEWS.d/next/Library/2022-02-07-13-27-59.bpo-46323.7UENAj.rst deleted file mode 100644 index e144450f2527a9..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-07-13-27-59.bpo-46323.7UENAj.rst +++ /dev/null @@ -1,3 +0,0 @@ -``ctypes.CFUNCTYPE()`` and ``ctypes.WINFUNCTYPE()`` now fail to create the type -if its ``_argtypes_`` member contains too many arguments. Previously, the error -was only raised when calling a function. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2022-02-07-19-20-42.bpo-46676.3Aws1o.rst b/Misc/NEWS.d/next/Library/2022-02-07-19-20-42.bpo-46676.3Aws1o.rst deleted file mode 100644 index 408412e6ff15d3..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-07-19-20-42.bpo-46676.3Aws1o.rst +++ /dev/null @@ -1 +0,0 @@ -Make :data:`typing.ParamSpec` args and kwargs equal to themselves. Patch by Gregory Beauregard. diff --git a/Misc/NEWS.d/next/Library/2022-02-08-16-42-20.bpo-46066.m32Hl0.rst b/Misc/NEWS.d/next/Library/2022-02-08-16-42-20.bpo-46066.m32Hl0.rst deleted file mode 100644 index d13d9421e748b8..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-08-16-42-20.bpo-46066.m32Hl0.rst +++ /dev/null @@ -1,3 +0,0 @@ -Deprecate kwargs-based syntax for :class:`typing.TypedDict` definitions. -It had confusing semantics when specifying totality, and was largely unused. -Patch by Jingchen Ye. diff --git a/Misc/NEWS.d/next/Library/2022-02-09-00-53-23.bpo-45863.zqQXVv.rst b/Misc/NEWS.d/next/Library/2022-02-09-00-53-23.bpo-45863.zqQXVv.rst deleted file mode 100644 index 6a52dacb474b72..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-09-00-53-23.bpo-45863.zqQXVv.rst +++ /dev/null @@ -1 +0,0 @@ -When the :mod:`tarfile` module creates a pax format archive, it will put an integer representation of timestamps in the ustar header (if possible) for the benefit of older unarchivers, in addition to the existing full-precision timestamps in the pax extended header. diff --git a/Misc/NEWS.d/next/Library/2022-02-09-22-40-11.bpo-46643.aBlIx1.rst b/Misc/NEWS.d/next/Library/2022-02-09-22-40-11.bpo-46643.aBlIx1.rst deleted file mode 100644 index 6edcfdfd814fd8..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-09-22-40-11.bpo-46643.aBlIx1.rst +++ /dev/null @@ -1,3 +0,0 @@ -In :func:`typing.get_type_hints`, support evaluating stringified -``ParamSpecArgs`` and ``ParamSpecKwargs`` annotations. Patch by -Gregory Beauregard. diff --git a/Misc/NEWS.d/next/Library/2022-02-11-20-01-49.bpo-46333.PMTBY9.rst b/Misc/NEWS.d/next/Library/2022-02-11-20-01-49.bpo-46333.PMTBY9.rst deleted file mode 100644 index 669217e25f789d..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-11-20-01-49.bpo-46333.PMTBY9.rst +++ /dev/null @@ -1,3 +0,0 @@ -The :meth:`__repr__` method of :class:`typing.ForwardRef` now -includes the ``module`` parameter of :class:`typing.ForwardRef` -when it is set. diff --git a/Misc/NEWS.d/next/Library/2022-02-11-20-41-17.bpo-46724.eU52_N.rst b/Misc/NEWS.d/next/Library/2022-02-11-20-41-17.bpo-46724.eU52_N.rst deleted file mode 100644 index 9ac8c17deb7a2d..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-11-20-41-17.bpo-46724.eU52_N.rst +++ /dev/null @@ -1 +0,0 @@ -Fix :mod:`dis` behavior on negative jump offsets. diff --git a/Misc/NEWS.d/next/Library/2022-02-14-21-21-49.bpo-46752.m6ldTm.rst b/Misc/NEWS.d/next/Library/2022-02-14-21-21-49.bpo-46752.m6ldTm.rst deleted file mode 100644 index f460600c8c9dde..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-14-21-21-49.bpo-46752.m6ldTm.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add task groups to asyncio (structured concurrency, inspired by Trio's nurseries). -This also introduces a change to task cancellation, where a cancelled task can't be cancelled again until it calls .uncancel(). diff --git a/Misc/NEWS.d/next/Library/2022-02-15-07-39-43.bpo-46737.6Pnblt.rst b/Misc/NEWS.d/next/Library/2022-02-15-07-39-43.bpo-46737.6Pnblt.rst deleted file mode 100644 index c3f693aeb759eb..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-15-07-39-43.bpo-46737.6Pnblt.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`random.gauss` and :func:`random.normalvariate` now have default -arguments. diff --git a/Misc/NEWS.d/next/Library/2022-02-15-11-57-53.bpo-46756.AigSPi.rst b/Misc/NEWS.d/next/Library/2022-02-15-11-57-53.bpo-46756.AigSPi.rst deleted file mode 100644 index 1660640c5d3fb8..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-15-11-57-53.bpo-46756.AigSPi.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fix a bug in :meth:`urllib.request.HTTPPasswordMgr.find_user_password` and -:meth:`urllib.request.HTTPPasswordMgrWithPriorAuth.is_authenticated` which -allowed to bypass authorization. For example, access to URI -``example.org/foobar`` was allowed if the user was authorized for URI -``example.org/foo``. diff --git a/Misc/NEWS.d/next/Library/2022-02-17-11-00-16.bpo-45390.sVhG6M.rst b/Misc/NEWS.d/next/Library/2022-02-17-11-00-16.bpo-45390.sVhG6M.rst deleted file mode 100644 index 5f1eafa5f25dd8..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-17-11-00-16.bpo-45390.sVhG6M.rst +++ /dev/null @@ -1,2 +0,0 @@ -Propagate :exc:`asyncio.CancelledError` message from inner task to outer -awaiter. diff --git a/Misc/NEWS.d/next/Library/2022-02-17-13-10-50.bpo-39327.ytIT7Z.rst b/Misc/NEWS.d/next/Library/2022-02-17-13-10-50.bpo-39327.ytIT7Z.rst deleted file mode 100644 index fc6e8250922ffe..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-17-13-10-50.bpo-39327.ytIT7Z.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`shutil.rmtree` can now work with VirtualBox shared folders when -running from the guest operating-system. diff --git a/Misc/NEWS.d/next/Library/2022-02-18-12-10-26.bpo-46786.P0xRvS.rst b/Misc/NEWS.d/next/Library/2022-02-18-12-10-26.bpo-46786.P0xRvS.rst deleted file mode 100644 index e0384a8558dee0..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-18-12-10-26.bpo-46786.P0xRvS.rst +++ /dev/null @@ -1,2 +0,0 @@ -The HTML serialisation in xml.etree.ElementTree now writes ``embed``, -``source``, ``track`` and ``wbr`` as empty tags, as defined in HTML 5. diff --git a/Misc/NEWS.d/next/Library/2022-02-18-22-10-30.bpo-46784.SVOQJx.rst b/Misc/NEWS.d/next/Library/2022-02-18-22-10-30.bpo-46784.SVOQJx.rst deleted file mode 100644 index d190816637ae8f..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-18-22-10-30.bpo-46784.SVOQJx.rst +++ /dev/null @@ -1 +0,0 @@ -Fix libexpat symbols collisions with user dynamically loaded or statically linked libexpat in embedded Python. diff --git a/Misc/NEWS.d/next/Library/2022-02-20-12-59-46.bpo-46252.KG1SqA.rst b/Misc/NEWS.d/next/Library/2022-02-20-12-59-46.bpo-46252.KG1SqA.rst deleted file mode 100644 index a15e7aaaa33899..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-20-12-59-46.bpo-46252.KG1SqA.rst +++ /dev/null @@ -1,2 +0,0 @@ -Raise :exc:`TypeError` if :class:`ssl.SSLSocket` is passed to -transport-based APIs. diff --git a/Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst b/Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst deleted file mode 100644 index 6969bd1898f658..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst +++ /dev/null @@ -1 +0,0 @@ -Make test suite support Expat >=2.4.5 diff --git a/Misc/NEWS.d/next/Library/2022-02-22-15-08-30.bpo-46827.hvj38S.rst b/Misc/NEWS.d/next/Library/2022-02-22-15-08-30.bpo-46827.hvj38S.rst deleted file mode 100644 index 259686ab1ddda1..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-22-15-08-30.bpo-46827.hvj38S.rst +++ /dev/null @@ -1 +0,0 @@ -Support UDP sockets in :meth:`asyncio.loop.sock_connect` for selector-based event loops. Patch by Thomas Grainger. diff --git a/Misc/NEWS.d/next/Library/2022-02-23-00-55-59.bpo-44886.I40Mbr.rst b/Misc/NEWS.d/next/Library/2022-02-23-00-55-59.bpo-44886.I40Mbr.rst deleted file mode 100644 index be223ddd58ba19..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-23-00-55-59.bpo-44886.I40Mbr.rst +++ /dev/null @@ -1,2 +0,0 @@ -Inherit asyncio proactor datagram transport from -:class:`asyncio.DatagramTransport`. diff --git a/Misc/NEWS.d/next/Library/2022-02-24-01-49-38.bpo-46736.NJcoWO.rst b/Misc/NEWS.d/next/Library/2022-02-24-01-49-38.bpo-46736.NJcoWO.rst deleted file mode 100644 index fca7780b82e9d7..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-24-01-49-38.bpo-46736.NJcoWO.rst +++ /dev/null @@ -1,2 +0,0 @@ -:class:`~http.server.SimpleHTTPRequestHandler` now uses HTML5 grammar. Patch -by Dong-hee Na. diff --git a/Misc/NEWS.d/next/Library/2022-03-01-01-16-13.bpo-46848.BB01Fr.rst b/Misc/NEWS.d/next/Library/2022-03-01-01-16-13.bpo-46848.BB01Fr.rst deleted file mode 100644 index bd20a843ab6ced..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-01-01-16-13.bpo-46848.BB01Fr.rst +++ /dev/null @@ -1,3 +0,0 @@ -For performance, use the optimized string-searching implementations -from :meth:`~bytes.find` and :meth:`~bytes.rfind` -for :meth:`~mmap.find` and :meth:`~mmap.rfind`. diff --git a/Misc/NEWS.d/next/Library/2022-03-03-06-58-52.bpo-46877.BKgjpD.rst b/Misc/NEWS.d/next/Library/2022-03-03-06-58-52.bpo-46877.BKgjpD.rst deleted file mode 100644 index 6738519377f4ad..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-03-06-58-52.bpo-46877.BKgjpD.rst +++ /dev/null @@ -1 +0,0 @@ -Export :func:`unittest.doModuleCleanups` in :mod:`unittest`. Patch by Kumar Aditya. diff --git a/Misc/NEWS.d/next/Library/2022-03-05-09-43-53.bpo-25707.gTlclP.rst b/Misc/NEWS.d/next/Library/2022-03-05-09-43-53.bpo-25707.gTlclP.rst deleted file mode 100644 index a59f0a7657ff23..00000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-05-09-43-53.bpo-25707.gTlclP.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed a file leak in :func:`xml.etree.ElementTree.iterparse` when the -iterator is not exhausted. Patch by Jacob Walls. diff --git a/Misc/NEWS.d/next/Tests/2022-02-03-09-45-26.bpo-46623.vxzuhV.rst b/Misc/NEWS.d/next/Tests/2022-02-03-09-45-26.bpo-46623.vxzuhV.rst deleted file mode 100644 index be085c067a3763..00000000000000 --- a/Misc/NEWS.d/next/Tests/2022-02-03-09-45-26.bpo-46623.vxzuhV.rst +++ /dev/null @@ -1,2 +0,0 @@ -Skip test_pair() and test_speech128() of test_zlib on s390x since they fail -if zlib uses the s390x hardware accelerator. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Tests/2022-02-07-12-40-45.bpo-46678.zfOrgL.rst b/Misc/NEWS.d/next/Tests/2022-02-07-12-40-45.bpo-46678.zfOrgL.rst deleted file mode 100644 index e369cb1f67baf7..00000000000000 --- a/Misc/NEWS.d/next/Tests/2022-02-07-12-40-45.bpo-46678.zfOrgL.rst +++ /dev/null @@ -1,3 +0,0 @@ -The function ``make_legacy_pyc`` in ``Lib/test/support/import_helper.py`` no -longer fails when ``PYTHONPYCACHEPREFIX`` is set to a directory on a -different device from where tempfiles are stored. diff --git a/Misc/NEWS.d/next/Tests/2022-02-10-14-33-47.bpo-46708.avLfCb.rst b/Misc/NEWS.d/next/Tests/2022-02-10-14-33-47.bpo-46708.avLfCb.rst deleted file mode 100644 index 119107a8fb96cc..00000000000000 --- a/Misc/NEWS.d/next/Tests/2022-02-10-14-33-47.bpo-46708.avLfCb.rst +++ /dev/null @@ -1,2 +0,0 @@ -Prevent default asyncio event loop policy modification warning after -``test_asyncio`` execution. diff --git a/Misc/NEWS.d/next/Tests/2022-02-16-10-38-18.bpo-46760.O3ovJo.rst b/Misc/NEWS.d/next/Tests/2022-02-16-10-38-18.bpo-46760.O3ovJo.rst deleted file mode 100644 index c7dfc7c5599399..00000000000000 --- a/Misc/NEWS.d/next/Tests/2022-02-16-10-38-18.bpo-46760.O3ovJo.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove bytecode offsets from expected values in test.test_dis module. -Reduces the obstacles to modifying the VM or compiler. diff --git a/Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst b/Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst deleted file mode 100644 index 65fed1c249d874..00000000000000 --- a/Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix test_faulthandler.test_sigfpe() if Python is built with undefined -behavior sanitizer (UBSAN): disable UBSAN on the faulthandler_sigfpe() -function. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Windows/2022-02-04-18-02-33.bpo-46638.mSJOSX.rst b/Misc/NEWS.d/next/Windows/2022-02-04-18-02-33.bpo-46638.mSJOSX.rst deleted file mode 100644 index 536aae68f8329d..00000000000000 --- a/Misc/NEWS.d/next/Windows/2022-02-04-18-02-33.bpo-46638.mSJOSX.rst +++ /dev/null @@ -1,4 +0,0 @@ -Ensures registry virtualization is consistently disabled. For 3.10 and -earlier, it remains enabled (some registry writes are protected), while for -3.11 and later it is disabled (registry modifications affect all -applications). diff --git a/Misc/NEWS.d/next/Windows/2022-02-25-01-22-31.bpo-46567.37WEue.rst b/Misc/NEWS.d/next/Windows/2022-02-25-01-22-31.bpo-46567.37WEue.rst deleted file mode 100644 index 10a2b764b7fce0..00000000000000 --- a/Misc/NEWS.d/next/Windows/2022-02-25-01-22-31.bpo-46567.37WEue.rst +++ /dev/null @@ -1,2 +0,0 @@ -Adds Tcl and Tk support for Windows ARM64. This also adds IDLE to the -installation. diff --git a/Misc/NEWS.d/next/Windows/2022-03-04-00-24-55.bpo-46744.tneWFr.rst b/Misc/NEWS.d/next/Windows/2022-03-04-00-24-55.bpo-46744.tneWFr.rst deleted file mode 100644 index 25f9e7a04b08db..00000000000000 --- a/Misc/NEWS.d/next/Windows/2022-03-04-00-24-55.bpo-46744.tneWFr.rst +++ /dev/null @@ -1,3 +0,0 @@ -The default all users install directory for ARM64 is now under the native -``Program Files`` folder, rather than ``Program Files (Arm)`` which is -intended for ARM (32-bit) files. diff --git a/README.rst b/README.rst index bd80772393375a..2b1bfadcccfa03 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -This is Python version 3.11.0 alpha 5 +This is Python version 3.11.0 alpha 6 ===================================== .. image:: https://github.com/python/cpython/workflows/Tests/badge.svg From webhook-mailer at python.org Mon Mar 7 13:23:39 2022 From: webhook-mailer at python.org (zooba) Date: Mon, 07 Mar 2022 18:23:39 -0000 Subject: [Python-checkins] bpo-44549: Update bzip2 to 1.0.8 in Windows builds to mitigate CVE-2016-3189 and CVE-2019-12900 (GH-31731) Message-ID: https://github.com/python/cpython/commit/105b9ac00174d7bcc653f9e9dc5052215e197c77 commit: 105b9ac00174d7bcc653f9e9dc5052215e197c77 branch: main author: Steve Dower committer: zooba date: 2022-03-07T18:23:29Z summary: bpo-44549: Update bzip2 to 1.0.8 in Windows builds to mitigate CVE-2016-3189 and CVE-2019-12900 (GH-31731) files: A Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst M PCbuild/get_externals.bat M PCbuild/python.props M PCbuild/readme.txt diff --git a/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst b/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst new file mode 100644 index 0000000000000..0f1ef9af6c617 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst @@ -0,0 +1,2 @@ +Update bzip2 to 1.0.8 in Windows builds to mitigate CVE-2016-3189 and +CVE-2019-12900 diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index d4e052ef32c82..b8279e2c7892a 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -51,7 +51,7 @@ if NOT DEFINED PYTHON ( echo.Fetching external libraries... set libraries= -set libraries=%libraries% bzip2-1.0.6 +set libraries=%libraries% bzip2-1.0.8 if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.4.2 if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1m set libraries=%libraries% sqlite-3.37.2.0 diff --git a/PCbuild/python.props b/PCbuild/python.props index c614c151c9034..71531b5a23611 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -62,7 +62,7 @@ $([System.IO.Path]::GetFullPath(`$(PySourcePath)externals`)) $(ExternalsDir)\ $(ExternalsDir)sqlite-3.37.2.0\ - $(ExternalsDir)bzip2-1.0.6\ + $(ExternalsDir)bzip2-1.0.8\ $(ExternalsDir)xz-5.2.2\ $(ExternalsDir)libffi-3.4.2\ $(ExternalsDir)libffi-3.4.2\$(ArchName)\ diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index 9f5a513445d5f..69531f065561e 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -162,7 +162,7 @@ interpreter, but they do implement several major features. See the about getting the source for building these libraries. The sub-projects are: _bz2 - Python wrapper for version 1.0.6 of the libbzip2 compression library + Python wrapper for version 1.0.8 of the libbzip2 compression library Homepage: http://www.bzip.org/ _lzma From webhook-mailer at python.org Mon Mar 7 14:15:33 2022 From: webhook-mailer at python.org (zooba) Date: Mon, 07 Mar 2022 19:15:33 -0000 Subject: [Python-checkins] bpo-44549: Update bzip2 to 1.0.8 in Windows builds to mitigate CVE-2016-3189 and CVE-2019-12900 (GH-31732) Message-ID: https://github.com/python/cpython/commit/58d576a43cb1800dd68f06a429d7d41f746a8c01 commit: 58d576a43cb1800dd68f06a429d7d41f746a8c01 branch: 3.10 author: Steve Dower committer: zooba date: 2022-03-07T19:15:04Z summary: bpo-44549: Update bzip2 to 1.0.8 in Windows builds to mitigate CVE-2016-3189 and CVE-2019-12900 (GH-31732) files: A Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst M PCbuild/get_externals.bat M PCbuild/python.props M PCbuild/readme.txt diff --git a/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst b/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst new file mode 100644 index 0000000000000..0f1ef9af6c617 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst @@ -0,0 +1,2 @@ +Update bzip2 to 1.0.8 in Windows builds to mitigate CVE-2016-3189 and +CVE-2019-12900 diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index accc464f7c204..462e0db361d09 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -51,7 +51,7 @@ if NOT DEFINED PYTHON ( echo.Fetching external libraries... set libraries= -set libraries=%libraries% bzip2-1.0.6 +set libraries=%libraries% bzip2-1.0.8 if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.3.0 if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1m set libraries=%libraries% sqlite-3.37.2.0 diff --git a/PCbuild/python.props b/PCbuild/python.props index 99d448fc1da95..eddb65879d3ab 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -58,7 +58,7 @@ $([System.IO.Path]::GetFullPath(`$(PySourcePath)externals`)) $(ExternalsDir)\ $(ExternalsDir)sqlite-3.37.2.0\ - $(ExternalsDir)bzip2-1.0.6\ + $(ExternalsDir)bzip2-1.0.8\ $(ExternalsDir)xz-5.2.2\ $(ExternalsDir)libffi-3.3.0\ $(ExternalsDir)libffi-3.3.0\$(ArchName)\ diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index 477f28611b93f..1ea8bebc15edf 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -161,7 +161,7 @@ interpreter, but they do implement several major features. See the about getting the source for building these libraries. The sub-projects are: _bz2 - Python wrapper for version 1.0.6 of the libbzip2 compression library + Python wrapper for version 1.0.8 of the libbzip2 compression library Homepage: http://www.bzip.org/ _lzma From webhook-mailer at python.org Mon Mar 7 14:34:59 2022 From: webhook-mailer at python.org (ned-deily) Date: Mon, 07 Mar 2022 19:34:59 -0000 Subject: [Python-checkins] bpo-44549: Update bzip2 to 1.0.8 in Windows builds to mitigate CVE-2016-3189 and CVE-2019-12900 (GH-31732) (GH-31735) Message-ID: https://github.com/python/cpython/commit/4a3c610cd635f14747cf02c77908e80620aae6ea commit: 4a3c610cd635f14747cf02c77908e80620aae6ea branch: 3.7 author: Steve Dower committer: ned-deily date: 2022-03-07T14:34:46-05:00 summary: bpo-44549: Update bzip2 to 1.0.8 in Windows builds to mitigate CVE-2016-3189 and CVE-2019-12900 (GH-31732) (GH-31735) files: A Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst M PCbuild/get_externals.bat M PCbuild/python.props M PCbuild/readme.txt diff --git a/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst b/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst new file mode 100644 index 0000000000000..0f1ef9af6c617 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst @@ -0,0 +1,2 @@ +Update bzip2 to 1.0.8 in Windows builds to mitigate CVE-2016-3189 and +CVE-2019-12900 diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index 38fc2756b18d0..9c7f81542ed04 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -48,7 +48,7 @@ if NOT DEFINED PYTHON ( echo.Fetching external libraries... set libraries= -set libraries=%libraries% bzip2-1.0.6 +set libraries=%libraries% bzip2-1.0.8 if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1g set libraries=%libraries% sqlite-3.31.1.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.9.0 diff --git a/PCbuild/python.props b/PCbuild/python.props index 1034e7f3da3fe..d3ad12c72830b 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -47,7 +47,7 @@ $([System.IO.Path]::GetFullPath(`$(PySourcePath)externals`)) $(ExternalsDir)\ $(ExternalsDir)sqlite-3.31.1.0\ - $(ExternalsDir)bzip2-1.0.6\ + $(ExternalsDir)bzip2-1.0.8\ $(ExternalsDir)xz-5.2.2\ $(ExternalsDir)openssl-1.1.1g\ $(ExternalsDir)openssl-bin-1.1.1g\$(ArchName)\ diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index 9c521fa52d898..5e57a9590cb6b 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -157,7 +157,7 @@ interpreter, but they do implement several major features. See the about getting the source for building these libraries. The sub-projects are: _bz2 - Python wrapper for version 1.0.6 of the libbzip2 compression library + Python wrapper for version 1.0.8 of the libbzip2 compression library Homepage: http://www.bzip.org/ _lzma From webhook-mailer at python.org Mon Mar 7 14:45:10 2022 From: webhook-mailer at python.org (brandtbucher) Date: Mon, 07 Mar 2022 19:45:10 -0000 Subject: [Python-checkins] bpo-46841: Use inline caching for calls (GH-31709) Message-ID: https://github.com/python/cpython/commit/f193631387bfee99a812e39b05d5b7e6384b57f5 commit: f193631387bfee99a812e39b05d5b7e6384b57f5 branch: main author: Brandt Bucher committer: brandtbucher date: 2022-03-07T11:45:00-08:00 summary: bpo-46841: Use inline caching for calls (GH-31709) files: A Misc/NEWS.d/next/Core and Builtins/2022-03-06-10-37-36.bpo-46841.O12Pba.rst M Include/cpython/code.h M Include/internal/pycore_code.h M Include/internal/pycore_global_strings.h M Include/internal/pycore_interp.h M Include/internal/pycore_runtime_init.h M Include/opcode.h M Lib/importlib/_bootstrap_external.py M Lib/opcode.py M Lib/test/test_dis.py M Objects/codeobject.c M Programs/test_frozenmain.h M Python/ceval.c M Python/opcode_targets.h M Python/pylifecycle.c M Python/specialize.c diff --git a/Include/cpython/code.h b/Include/cpython/code.h index 21f8fe7ddad4a..f3e0761d95345 100644 --- a/Include/cpython/code.h +++ b/Include/cpython/code.h @@ -105,7 +105,7 @@ struct PyCodeObject { /* Quickened instructions and cache, or NULL This should be treated as opaque by all code except the specializer and interpreter. */ - union _cache_or_instruction *co_quickened; + _Py_CODEUNIT *co_quickened; }; diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index 2e03358dfcd47..21c657afed6c8 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -8,50 +8,10 @@ extern "C" { * Specialization and quickening structs and helper functions */ -typedef struct { - int32_t cache_count; - int32_t _; /* Force 8 byte size */ -} _PyEntryZero; - -typedef struct { - uint8_t original_oparg; - uint8_t counter; - uint16_t index; - uint32_t version; -} _PyAdaptiveEntry; -typedef struct { - /* Borrowed ref */ - PyObject *obj; -} _PyObjectCache; - -typedef struct { - uint32_t func_version; - uint16_t min_args; - uint16_t defaults_len; -} _PyCallCache; - - -/* Add specialized versions of entries to this union. - * - * Do not break the invariant: sizeof(SpecializedCacheEntry) == 8 - * Preserving this invariant is necessary because: - - If any one form uses more space, then all must and on 64 bit machines - this is likely to double the memory consumption of caches - - The function for calculating the offset of caches assumes a 4:1 - cache:instruction size ratio. Changing that would need careful - analysis to choose a new function. - */ -typedef union { - _PyEntryZero zero; - _PyAdaptiveEntry adaptive; - _PyObjectCache obj; - _PyCallCache call; -} SpecializedCacheEntry; - -#define INSTRUCTIONS_PER_ENTRY (sizeof(SpecializedCacheEntry)/sizeof(_Py_CODEUNIT)) - -/* Inline caches */ +// Inline caches. If you change the number of cache entries for an instruction, +// you must *also* update the number of cache entries in Lib/opcode.py and bump +// the magic number in Lib/importlib/_bootstrap_external.py! #define CACHE_ENTRIES(cache) (sizeof(cache)/sizeof(_Py_CODEUNIT)) @@ -112,73 +72,22 @@ typedef struct { #define INLINE_CACHE_ENTRIES_LOAD_METHOD CACHE_ENTRIES(_PyLoadMethodCache) -/* Maximum size of code to quicken, in code units. */ -#define MAX_SIZE_TO_QUICKEN 5000 - -typedef union _cache_or_instruction { - _Py_CODEUNIT code[1]; - SpecializedCacheEntry entry; -} SpecializedCacheOrInstruction; +typedef struct { + _Py_CODEUNIT counter; + _Py_CODEUNIT func_version[2]; + _Py_CODEUNIT min_args; +} _PyCallCache; -/* Get pointer to the nth cache entry, from the first instruction and n. - * Cache entries are indexed backwards, with [count-1] first in memory, and [0] last. - * The zeroth entry immediately precedes the instructions. - */ -static inline SpecializedCacheEntry * -_GetSpecializedCacheEntry(const _Py_CODEUNIT *first_instr, Py_ssize_t n) -{ - SpecializedCacheOrInstruction *last_cache_plus_one = (SpecializedCacheOrInstruction *)first_instr; - assert(&last_cache_plus_one->code[0] == first_instr); - return &last_cache_plus_one[-1-n].entry; -} +#define INLINE_CACHE_ENTRIES_CALL CACHE_ENTRIES(_PyCallCache) -/* Following two functions form a pair. - * - * oparg_from_offset_and_index() is used to compute the oparg - * when quickening, so that offset_from_oparg_and_nexti() - * can be used at runtime to compute the offset. - * - * The relationship between the three values is currently - * offset == (index>>1) + oparg - * This relation is chosen based on the following observations: - * 1. typically 1 in 4 instructions need a cache - * 2. instructions that need a cache typically use 2 entries - * These observations imply: offset ? index/2 - * We use the oparg to fine tune the relation to avoid wasting space - * and allow consecutive instructions to use caches. - * - * If the number of cache entries < number of instructions/2 we will waste - * some small amoount of space. - * If the number of cache entries > (number of instructions/2) + 255, then - * some instructions will not be able to use a cache. - * In practice, we expect some small amount of wasted space in a shorter functions - * and only functions exceeding a 1000 lines or more not to have enugh cache space. - * - */ -static inline int -oparg_from_offset_and_nexti(int offset, int nexti) -{ - return offset-(nexti>>1); -} +typedef struct { + _Py_CODEUNIT counter; +} _PyPrecallCache; -static inline int -offset_from_oparg_and_nexti(int oparg, int nexti) -{ - return (nexti>>1)+oparg; -} +#define INLINE_CACHE_ENTRIES_PRECALL CACHE_ENTRIES(_PyPrecallCache) -/* Get pointer to the cache entry associated with an instruction. - * nexti is the index of the instruction plus one. - * nexti is used as it corresponds to the instruction pointer in the interpreter. - * This doesn't check that an entry has been allocated for that instruction. */ -static inline SpecializedCacheEntry * -_GetSpecializedCacheEntryForInstruction(const _Py_CODEUNIT *first_instr, int nexti, int oparg) -{ - return _GetSpecializedCacheEntry( - first_instr, - offset_from_oparg_and_nexti(oparg, nexti) - ); -} +/* Maximum size of code to quicken, in code units. */ +#define MAX_SIZE_TO_QUICKEN 10000 #define QUICKENING_WARMUP_DELAY 8 @@ -205,6 +114,13 @@ _Py_IncrementCountAndMaybeQuicken(PyCodeObject *code) extern Py_ssize_t _Py_QuickenedCount; +// Borrowed references to common callables: +struct callable_cache { + PyObject *isinstance; + PyObject *len; + PyObject *list_append; +}; + /* "Locals plus" for a code object is the set of locals + cell vars + * free vars. This relates to variable names as well as offsets into * the "fast locals" storage array of execution frames. The compiler @@ -332,11 +248,6 @@ extern int _PyLineTable_PreviousAddressRange(PyCodeAddressRange *range); #define ADAPTIVE_CACHE_BACKOFF 64 -static inline void -cache_backoff(_PyAdaptiveEntry *entry) { - entry->counter = ADAPTIVE_CACHE_BACKOFF; -} - /* Specialization functions */ extern int _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, @@ -348,10 +259,10 @@ extern int _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name); extern int _Py_Specialize_BinarySubscr(PyObject *sub, PyObject *container, _Py_CODEUNIT *instr); extern int _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *instr); -extern int _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, - PyObject *kwnames, SpecializedCacheEntry *cache); -extern int _Py_Specialize_Precall(PyObject *callable, _Py_CODEUNIT *instr, int nargs, - PyObject *kwnames, SpecializedCacheEntry *cache, PyObject *builtins); +extern int _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, + int nargs, PyObject *kwnames); +extern int _Py_Specialize_Precall(PyObject *callable, _Py_CODEUNIT *instr, + int nargs, PyObject *kwnames, int oparg); extern void _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, int oparg); extern void _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h index 2a42dc16ce1b5..74ebc144ab548 100644 --- a/Include/internal/pycore_global_strings.h +++ b/Include/internal/pycore_global_strings.h @@ -269,6 +269,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(inf) STRUCT_FOR_ID(intersection) STRUCT_FOR_ID(isatty) + STRUCT_FOR_ID(isinstance) STRUCT_FOR_ID(items) STRUCT_FOR_ID(iter) STRUCT_FOR_ID(join) @@ -278,6 +279,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(last_type) STRUCT_FOR_ID(last_value) STRUCT_FOR_ID(latin1) + STRUCT_FOR_ID(len) STRUCT_FOR_ID(line) STRUCT_FOR_ID(lineno) STRUCT_FOR_ID(listcomp) diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index db8edffda8bb9..d55627908a28f 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -12,6 +12,7 @@ extern "C" { #include "pycore_atomic.h" // _Py_atomic_address #include "pycore_ast_state.h" // struct ast_state +#include "pycore_code.h" // struct callable_cache #include "pycore_context.h" // struct _Py_context_state #include "pycore_dict.h" // struct _Py_dict_state #include "pycore_exceptions.h" // struct _Py_exc_state @@ -176,6 +177,7 @@ struct _is { struct ast_state ast; struct type_cache type_cache; + struct callable_cache callable_cache; /* The following fields are here to avoid allocation during init. The data is exposed through PyInterpreterState pointer fields. diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h index 2f2bc65cd7111..8b1abcde11f72 100644 --- a/Include/internal/pycore_runtime_init.h +++ b/Include/internal/pycore_runtime_init.h @@ -884,6 +884,7 @@ extern "C" { INIT_ID(inf), \ INIT_ID(intersection), \ INIT_ID(isatty), \ + INIT_ID(isinstance), \ INIT_ID(items), \ INIT_ID(iter), \ INIT_ID(join), \ @@ -893,6 +894,7 @@ extern "C" { INIT_ID(last_type), \ INIT_ID(last_value), \ INIT_ID(latin1), \ + INIT_ID(len), \ INIT_ID(line), \ INIT_ID(lineno), \ INIT_ID(listcomp), \ diff --git a/Include/opcode.h b/Include/opcode.h index 1b9eeacdeab01..930a975897e29 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -7,9 +7,9 @@ extern "C" { /* Instruction opcodes for compiled code */ +#define CACHE 0 #define POP_TOP 1 #define PUSH_NULL 2 -#define CACHE 3 #define NOP 9 #define UNARY_POSITIVE 10 #define UNARY_NEGATIVE 11 @@ -114,75 +114,75 @@ extern "C" { #define PRECALL 166 #define CALL 171 #define KW_NAMES 172 -#define BINARY_OP_ADAPTIVE 4 -#define BINARY_OP_ADD_INT 5 -#define BINARY_OP_ADD_FLOAT 6 -#define BINARY_OP_ADD_UNICODE 7 -#define BINARY_OP_INPLACE_ADD_UNICODE 8 -#define BINARY_OP_MULTIPLY_INT 13 -#define BINARY_OP_MULTIPLY_FLOAT 14 -#define BINARY_OP_SUBTRACT_INT 16 -#define BINARY_OP_SUBTRACT_FLOAT 17 -#define COMPARE_OP_ADAPTIVE 18 -#define COMPARE_OP_FLOAT_JUMP 19 -#define COMPARE_OP_INT_JUMP 20 -#define COMPARE_OP_STR_JUMP 21 -#define BINARY_SUBSCR_ADAPTIVE 22 -#define BINARY_SUBSCR_GETITEM 23 -#define BINARY_SUBSCR_LIST_INT 24 -#define BINARY_SUBSCR_TUPLE_INT 26 -#define BINARY_SUBSCR_DICT 27 -#define STORE_SUBSCR_ADAPTIVE 28 -#define STORE_SUBSCR_LIST_INT 29 -#define STORE_SUBSCR_DICT 34 -#define CALL_ADAPTIVE 36 -#define CALL_PY_EXACT_ARGS 37 -#define CALL_PY_WITH_DEFAULTS 38 -#define JUMP_ABSOLUTE_QUICK 39 -#define LOAD_ATTR_ADAPTIVE 40 -#define LOAD_ATTR_INSTANCE_VALUE 41 -#define LOAD_ATTR_WITH_HINT 42 -#define LOAD_ATTR_SLOT 43 -#define LOAD_ATTR_MODULE 44 -#define LOAD_GLOBAL_ADAPTIVE 45 -#define LOAD_GLOBAL_MODULE 46 -#define LOAD_GLOBAL_BUILTIN 47 -#define LOAD_METHOD_ADAPTIVE 48 -#define LOAD_METHOD_CLASS 55 -#define LOAD_METHOD_MODULE 56 -#define LOAD_METHOD_NO_DICT 57 -#define LOAD_METHOD_WITH_DICT 58 -#define LOAD_METHOD_WITH_VALUES 59 -#define PRECALL_ADAPTIVE 62 -#define PRECALL_BUILTIN_CLASS 63 -#define PRECALL_NO_KW_BUILTIN_O 64 -#define PRECALL_NO_KW_BUILTIN_FAST 65 -#define PRECALL_BUILTIN_FAST_WITH_KEYWORDS 66 -#define PRECALL_NO_KW_LEN 67 -#define PRECALL_NO_KW_ISINSTANCE 72 -#define PRECALL_NO_KW_LIST_APPEND 73 -#define PRECALL_NO_KW_METHOD_DESCRIPTOR_O 76 -#define PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS 77 -#define PRECALL_NO_KW_STR_1 78 -#define PRECALL_NO_KW_TUPLE_1 79 -#define PRECALL_NO_KW_TYPE_1 80 -#define PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST 81 -#define PRECALL_BOUND_METHOD 140 -#define PRECALL_PYFUNC 141 -#define RESUME_QUICK 143 -#define STORE_ATTR_ADAPTIVE 150 -#define STORE_ATTR_INSTANCE_VALUE 153 -#define STORE_ATTR_SLOT 154 -#define STORE_ATTR_WITH_HINT 158 -#define UNPACK_SEQUENCE_ADAPTIVE 159 -#define UNPACK_SEQUENCE_LIST 161 -#define UNPACK_SEQUENCE_TUPLE 167 -#define UNPACK_SEQUENCE_TWO_TUPLE 168 -#define LOAD_FAST__LOAD_FAST 169 -#define STORE_FAST__LOAD_FAST 170 -#define LOAD_FAST__LOAD_CONST 173 -#define LOAD_CONST__LOAD_FAST 174 -#define STORE_FAST__STORE_FAST 175 +#define BINARY_OP_ADAPTIVE 3 +#define BINARY_OP_ADD_INT 4 +#define BINARY_OP_ADD_FLOAT 5 +#define BINARY_OP_ADD_UNICODE 6 +#define BINARY_OP_INPLACE_ADD_UNICODE 7 +#define BINARY_OP_MULTIPLY_INT 8 +#define BINARY_OP_MULTIPLY_FLOAT 13 +#define BINARY_OP_SUBTRACT_INT 14 +#define BINARY_OP_SUBTRACT_FLOAT 16 +#define COMPARE_OP_ADAPTIVE 17 +#define COMPARE_OP_FLOAT_JUMP 18 +#define COMPARE_OP_INT_JUMP 19 +#define COMPARE_OP_STR_JUMP 20 +#define BINARY_SUBSCR_ADAPTIVE 21 +#define BINARY_SUBSCR_GETITEM 22 +#define BINARY_SUBSCR_LIST_INT 23 +#define BINARY_SUBSCR_TUPLE_INT 24 +#define BINARY_SUBSCR_DICT 26 +#define STORE_SUBSCR_ADAPTIVE 27 +#define STORE_SUBSCR_LIST_INT 28 +#define STORE_SUBSCR_DICT 29 +#define CALL_ADAPTIVE 34 +#define CALL_PY_EXACT_ARGS 36 +#define CALL_PY_WITH_DEFAULTS 37 +#define JUMP_ABSOLUTE_QUICK 38 +#define LOAD_ATTR_ADAPTIVE 39 +#define LOAD_ATTR_INSTANCE_VALUE 40 +#define LOAD_ATTR_WITH_HINT 41 +#define LOAD_ATTR_SLOT 42 +#define LOAD_ATTR_MODULE 43 +#define LOAD_GLOBAL_ADAPTIVE 44 +#define LOAD_GLOBAL_MODULE 45 +#define LOAD_GLOBAL_BUILTIN 46 +#define LOAD_METHOD_ADAPTIVE 47 +#define LOAD_METHOD_CLASS 48 +#define LOAD_METHOD_MODULE 55 +#define LOAD_METHOD_NO_DICT 56 +#define LOAD_METHOD_WITH_DICT 57 +#define LOAD_METHOD_WITH_VALUES 58 +#define PRECALL_ADAPTIVE 59 +#define PRECALL_BUILTIN_CLASS 62 +#define PRECALL_NO_KW_BUILTIN_O 63 +#define PRECALL_NO_KW_BUILTIN_FAST 64 +#define PRECALL_BUILTIN_FAST_WITH_KEYWORDS 65 +#define PRECALL_NO_KW_LEN 66 +#define PRECALL_NO_KW_ISINSTANCE 67 +#define PRECALL_NO_KW_LIST_APPEND 72 +#define PRECALL_NO_KW_METHOD_DESCRIPTOR_O 73 +#define PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS 76 +#define PRECALL_NO_KW_STR_1 77 +#define PRECALL_NO_KW_TUPLE_1 78 +#define PRECALL_NO_KW_TYPE_1 79 +#define PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST 80 +#define PRECALL_BOUND_METHOD 81 +#define PRECALL_PYFUNC 140 +#define RESUME_QUICK 141 +#define STORE_ATTR_ADAPTIVE 143 +#define STORE_ATTR_INSTANCE_VALUE 150 +#define STORE_ATTR_SLOT 153 +#define STORE_ATTR_WITH_HINT 154 +#define UNPACK_SEQUENCE_ADAPTIVE 158 +#define UNPACK_SEQUENCE_LIST 159 +#define UNPACK_SEQUENCE_TUPLE 161 +#define UNPACK_SEQUENCE_TWO_TUPLE 167 +#define LOAD_FAST__LOAD_FAST 168 +#define STORE_FAST__LOAD_FAST 169 +#define LOAD_FAST__LOAD_CONST 170 +#define LOAD_CONST__LOAD_FAST 173 +#define STORE_FAST__STORE_FAST 174 #define DO_TRACING 255 extern const uint8_t _PyOpcode_InlineCacheEntries[256]; @@ -218,6 +218,8 @@ const uint8_t _PyOpcode_InlineCacheEntries[256] = { [LOAD_GLOBAL] = 5, [BINARY_OP] = 1, [LOAD_METHOD] = 10, + [PRECALL] = 1, + [CALL] = 4, }; #endif /* OPCODE_TABLES */ diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 741247dd25d63..32a41f852e5d7 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -393,6 +393,7 @@ def _write_atomic(path, data, mode=0o666): # Python 3.11a5 3484 (Use inline caching for LOAD_ATTR, LOAD_METHOD, and # STORE_ATTR) # Python 3.11a5 3485 (Add an oparg to GET_AWAITABLE) +# Python 3.11a6 3486 (Use inline caching for PRECALL and CALL) # Python 3.12 will start with magic number 3500 @@ -407,7 +408,7 @@ def _write_atomic(path, data, mode=0o666): # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array # in PC/launcher.c must also be updated. -MAGIC_NUMBER = (3485).to_bytes(2, 'little') + b'\r\n' +MAGIC_NUMBER = (3486).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c _PYCACHE = '__pycache__' diff --git a/Lib/opcode.py b/Lib/opcode.py index 3675780839671..a31a77a61c8af 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -57,9 +57,9 @@ def jabs_op(name, op, entries=0): # Instruction opcodes for compiled code # Blank lines correspond to available opcodes +def_op('CACHE', 0) def_op('POP_TOP', 1) def_op('PUSH_NULL', 2) -def_op('CACHE', 3) def_op('NOP', 9) def_op('UNARY_POSITIVE', 10) @@ -191,9 +191,9 @@ def jabs_op(name, op, entries=0): def_op('SET_UPDATE', 163) def_op('DICT_MERGE', 164) def_op('DICT_UPDATE', 165) -def_op('PRECALL', 166) +def_op('PRECALL', 166, 1) -def_op('CALL', 171) +def_op('CALL', 171, 4) def_op('KW_NAMES', 172) hasconst.append(172) diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 7e0542ae0ae9e..12d46af208e0a 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -149,10 +149,10 @@ def bug708901(): %3d PRECALL 2 CALL 2 GET_ITER - >> FOR_ITER 2 (to 32) + >> FOR_ITER 2 (to 42) STORE_FAST 0 (res) -%3d JUMP_ABSOLUTE 13 (to 26) +%3d JUMP_ABSOLUTE 18 (to 36) %3d >> LOAD_CONST 0 (None) RETURN_VALUE @@ -1164,10 +1164,10 @@ def _prepare_test_cases(): Instruction(opname='BUILD_MAP', opcode=105, arg=0, argval=0, argrepr='', offset=44, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Hello world!', argrepr="'Hello world!'", offset=46, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='PRECALL', opcode=166, arg=7, argval=7, argrepr='', offset=48, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=7, argval=7, argrepr='', offset=50, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=52, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='f', argrepr='f', offset=54, starts_line=8, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=56, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=7, argval=7, argrepr='', offset=52, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=62, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='f', argrepr='f', offset=64, starts_line=8, is_jump_target=False, positions=None), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=66, starts_line=None, is_jump_target=False, positions=None), ] expected_opinfo_f = [ @@ -1191,10 +1191,10 @@ def _prepare_test_cases(): Instruction(opname='LOAD_DEREF', opcode=137, arg=0, argval='c', argrepr='c', offset=44, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='LOAD_DEREF', opcode=137, arg=1, argval='d', argrepr='d', offset=46, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='PRECALL', opcode=166, arg=4, argval=4, argrepr='', offset=48, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=4, argval=4, argrepr='', offset=50, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=52, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='inner', argrepr='inner', offset=54, starts_line=6, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=56, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=4, argval=4, argrepr='', offset=52, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=62, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='inner', argrepr='inner', offset=64, starts_line=6, is_jump_target=False, positions=None), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=66, starts_line=None, is_jump_target=False, positions=None), ] expected_opinfo_inner = [ @@ -1209,153 +1209,152 @@ def _prepare_test_cases(): Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='e', argrepr='e', offset=26, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='LOAD_FAST', opcode=124, arg=1, argval='f', argrepr='f', offset=28, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='PRECALL', opcode=166, arg=6, argval=6, argrepr='', offset=30, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=6, argval=6, argrepr='', offset=32, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=34, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=36, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=38, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=6, argval=6, argrepr='', offset=34, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=44, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=46, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=48, starts_line=None, is_jump_target=False, positions=None), ] - expected_opinfo_jumpy = [ Instruction(opname='RESUME', opcode=151, arg=0, argval=0, argrepr='', offset=0, starts_line=1, is_jump_target=False, positions=None), Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=2, starts_line=3, is_jump_target=False, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='range', argrepr='range', offset=4, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=10, argrepr='10', offset=16, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=18, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=20, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='GET_ITER', opcode=68, arg=None, argval=None, argrepr='', offset=22, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='FOR_ITER', opcode=93, arg=28, argval=82, argrepr='to 82', offset=24, starts_line=None, is_jump_target=True, positions=None), - Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=26, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=28, starts_line=4, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=30, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=42, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=44, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=46, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=48, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=50, starts_line=5, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=52, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=54, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=32, argval=64, argrepr='to 64', offset=60, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=12, argval=24, argrepr='to 24', offset=62, starts_line=6, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=64, starts_line=7, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=66, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=68, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=40, argval=80, argrepr='to 80', offset=74, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=76, starts_line=8, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=12, argval=104, argrepr='to 104', offset=78, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=12, argval=24, argrepr='to 24', offset=80, starts_line=7, is_jump_target=True, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=82, starts_line=10, is_jump_target=True, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=84, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=96, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=98, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=100, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=102, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=104, starts_line=11, is_jump_target=True, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=86, argval=172, argrepr='to 172', offset=106, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=108, starts_line=12, is_jump_target=True, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=110, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=122, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=124, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=126, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=128, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=130, starts_line=13, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=132, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BINARY_OP', opcode=122, arg=23, argval=23, argrepr='-=', offset=134, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=138, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=140, starts_line=14, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=142, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=144, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=77, argval=154, argrepr='to 154', offset=150, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=52, argval=104, argrepr='to 104', offset=152, starts_line=15, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=154, starts_line=16, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=156, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=158, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=84, argval=168, argrepr='to 168', offset=164, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=13, argval=194, argrepr='to 194', offset=166, starts_line=17, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=168, starts_line=11, is_jump_target=True, positions=None), - Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=54, argval=108, argrepr='to 108', offset=170, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=172, starts_line=19, is_jump_target=True, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=174, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=186, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=188, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=190, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=192, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=194, starts_line=20, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=196, starts_line=21, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=198, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BINARY_OP', opcode=122, arg=11, argval=11, argrepr='/', offset=200, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=204, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=206, starts_line=25, is_jump_target=False, positions=None), - Instruction(opname='BEFORE_WITH', opcode=53, arg=None, argval=None, argrepr='', offset=208, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=210, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=212, starts_line=26, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=22, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='GET_ITER', opcode=68, arg=None, argval=None, argrepr='', offset=32, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='FOR_ITER', opcode=93, arg=33, argval=102, argrepr='to 102', offset=34, starts_line=None, is_jump_target=True, positions=None), + Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=36, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=38, starts_line=4, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=40, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=52, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=54, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=58, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=68, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=70, starts_line=5, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=72, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=74, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=42, argval=84, argrepr='to 84', offset=80, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=17, argval=34, argrepr='to 34', offset=82, starts_line=6, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=84, starts_line=7, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=86, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=88, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=50, argval=100, argrepr='to 100', offset=94, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=96, starts_line=8, is_jump_target=False, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=17, argval=134, argrepr='to 134', offset=98, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=17, argval=34, argrepr='to 34', offset=100, starts_line=7, is_jump_target=True, positions=None), + Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=102, starts_line=10, is_jump_target=True, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=104, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=116, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=118, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=122, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=132, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=134, starts_line=11, is_jump_target=True, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=106, argval=212, argrepr='to 212', offset=136, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=138, starts_line=12, is_jump_target=True, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=140, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=152, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=154, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=158, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=168, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=170, starts_line=13, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=172, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='BINARY_OP', opcode=122, arg=23, argval=23, argrepr='-=', offset=174, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=178, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=180, starts_line=14, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=182, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=184, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=97, argval=194, argrepr='to 194', offset=190, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=67, argval=134, argrepr='to 134', offset=192, starts_line=15, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=194, starts_line=16, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=196, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=198, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=104, argval=208, argrepr='to 208', offset=204, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=18, argval=244, argrepr='to 244', offset=206, starts_line=17, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=208, starts_line=11, is_jump_target=True, positions=None), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=69, argval=138, argrepr='to 138', offset=210, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=212, starts_line=19, is_jump_target=True, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=214, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval='Never reach this', argrepr="'Never reach this'", offset=226, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=226, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=228, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=230, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=232, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=234, starts_line=25, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=236, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=238, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=2, argval=2, argrepr='', offset=240, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=2, argval=2, argrepr='', offset=242, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=244, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=11, argval=270, argrepr='to 270', offset=246, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=248, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='WITH_EXCEPT_START', opcode=49, arg=None, argval=None, argrepr='', offset=250, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=131, argval=262, argrepr='to 262', offset=252, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=2, argval=2, argrepr='', offset=254, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=256, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=258, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=260, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=262, starts_line=None, is_jump_target=True, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=264, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=266, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=268, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=26, argval=324, argrepr='to 324', offset=270, starts_line=None, is_jump_target=True, positions=None), - Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=272, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=2, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=274, starts_line=22, is_jump_target=False, positions=None), - Instruction(opname='JUMP_IF_NOT_EXC_MATCH', opcode=121, arg=158, argval=316, argrepr='to 316', offset=286, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=288, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=290, starts_line=23, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=292, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=304, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=306, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=308, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=310, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=312, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=17, argval=350, argrepr='to 350', offset=314, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=316, starts_line=22, is_jump_target=True, positions=None), - Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=318, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=320, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=322, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=324, starts_line=28, is_jump_target=True, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=326, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=338, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=340, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=342, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=344, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=346, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=348, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=350, starts_line=23, is_jump_target=True, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=352, starts_line=28, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=354, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=366, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=368, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=370, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=372, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=374, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=376, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=378, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=380, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=382, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=394, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=396, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=398, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=400, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=402, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=404, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=406, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=408, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=232, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=242, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=244, starts_line=20, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=246, starts_line=21, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=248, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='BINARY_OP', opcode=122, arg=11, argval=11, argrepr='/', offset=250, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=254, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=256, starts_line=25, is_jump_target=False, positions=None), + Instruction(opname='BEFORE_WITH', opcode=53, arg=None, argval=None, argrepr='', offset=258, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=260, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=262, starts_line=26, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=264, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval='Never reach this', argrepr="'Never reach this'", offset=276, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=278, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=282, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=292, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=294, starts_line=25, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=296, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=298, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=2, argval=2, argrepr='', offset=300, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=2, argval=2, argrepr='', offset=304, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=314, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=11, argval=340, argrepr='to 340', offset=316, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=318, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='WITH_EXCEPT_START', opcode=49, arg=None, argval=None, argrepr='', offset=320, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=166, argval=332, argrepr='to 332', offset=322, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=2, argval=2, argrepr='', offset=324, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=326, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=328, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=330, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=332, starts_line=None, is_jump_target=True, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=334, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=336, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=338, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=31, argval=404, argrepr='to 404', offset=340, starts_line=None, is_jump_target=True, positions=None), + Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=342, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=2, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=344, starts_line=22, is_jump_target=False, positions=None), + Instruction(opname='JUMP_IF_NOT_EXC_MATCH', opcode=121, arg=198, argval=396, argrepr='to 396', offset=356, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=358, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=360, starts_line=23, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=362, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=374, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=376, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=380, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=390, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=392, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=22, argval=440, argrepr='to 440', offset=394, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=396, starts_line=22, is_jump_target=True, positions=None), + Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=398, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=400, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=402, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=404, starts_line=28, is_jump_target=True, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=406, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=418, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=420, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=424, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=434, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=436, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=438, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=440, starts_line=23, is_jump_target=True, positions=None), + Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=442, starts_line=28, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=444, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=456, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=458, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=462, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=472, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=474, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=476, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=478, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=480, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=482, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=494, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=496, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=500, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=510, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=512, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=514, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=516, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=518, starts_line=None, is_jump_target=False, positions=None), ] # One last piece of inspect fodder to check the default line number handling diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-06-10-37-36.bpo-46841.O12Pba.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-06-10-37-36.bpo-46841.O12Pba.rst new file mode 100644 index 0000000000000..835427437c287 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-06-10-37-36.bpo-46841.O12Pba.rst @@ -0,0 +1,2 @@ +Use inline caching for :opcode:`PRECALL` and :opcode:`CALL`, and remove the +internal machinery for managing the (now unused) non-inline caches. diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 5a87e6c4ff877..5279f6ce17064 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -1571,10 +1571,7 @@ code_sizeof(PyCodeObject *co, PyObject *Py_UNUSED(args)) } if (co->co_quickened != NULL) { - Py_ssize_t count = co->co_quickened[0].entry.zero.cache_count; - count += (PyBytes_GET_SIZE(co->co_code)+sizeof(SpecializedCacheEntry)-1)/ - sizeof(SpecializedCacheEntry); - res += count * sizeof(SpecializedCacheEntry); + res += PyBytes_GET_SIZE(co->co_code); } return PyLong_FromSsize_t(res); diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h index 4ebab4f7544bb..8cae77a4899f1 100644 --- a/Programs/test_frozenmain.h +++ b/Programs/test_frozenmain.h @@ -1,41 +1,46 @@ // Auto-generated by Programs/freeze_test_frozenmain.py unsigned char M_test_frozenmain[] = { 227,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0, - 0,0,0,0,0,115,136,0,0,0,151,0,100,0,100,1, + 0,0,0,0,0,115,176,0,0,0,151,0,100,0,100,1, 108,0,90,0,100,0,100,1,108,1,90,1,2,0,101,2, - 100,2,166,1,171,1,1,0,2,0,101,2,100,3,101,0, - 106,3,3,0,3,0,3,0,3,0,166,2,171,2,1,0, - 2,0,101,1,106,4,3,0,3,0,3,0,3,0,166,0, - 171,0,100,4,25,0,3,0,3,0,3,0,3,0,90,5, - 100,5,68,0,93,20,90,6,2,0,101,2,100,6,101,6, - 155,0,100,7,101,5,101,6,25,0,3,0,3,0,3,0, - 3,0,155,0,157,4,166,1,171,1,1,0,113,45,100,1, - 83,0,41,8,233,0,0,0,0,78,122,18,70,114,111,122, - 101,110,32,72,101,108,108,111,32,87,111,114,108,100,122,8, - 115,121,115,46,97,114,103,118,218,6,99,111,110,102,105,103, - 41,5,90,12,112,114,111,103,114,97,109,95,110,97,109,101, - 218,10,101,120,101,99,117,116,97,98,108,101,90,15,117,115, - 101,95,101,110,118,105,114,111,110,109,101,110,116,90,17,99, - 111,110,102,105,103,117,114,101,95,99,95,115,116,100,105,111, - 90,14,98,117,102,102,101,114,101,100,95,115,116,100,105,111, - 122,7,99,111,110,102,105,103,32,122,2,58,32,41,7,218, - 3,115,121,115,90,17,95,116,101,115,116,105,110,116,101,114, - 110,97,108,99,97,112,105,218,5,112,114,105,110,116,218,4, - 97,114,103,118,90,11,103,101,116,95,99,111,110,102,105,103, - 115,114,2,0,0,0,218,3,107,101,121,169,0,243,0,0, - 0,0,250,18,116,101,115,116,95,102,114,111,122,101,110,109, - 97,105,110,46,112,121,250,8,60,109,111,100,117,108,101,62, - 114,11,0,0,0,1,0,0,0,115,18,0,0,0,2,128, - 8,3,8,1,12,2,24,1,32,1,8,1,38,7,4,249, - 115,20,0,0,0,2,128,8,3,8,1,12,2,24,1,32, - 1,2,7,4,1,2,249,42,7,115,136,0,0,0,0,0, - 1,11,1,11,1,11,1,11,1,25,1,25,1,25,1,25, - 1,6,1,6,7,27,1,28,1,28,1,28,1,6,1,6, - 7,17,19,22,19,27,19,27,19,27,19,27,19,27,1,28, - 1,28,1,28,10,39,10,27,10,39,10,39,10,39,10,39, - 10,39,10,41,10,41,42,50,10,51,10,51,10,51,10,51, - 10,51,1,7,12,2,1,42,1,42,5,8,5,10,5,10, - 11,41,21,24,11,41,11,41,28,34,35,38,28,39,28,39, - 28,39,28,39,28,39,11,41,11,41,5,42,5,42,5,42, + 100,2,166,1,0,0,171,1,0,0,0,0,0,0,0,0, + 1,0,2,0,101,2,100,3,101,0,106,3,0,0,0,0, + 0,0,0,0,166,2,0,0,171,2,0,0,0,0,0,0, + 0,0,1,0,2,0,101,1,106,4,0,0,0,0,0,0, + 0,0,166,0,0,0,171,0,0,0,0,0,0,0,0,0, + 100,4,25,0,0,0,0,0,0,0,0,0,90,5,100,5, + 68,0,93,25,90,6,2,0,101,2,100,6,101,6,155,0, + 100,7,101,5,101,6,25,0,0,0,0,0,0,0,0,0, + 155,0,157,4,166,1,0,0,171,1,0,0,0,0,0,0, + 0,0,1,0,113,60,100,1,83,0,41,8,233,0,0,0, + 0,78,122,18,70,114,111,122,101,110,32,72,101,108,108,111, + 32,87,111,114,108,100,122,8,115,121,115,46,97,114,103,118, + 218,6,99,111,110,102,105,103,41,5,90,12,112,114,111,103, + 114,97,109,95,110,97,109,101,218,10,101,120,101,99,117,116, + 97,98,108,101,90,15,117,115,101,95,101,110,118,105,114,111, + 110,109,101,110,116,90,17,99,111,110,102,105,103,117,114,101, + 95,99,95,115,116,100,105,111,90,14,98,117,102,102,101,114, + 101,100,95,115,116,100,105,111,122,7,99,111,110,102,105,103, + 32,122,2,58,32,41,7,218,3,115,121,115,90,17,95,116, + 101,115,116,105,110,116,101,114,110,97,108,99,97,112,105,218, + 5,112,114,105,110,116,218,4,97,114,103,118,90,11,103,101, + 116,95,99,111,110,102,105,103,115,114,2,0,0,0,218,3, + 107,101,121,169,0,243,0,0,0,0,250,18,116,101,115,116, + 95,102,114,111,122,101,110,109,97,105,110,46,112,121,250,8, + 60,109,111,100,117,108,101,62,114,11,0,0,0,1,0,0, + 0,115,18,0,0,0,2,128,8,3,8,1,22,2,34,1, + 42,1,8,1,48,7,4,249,115,20,0,0,0,2,128,8, + 3,8,1,22,2,34,1,42,1,2,7,4,1,2,249,52, + 7,115,176,0,0,0,0,0,1,11,1,11,1,11,1,11, + 1,25,1,25,1,25,1,25,1,6,1,6,7,27,1,28, + 1,28,1,28,1,28,1,28,1,28,1,28,1,28,1,6, + 1,6,7,17,19,22,19,27,19,27,19,27,19,27,19,27, + 1,28,1,28,1,28,1,28,1,28,1,28,1,28,1,28, + 10,39,10,27,10,39,10,39,10,39,10,39,10,39,10,41, + 10,41,10,41,10,41,10,41,10,41,10,41,42,50,10,51, + 10,51,10,51,10,51,10,51,1,7,12,2,1,42,1,42, + 5,8,5,10,5,10,11,41,21,24,11,41,11,41,28,34, + 35,38,28,39,28,39,28,39,28,39,28,39,11,41,11,41, + 5,42,5,42,5,42,5,42,5,42,5,42,5,42,5,42, 5,42,1,42,1,42,114,9,0,0,0, }; diff --git a/Python/ceval.c b/Python/ceval.c index 7439710ae47b7..b15c1015cd242 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1321,6 +1321,10 @@ eval_frame_handle_pending(PyThreadState *tstate) #define JUMPTO(x) (next_instr = first_instr + (x)) #define JUMPBY(x) (next_instr += (x)) +// Skip from a PRECALL over a CALL to the next instruction: +#define SKIP_CALL() \ + JUMPBY(INLINE_CACHE_ENTRIES_PRECALL + 1 + INLINE_CACHE_ENTRIES_CALL) + /* Get opcode and oparg from original instructions, not quickened form. */ #define TRACING_NEXTOPARG() do { \ _Py_CODEUNIT word = ((_Py_CODEUNIT *)PyBytes_AS_STRING(frame->f_code->co_code))[INSTR_OFFSET()]; \ @@ -1431,9 +1435,6 @@ eval_frame_handle_pending(PyThreadState *tstate) #define JUMP_TO_INSTRUCTION(op) goto PREDICT_ID(op) -#define GET_CACHE() \ - _GetSpecializedCacheEntryForInstruction(first_instr, INSTR_OFFSET(), oparg) - #define DEOPT_IF(cond, instname) if (cond) { goto instname ## _miss; } @@ -3003,8 +3004,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int TARGET(LOAD_GLOBAL_ADAPTIVE) { assert(cframe.use_tracing == 0); - uint16_t counter = *next_instr; - if (counter == 0) { + _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; + if (cache->counter == 0) { PyObject *name = GETITEM(names, oparg); next_instr--; if (_Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name) < 0) { @@ -3014,7 +3015,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } else { STAT_INC(LOAD_GLOBAL, deferred); - *next_instr = counter-1; + cache->counter--; JUMP_TO_INSTRUCTION(LOAD_GLOBAL); } } @@ -4563,20 +4564,12 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int We'll be passing `oparg + 1` to call_function, to make it accept the `self` as a first argument. */ - int is_method = (PEEK(oparg + 2) != NULL); - int nargs = oparg + is_method; + int is_meth = is_method(stack_pointer, oparg); + int nargs = oparg + is_meth; /* Move ownership of reference from stack to call_shape * and make sure that NULL is cleared from stack */ PyObject *function = PEEK(nargs + 1); -#ifdef Py_STATS - extern int _PySpecialization_ClassifyCallable(PyObject *); - SpecializationStats *stats = - &_py_stats.opcode_stats[PRECALL].specialization; - stats->failure++; - int kind = _PySpecialization_ClassifyCallable(function); - stats->failure_kinds[kind]++; -#endif - if (!is_method && Py_TYPE(function) == &PyMethod_Type) { + if (!is_meth && Py_TYPE(function) == &PyMethod_Type) { PyObject *meth = ((PyMethodObject *)function)->im_func; PyObject *self = ((PyMethodObject *)function)->im_self; Py_INCREF(meth); @@ -4585,35 +4578,32 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int PEEK(oparg+2) = meth; Py_DECREF(function); } + JUMPBY(INLINE_CACHE_ENTRIES_PRECALL); DISPATCH(); } TARGET(PRECALL_BOUND_METHOD) { - SpecializedCacheEntry *cache = GET_CACHE(); - int original_oparg = cache->adaptive.original_oparg; - int is_method = (PEEK(original_oparg + 2) != NULL); - DEOPT_IF(is_method, PRECALL); - PyObject *function = PEEK(original_oparg + 1); + DEOPT_IF(is_method(stack_pointer, oparg), PRECALL); + PyObject *function = PEEK(oparg + 1); DEOPT_IF(Py_TYPE(function) != &PyMethod_Type, PRECALL); STAT_INC(PRECALL, hit); PyObject *meth = ((PyMethodObject *)function)->im_func; PyObject *self = ((PyMethodObject *)function)->im_self; Py_INCREF(meth); Py_INCREF(self); - PEEK(original_oparg+1) = self; - PEEK(original_oparg+2) = meth; + PEEK(oparg + 1) = self; + PEEK(oparg + 2) = meth; Py_DECREF(function); + JUMPBY(INLINE_CACHE_ENTRIES_PRECALL); DISPATCH(); } TARGET(PRECALL_PYFUNC) { - SpecializedCacheEntry *cache = GET_CACHE(); - int original_oparg = cache->adaptive.original_oparg; - int is_method = (PEEK(original_oparg + 2) != NULL); - int nargs = original_oparg + is_method; + int nargs = oparg + is_method(stack_pointer, oparg); PyObject *function = PEEK(nargs + 1); DEOPT_IF(Py_TYPE(function) != &PyFunction_Type, PRECALL); STAT_INC(PRECALL, hit); + JUMPBY(INLINE_CACHE_ENTRIES_PRECALL); DISPATCH(); } @@ -4649,6 +4639,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int goto error; } _PyFrame_SetStackPointer(frame, stack_pointer); + frame->f_lasti += INLINE_CACHE_ENTRIES_CALL; new_frame->previous = frame; cframe.current_frame = frame = new_frame; CALL_STAT_INC(inlined_py_calls); @@ -4680,21 +4671,20 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int if (res == NULL) { goto error; } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); CHECK_EVAL_BREAKER(); DISPATCH(); } TARGET(PRECALL_ADAPTIVE) { - SpecializedCacheEntry *cache = GET_CACHE(); - int original_oparg = cache->adaptive.original_oparg; - if (cache->adaptive.counter == 0) { + _PyPrecallCache *cache = (_PyPrecallCache *)next_instr; + if (cache->counter == 0) { next_instr--; - int is_meth = is_method(stack_pointer, original_oparg); - int nargs = original_oparg + is_meth; + int is_meth = is_method(stack_pointer, oparg); + int nargs = oparg + is_meth; PyObject *callable = PEEK(nargs + 1); - int err = _Py_Specialize_Precall( - callable, next_instr, nargs, - call_shape.kwnames, cache, BUILTINS()); + int err = _Py_Specialize_Precall(callable, next_instr, nargs, + call_shape.kwnames, oparg); if (err < 0) { goto error; } @@ -4702,23 +4692,20 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } else { STAT_INC(PRECALL, deferred); - cache->adaptive.counter--; - oparg = original_oparg; + cache->counter--; JUMP_TO_INSTRUCTION(PRECALL); } } TARGET(CALL_ADAPTIVE) { - SpecializedCacheEntry *cache = GET_CACHE(); - int original_oparg = cache->adaptive.original_oparg; - if (cache->adaptive.counter == 0) { + _PyCallCache *cache = (_PyCallCache *)next_instr; + if (cache->counter == 0) { next_instr--; - int is_meth = is_method(stack_pointer, original_oparg); - int nargs = original_oparg + is_meth; + int is_meth = is_method(stack_pointer, oparg); + int nargs = oparg + is_meth; PyObject *callable = PEEK(nargs + 1); - int err = _Py_Specialize_Call( - callable, next_instr, nargs, - call_shape.kwnames, cache); + int err = _Py_Specialize_Call(callable, next_instr, nargs, + call_shape.kwnames); if (err < 0) { goto error; } @@ -4726,23 +4713,20 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } else { STAT_INC(CALL, deferred); - cache->adaptive.counter--; - oparg = original_oparg; + cache->counter--; goto call_function; } } TARGET(CALL_PY_EXACT_ARGS) { assert(call_shape.kwnames == NULL); - SpecializedCacheEntry *caches = GET_CACHE(); - int original_oparg = caches->adaptive.original_oparg; - int is_meth = is_method(stack_pointer, original_oparg); - int argcount = original_oparg + is_meth; + _PyCallCache *cache = (_PyCallCache *)next_instr; + int is_meth = is_method(stack_pointer, oparg); + int argcount = oparg + is_meth; PyObject *callable = PEEK(argcount + 1); DEOPT_IF(!PyFunction_Check(callable), CALL); - _PyCallCache *cache1 = &caches[-1].call; PyFunctionObject *func = (PyFunctionObject *)callable; - DEOPT_IF(func->func_version != cache1->func_version, CALL); + DEOPT_IF(func->func_version != read_u32(cache->func_version), CALL); PyCodeObject *code = (PyCodeObject *)func->func_code; DEOPT_IF(code->co_argcount != argcount, CALL); STAT_INC(CALL, hit); @@ -4760,6 +4744,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } STACK_SHRINK(2-is_meth); _PyFrame_SetStackPointer(frame, stack_pointer); + frame->f_lasti += INLINE_CACHE_ENTRIES_CALL; new_frame->previous = frame; frame = cframe.current_frame = new_frame; goto start_frame; @@ -4767,18 +4752,16 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int TARGET(CALL_PY_WITH_DEFAULTS) { assert(call_shape.kwnames == NULL); - SpecializedCacheEntry *caches = GET_CACHE(); - int original_oparg = caches->adaptive.original_oparg; - int is_meth = is_method(stack_pointer, original_oparg); - int argcount = original_oparg + is_meth; + _PyCallCache *cache = (_PyCallCache *)next_instr; + int is_meth = is_method(stack_pointer, oparg); + int argcount = oparg + is_meth; PyObject *callable = PEEK(argcount + 1); DEOPT_IF(!PyFunction_Check(callable), CALL); - _PyCallCache *cache1 = &caches[-1].call; PyFunctionObject *func = (PyFunctionObject *)callable; - DEOPT_IF(func->func_version != cache1->func_version, CALL); + DEOPT_IF(func->func_version != read_u32(cache->func_version), CALL); PyCodeObject *code = (PyCodeObject *)func->func_code; DEOPT_IF(argcount > code->co_argcount, CALL); - int minargs = cache1->min_args; + int minargs = cache->min_args; DEOPT_IF(argcount < minargs, CALL); STAT_INC(CALL, hit); _PyInterpreterFrame *new_frame = _PyFrame_Push(tstate, func); @@ -4790,9 +4773,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int for (int i = 0; i < argcount; i++) { new_frame->localsplus[i] = stack_pointer[i]; } - int def_offset = cache1->defaults_len - code->co_argcount; for (int i = argcount; i < code->co_argcount; i++) { - PyObject *def = PyTuple_GET_ITEM(func->func_defaults, i + def_offset); + PyObject *def = PyTuple_GET_ITEM(func->func_defaults, + i - minargs); Py_INCREF(def); new_frame->localsplus[i] = def; } @@ -4801,6 +4784,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } STACK_SHRINK(2-is_meth); _PyFrame_SetStackPointer(frame, stack_pointer); + frame->f_lasti += INLINE_CACHE_ENTRIES_CALL; new_frame->previous = frame; frame = cframe.current_frame = new_frame; goto start_frame; @@ -4809,13 +4793,13 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int TARGET(PRECALL_NO_KW_TYPE_1) { assert(call_shape.kwnames == NULL); assert(cframe.use_tracing == 0); - assert(GET_CACHE()->adaptive.original_oparg == 1); + assert(oparg == 1); DEOPT_IF(is_method(stack_pointer, 1), PRECALL); PyObject *obj = TOP(); PyObject *callable = SECOND(); DEOPT_IF(callable != (PyObject *)&PyType_Type, PRECALL); - next_instr++; // Skip following call STAT_INC(PRECALL, hit); + SKIP_CALL(); PyObject *res = Py_NewRef(Py_TYPE(obj)); Py_DECREF(callable); Py_DECREF(obj); @@ -4827,12 +4811,12 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int TARGET(PRECALL_NO_KW_STR_1) { assert(call_shape.kwnames == NULL); assert(cframe.use_tracing == 0); - assert(GET_CACHE()->adaptive.original_oparg == 1); + assert(oparg == 1); DEOPT_IF(is_method(stack_pointer, 1), PRECALL); PyObject *callable = PEEK(2); DEOPT_IF(callable != (PyObject *)&PyUnicode_Type, PRECALL); - next_instr++; // Skip following call STAT_INC(PRECALL, hit); + SKIP_CALL(); PyObject *arg = TOP(); PyObject *res = PyObject_Str(arg); Py_DECREF(arg); @@ -4848,12 +4832,12 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int TARGET(PRECALL_NO_KW_TUPLE_1) { assert(call_shape.kwnames == NULL); - assert(GET_CACHE()->adaptive.original_oparg == 1); + assert(oparg == 1); DEOPT_IF(is_method(stack_pointer, 1), PRECALL); PyObject *callable = PEEK(2); DEOPT_IF(callable != (PyObject *)&PyTuple_Type, PRECALL); - next_instr++; // Skip following call STAT_INC(PRECALL, hit); + SKIP_CALL(); PyObject *arg = TOP(); PyObject *res = PySequence_Tuple(arg); Py_DECREF(arg); @@ -4868,16 +4852,15 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } TARGET(PRECALL_BUILTIN_CLASS) { - int original_oparg = GET_CACHE()->adaptive.original_oparg; - int is_meth = is_method(stack_pointer, original_oparg); - int total_args = original_oparg + is_meth; + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; int kwnames_len = KWNAMES_LEN(); PyObject *callable = PEEK(total_args + 1); DEOPT_IF(!PyType_Check(callable), PRECALL); PyTypeObject *tp = (PyTypeObject *)callable; DEOPT_IF(tp->tp_vectorcall == NULL, PRECALL); - next_instr++; // Skip following call STAT_INC(PRECALL, hit); + SKIP_CALL(); STACK_SHRINK(total_args); PyObject *res = tp->tp_vectorcall((PyObject *)tp, stack_pointer, total_args-kwnames_len, call_shape.kwnames); @@ -4900,16 +4883,14 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert(cframe.use_tracing == 0); /* Builtin METH_O functions */ assert(call_shape.kwnames == NULL); - SpecializedCacheEntry *caches = GET_CACHE(); - int original_oparg = caches->adaptive.original_oparg; - int is_meth = is_method(stack_pointer, original_oparg); - int total_args = original_oparg + is_meth; + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; DEOPT_IF(total_args != 1, PRECALL); PyObject *callable = PEEK(total_args + 1); DEOPT_IF(!PyCFunction_CheckExact(callable), PRECALL); DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_O, PRECALL); - next_instr++; // Skip following call STAT_INC(PRECALL, hit); + SKIP_CALL(); PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); // This is slower but CPython promises to check all non-vectorcall // function calls. @@ -4936,16 +4917,14 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert(cframe.use_tracing == 0); /* Builtin METH_FASTCALL functions, without keywords */ assert(call_shape.kwnames == NULL); - SpecializedCacheEntry *caches = GET_CACHE(); - int original_oparg = caches->adaptive.original_oparg; - int is_meth = is_method(stack_pointer, original_oparg); - int total_args = original_oparg + is_meth; + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; PyObject *callable = PEEK(total_args + 1); DEOPT_IF(!PyCFunction_CheckExact(callable), PRECALL); DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_FASTCALL, PRECALL); - next_instr++; // Skip following call STAT_INC(PRECALL, hit); + SKIP_CALL(); PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); STACK_SHRINK(total_args); /* res = func(self, args, nargs) */ @@ -4977,16 +4956,14 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int TARGET(PRECALL_BUILTIN_FAST_WITH_KEYWORDS) { assert(cframe.use_tracing == 0); /* Builtin METH_FASTCALL | METH_KEYWORDS functions */ - SpecializedCacheEntry *caches = GET_CACHE(); - int original_oparg = caches->adaptive.original_oparg; - int is_meth = is_method(stack_pointer, original_oparg); - int total_args = original_oparg + is_meth; + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; PyObject *callable = PEEK(total_args + 1); DEOPT_IF(!PyCFunction_CheckExact(callable), PRECALL); DEOPT_IF(PyCFunction_GET_FLAGS(callable) != (METH_FASTCALL | METH_KEYWORDS), PRECALL); - next_instr++; // Skip following call STAT_INC(PRECALL, hit); + SKIP_CALL(); STACK_SHRINK(total_args); /* res = func(self, args, nargs, kwnames) */ _PyCFunctionFastWithKeywords cfunc = @@ -5019,16 +4996,14 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert(cframe.use_tracing == 0); assert(call_shape.kwnames == NULL); /* len(o) */ - SpecializedCacheEntry *caches = GET_CACHE(); - int original_oparg = caches->adaptive.original_oparg; - int is_meth = is_method(stack_pointer, original_oparg); - int total_args = original_oparg + is_meth; + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; DEOPT_IF(total_args != 1, PRECALL); - _PyObjectCache *cache1 = &caches[-1].obj; PyObject *callable = PEEK(total_args + 1); - DEOPT_IF(callable != cache1->obj, PRECALL); - next_instr++; // Skip following call + PyInterpreterState *interp = _PyInterpreterState_GET(); + DEOPT_IF(callable != interp->callable_cache.len, PRECALL); STAT_INC(PRECALL, hit); + SKIP_CALL(); PyObject *arg = TOP(); Py_ssize_t len_i = PyObject_Length(arg); if (len_i < 0) { @@ -5051,17 +5026,14 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert(cframe.use_tracing == 0); assert(call_shape.kwnames == NULL); /* isinstance(o, o2) */ - SpecializedCacheEntry *caches = GET_CACHE(); - int original_oparg = caches->adaptive.original_oparg; - int is_meth = is_method(stack_pointer, original_oparg); - int total_args = original_oparg + is_meth; + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; PyObject *callable = PEEK(total_args + 1); DEOPT_IF(total_args != 2, PRECALL); - _PyObjectCache *cache1 = &caches[-1].obj; - - DEOPT_IF(callable != cache1->obj, PRECALL); - next_instr++; // Skip following call + PyInterpreterState *interp = _PyInterpreterState_GET(); + DEOPT_IF(callable != interp->callable_cache.isinstance, PRECALL); STAT_INC(PRECALL, hit); + SKIP_CALL(); PyObject *cls = POP(); PyObject *inst = TOP(); int retval = PyObject_IsInstance(inst, cls); @@ -5086,16 +5058,14 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int TARGET(PRECALL_NO_KW_LIST_APPEND) { assert(cframe.use_tracing == 0); assert(call_shape.kwnames == NULL); - assert(GET_CACHE()->adaptive.original_oparg == 1); - SpecializedCacheEntry *caches = GET_CACHE(); - _PyObjectCache *cache1 = &caches[-1].obj; - assert(cache1->obj != NULL); + assert(oparg == 1); PyObject *callable = PEEK(3); - DEOPT_IF(callable != cache1->obj, PRECALL); + PyInterpreterState *interp = _PyInterpreterState_GET(); + DEOPT_IF(callable != interp->callable_cache.list_append, PRECALL); PyObject *list = SECOND(); DEOPT_IF(!PyList_Check(list), PRECALL); STAT_INC(PRECALL, hit); - next_instr++; // Skip following call + SKIP_CALL(); PyObject *arg = TOP(); int err = PyList_Append(list, arg); if (err) { @@ -5112,16 +5082,15 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int TARGET(PRECALL_NO_KW_METHOD_DESCRIPTOR_O) { assert(call_shape.kwnames == NULL); - int original_oparg = GET_CACHE()->adaptive.original_oparg; - int is_meth = is_method(stack_pointer, original_oparg); - int total_args = original_oparg + is_meth; + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; PyObject *callable = PEEK(total_args + 1); DEOPT_IF(total_args != 2, PRECALL); DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), PRECALL); PyMethodDef *meth = ((PyMethodDescrObject *)callable)->d_method; DEOPT_IF(meth->ml_flags != METH_O, PRECALL); - next_instr++; // Skip following call STAT_INC(PRECALL, hit); + SKIP_CALL(); PyCFunction cfunc = meth->ml_meth; // This is slower but CPython promises to check all non-vectorcall // function calls. @@ -5135,7 +5104,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); Py_DECREF(self); Py_DECREF(arg); - STACK_SHRINK(original_oparg+1); + STACK_SHRINK(oparg + 1); SET_TOP(res); Py_DECREF(callable); if (res == NULL) { @@ -5147,17 +5116,16 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int TARGET(PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS) { assert(call_shape.kwnames == NULL); - int original_oparg = GET_CACHE()->adaptive.original_oparg; - assert(original_oparg == 0 || original_oparg == 1); - int is_meth = is_method(stack_pointer, original_oparg); - int total_args = original_oparg + is_meth; + assert(oparg == 0 || oparg == 1); + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; DEOPT_IF(total_args != 1, PRECALL); PyObject *callable = SECOND(); DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), PRECALL); PyMethodDef *meth = ((PyMethodDescrObject *)callable)->d_method; DEOPT_IF(meth->ml_flags != METH_NOARGS, PRECALL); - next_instr++; // Skip following call STAT_INC(PRECALL, hit); + SKIP_CALL(); PyCFunction cfunc = meth->ml_meth; // This is slower but CPython promises to check all non-vectorcall // function calls. @@ -5169,7 +5137,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int _Py_LeaveRecursiveCall(tstate); assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); Py_DECREF(self); - STACK_SHRINK(original_oparg+1); + STACK_SHRINK(oparg + 1); SET_TOP(res); Py_DECREF(callable); if (res == NULL) { @@ -5181,16 +5149,15 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int TARGET(PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST) { assert(call_shape.kwnames == NULL); - int original_oparg = GET_CACHE()->adaptive.original_oparg; - int is_meth = is_method(stack_pointer, original_oparg); - int total_args = original_oparg + is_meth; + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; PyObject *callable = PEEK(total_args + 1); /* Builtin METH_FASTCALL methods, without keywords */ DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), PRECALL); PyMethodDef *meth = ((PyMethodDescrObject *)callable)->d_method; DEOPT_IF(meth->ml_flags != METH_FASTCALL, PRECALL); - next_instr++; // Skip following call STAT_INC(PRECALL, hit); + SKIP_CALL(); _PyCFunctionFast cfunc = (_PyCFunctionFast)(void(*)(void))meth->ml_meth; int nargs = total_args-1; STACK_SHRINK(nargs); @@ -5537,22 +5504,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int /* Specialization misses */ -#define MISS_WITH_CACHE(opname) \ -opname ## _miss: \ - { \ - STAT_INC(opcode, miss); \ - STAT_INC(opname, miss); \ - _PyAdaptiveEntry *cache = &GET_CACHE()->adaptive; \ - cache->counter--; \ - if (cache->counter == 0) { \ - next_instr[-1] = _Py_MAKECODEUNIT(opname ## _ADAPTIVE, _Py_OPARG(next_instr[-1])); \ - STAT_INC(opname, deopt); \ - cache_backoff(cache); \ - } \ - oparg = cache->original_oparg; \ - JUMP_TO_INSTRUCTION(opname); \ - } - #define MISS_WITH_INLINE_CACHE(opname) \ opname ## _miss: \ { \ @@ -5588,8 +5539,8 @@ MISS_WITH_INLINE_CACHE(LOAD_ATTR) MISS_WITH_INLINE_CACHE(STORE_ATTR) MISS_WITH_INLINE_CACHE(LOAD_GLOBAL) MISS_WITH_INLINE_CACHE(LOAD_METHOD) -MISS_WITH_CACHE(PRECALL) -MISS_WITH_CACHE(CALL) +MISS_WITH_INLINE_CACHE(PRECALL) +MISS_WITH_INLINE_CACHE(CALL) MISS_WITH_INLINE_CACHE(BINARY_OP) MISS_WITH_INLINE_CACHE(COMPARE_OP) MISS_WITH_INLINE_CACHE(BINARY_SUBSCR) diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index 2060793b4f1c8..7c94999bfdfe4 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -1,21 +1,20 @@ static void *opcode_targets[256] = { - &&_unknown_opcode, + &&TARGET_CACHE, &&TARGET_POP_TOP, &&TARGET_PUSH_NULL, - &&TARGET_CACHE, &&TARGET_BINARY_OP_ADAPTIVE, &&TARGET_BINARY_OP_ADD_INT, &&TARGET_BINARY_OP_ADD_FLOAT, &&TARGET_BINARY_OP_ADD_UNICODE, &&TARGET_BINARY_OP_INPLACE_ADD_UNICODE, + &&TARGET_BINARY_OP_MULTIPLY_INT, &&TARGET_NOP, &&TARGET_UNARY_POSITIVE, &&TARGET_UNARY_NEGATIVE, &&TARGET_UNARY_NOT, - &&TARGET_BINARY_OP_MULTIPLY_INT, &&TARGET_BINARY_OP_MULTIPLY_FLOAT, - &&TARGET_UNARY_INVERT, &&TARGET_BINARY_OP_SUBTRACT_INT, + &&TARGET_UNARY_INVERT, &&TARGET_BINARY_OP_SUBTRACT_FLOAT, &&TARGET_COMPARE_OP_ADAPTIVE, &&TARGET_COMPARE_OP_FLOAT_JUMP, @@ -24,18 +23,18 @@ static void *opcode_targets[256] = { &&TARGET_BINARY_SUBSCR_ADAPTIVE, &&TARGET_BINARY_SUBSCR_GETITEM, &&TARGET_BINARY_SUBSCR_LIST_INT, - &&TARGET_BINARY_SUBSCR, &&TARGET_BINARY_SUBSCR_TUPLE_INT, + &&TARGET_BINARY_SUBSCR, &&TARGET_BINARY_SUBSCR_DICT, &&TARGET_STORE_SUBSCR_ADAPTIVE, &&TARGET_STORE_SUBSCR_LIST_INT, + &&TARGET_STORE_SUBSCR_DICT, &&TARGET_GET_LEN, &&TARGET_MATCH_MAPPING, &&TARGET_MATCH_SEQUENCE, &&TARGET_MATCH_KEYS, - &&TARGET_STORE_SUBSCR_DICT, - &&TARGET_PUSH_EXC_INFO, &&TARGET_CALL_ADAPTIVE, + &&TARGET_PUSH_EXC_INFO, &&TARGET_CALL_PY_EXACT_ARGS, &&TARGET_CALL_PY_WITH_DEFAULTS, &&TARGET_JUMP_ABSOLUTE_QUICK, @@ -48,39 +47,40 @@ static void *opcode_targets[256] = { &&TARGET_LOAD_GLOBAL_MODULE, &&TARGET_LOAD_GLOBAL_BUILTIN, &&TARGET_LOAD_METHOD_ADAPTIVE, + &&TARGET_LOAD_METHOD_CLASS, &&TARGET_WITH_EXCEPT_START, &&TARGET_GET_AITER, &&TARGET_GET_ANEXT, &&TARGET_BEFORE_ASYNC_WITH, &&TARGET_BEFORE_WITH, &&TARGET_END_ASYNC_FOR, - &&TARGET_LOAD_METHOD_CLASS, &&TARGET_LOAD_METHOD_MODULE, &&TARGET_LOAD_METHOD_NO_DICT, &&TARGET_LOAD_METHOD_WITH_DICT, &&TARGET_LOAD_METHOD_WITH_VALUES, + &&TARGET_PRECALL_ADAPTIVE, &&TARGET_STORE_SUBSCR, &&TARGET_DELETE_SUBSCR, - &&TARGET_PRECALL_ADAPTIVE, &&TARGET_PRECALL_BUILTIN_CLASS, &&TARGET_PRECALL_NO_KW_BUILTIN_O, &&TARGET_PRECALL_NO_KW_BUILTIN_FAST, &&TARGET_PRECALL_BUILTIN_FAST_WITH_KEYWORDS, &&TARGET_PRECALL_NO_KW_LEN, + &&TARGET_PRECALL_NO_KW_ISINSTANCE, &&TARGET_GET_ITER, &&TARGET_GET_YIELD_FROM_ITER, &&TARGET_PRINT_EXPR, &&TARGET_LOAD_BUILD_CLASS, - &&TARGET_PRECALL_NO_KW_ISINSTANCE, &&TARGET_PRECALL_NO_KW_LIST_APPEND, + &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_O, &&TARGET_LOAD_ASSERTION_ERROR, &&TARGET_RETURN_GENERATOR, - &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_O, &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS, &&TARGET_PRECALL_NO_KW_STR_1, &&TARGET_PRECALL_NO_KW_TUPLE_1, &&TARGET_PRECALL_NO_KW_TYPE_1, &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST, + &&TARGET_PRECALL_BOUND_METHOD, &&TARGET_LIST_TO_TUPLE, &&TARGET_RETURN_VALUE, &&TARGET_IMPORT_STAR, @@ -139,40 +139,39 @@ static void *opcode_targets[256] = { &&TARGET_LOAD_DEREF, &&TARGET_STORE_DEREF, &&TARGET_DELETE_DEREF, - &&TARGET_PRECALL_BOUND_METHOD, &&TARGET_PRECALL_PYFUNC, - &&TARGET_CALL_FUNCTION_EX, &&TARGET_RESUME_QUICK, + &&TARGET_CALL_FUNCTION_EX, + &&TARGET_STORE_ATTR_ADAPTIVE, &&TARGET_EXTENDED_ARG, &&TARGET_LIST_APPEND, &&TARGET_SET_ADD, &&TARGET_MAP_ADD, &&TARGET_LOAD_CLASSDEREF, &&TARGET_COPY_FREE_VARS, - &&TARGET_STORE_ATTR_ADAPTIVE, + &&TARGET_STORE_ATTR_INSTANCE_VALUE, &&TARGET_RESUME, &&TARGET_MATCH_CLASS, - &&TARGET_STORE_ATTR_INSTANCE_VALUE, &&TARGET_STORE_ATTR_SLOT, + &&TARGET_STORE_ATTR_WITH_HINT, &&TARGET_FORMAT_VALUE, &&TARGET_BUILD_CONST_KEY_MAP, &&TARGET_BUILD_STRING, - &&TARGET_STORE_ATTR_WITH_HINT, &&TARGET_UNPACK_SEQUENCE_ADAPTIVE, - &&TARGET_LOAD_METHOD, &&TARGET_UNPACK_SEQUENCE_LIST, + &&TARGET_LOAD_METHOD, + &&TARGET_UNPACK_SEQUENCE_TUPLE, &&TARGET_LIST_EXTEND, &&TARGET_SET_UPDATE, &&TARGET_DICT_MERGE, &&TARGET_DICT_UPDATE, &&TARGET_PRECALL, - &&TARGET_UNPACK_SEQUENCE_TUPLE, &&TARGET_UNPACK_SEQUENCE_TWO_TUPLE, &&TARGET_LOAD_FAST__LOAD_FAST, &&TARGET_STORE_FAST__LOAD_FAST, + &&TARGET_LOAD_FAST__LOAD_CONST, &&TARGET_CALL, &&TARGET_KW_NAMES, - &&TARGET_LOAD_FAST__LOAD_CONST, &&TARGET_LOAD_CONST__LOAD_FAST, &&TARGET_STORE_FAST__STORE_FAST, &&_unknown_opcode, @@ -254,5 +253,6 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, + &&_unknown_opcode, &&TARGET_DO_TRACING }; diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 9228778d6bd04..8abd536f5534d 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -774,6 +774,16 @@ pycore_init_builtins(PyThreadState *tstate) Py_INCREF(builtins_dict); interp->builtins = builtins_dict; + PyObject *isinstance = PyDict_GetItem(builtins_dict, &_Py_ID(isinstance)); + assert(isinstance); + interp->callable_cache.isinstance = isinstance; + PyObject *len = PyDict_GetItem(builtins_dict, &_Py_ID(len)); + assert(len); + interp->callable_cache.len = len; + PyObject *list_append = _PyType_Lookup(&PyList_Type, &_Py_ID(append)); + assert(list_append); + interp->callable_cache.list_append = list_append; + if (_PyBuiltins_AddExceptions(bimod) < 0) { return _PyStatus_ERR("failed to add exceptions to builtins"); } diff --git a/Python/specialize.c b/Python/specialize.c index 417eece88b86a..dae4e3fa188bd 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -56,13 +56,6 @@ static uint8_t adaptive_opcodes[256] = { [UNPACK_SEQUENCE] = UNPACK_SEQUENCE_ADAPTIVE, }; -/* The number of cache entries required for a "family" of instructions. */ -static uint8_t cache_requirements[256] = { - [STORE_SUBSCR] = 0, - [CALL] = 2, /* _PyAdaptiveEntry and _PyObjectCache/_PyCallCache */ - [PRECALL] = 2, /* _PyAdaptiveEntry and _PyObjectCache/_PyCallCache */ -}; - Py_ssize_t _Py_QuickenedCount = 0; #ifdef Py_STATS PyStats _py_stats = { 0 }; @@ -282,137 +275,41 @@ _Py_PrintSpecializationStats(int to_file) #define SPECIALIZATION_FAIL(opcode, kind) ((void)0) #endif -static SpecializedCacheOrInstruction * -allocate(int cache_count, int instruction_count) +static _Py_CODEUNIT * +allocate(int instruction_count) { - assert(sizeof(SpecializedCacheOrInstruction) == 2*sizeof(int32_t)); - assert(sizeof(SpecializedCacheEntry) == 2*sizeof(int32_t)); - assert(cache_count > 0); assert(instruction_count > 0); - int count = cache_count + (instruction_count + INSTRUCTIONS_PER_ENTRY -1)/INSTRUCTIONS_PER_ENTRY; - SpecializedCacheOrInstruction *array = (SpecializedCacheOrInstruction *) - PyMem_Malloc(sizeof(SpecializedCacheOrInstruction) * count); + void *array = PyMem_Malloc(sizeof(_Py_CODEUNIT) * instruction_count); if (array == NULL) { PyErr_NoMemory(); return NULL; } _Py_QuickenedCount++; - array[0].entry.zero.cache_count = cache_count; - return array; + return (_Py_CODEUNIT *)array; } -static int -get_cache_count(SpecializedCacheOrInstruction *quickened) { - return quickened[0].entry.zero.cache_count; -} -/* Return the oparg for the cache_offset and instruction index. - * - * If no cache is needed then return the original oparg. - * If a cache is needed, but cannot be accessed because - * oparg would be too large, then return -1. - * - * Also updates the cache_offset, as it may need to be incremented by - * more than the cache requirements, if many instructions do not need caches. - * - * See pycore_code.h for details of how the cache offset, - * instruction index and oparg are related */ -static int -oparg_from_instruction_and_update_offset(int index, int opcode, int original_oparg, int *cache_offset) { - /* The instruction pointer in the interpreter points to the next - * instruction, so we compute the offset using nexti (index + 1) */ - int nexti = index + 1; - uint8_t need = cache_requirements[opcode]; - if (need == 0) { - return original_oparg; - } - assert(adaptive_opcodes[opcode] != 0); - int oparg = oparg_from_offset_and_nexti(*cache_offset, nexti); - assert(*cache_offset == offset_from_oparg_and_nexti(oparg, nexti)); - /* Some cache space is wasted here as the minimum possible offset is (nexti>>1) */ - if (oparg < 0) { - oparg = 0; - *cache_offset = offset_from_oparg_and_nexti(oparg, nexti); - } - else if (oparg > 255) { - return -1; - } - *cache_offset += need; - return oparg; -} - -static int -entries_needed(const _Py_CODEUNIT *code, int len) -{ - int cache_offset = 0; - int previous_opcode = -1; - for (int i = 0; i < len; i++) { - uint8_t opcode = _Py_OPCODE(code[i]); - if (previous_opcode != EXTENDED_ARG) { - oparg_from_instruction_and_update_offset(i, opcode, 0, &cache_offset); - } - previous_opcode = opcode; - } - return cache_offset + 1; // One extra for the count entry -} - -static inline _Py_CODEUNIT * -first_instruction(SpecializedCacheOrInstruction *quickened) -{ - return &quickened[get_cache_count(quickened)].code[0]; -} - -/** Insert adaptive instructions and superinstructions. - * - * Skip instruction preceded by EXTENDED_ARG for adaptive - * instructions as those are both very rare and tricky - * to handle. - */ +// Insert adaptive instructions and superinstructions. static void -optimize(SpecializedCacheOrInstruction *quickened, int len) +optimize(_Py_CODEUNIT *instructions, int len) { - _Py_CODEUNIT *instructions = first_instruction(quickened); - int cache_offset = 0; int previous_opcode = -1; - int previous_oparg = 0; + int previous_oparg = -1; for(int i = 0; i < len; i++) { int opcode = _Py_OPCODE(instructions[i]); int oparg = _Py_OPARG(instructions[i]); uint8_t adaptive_opcode = adaptive_opcodes[opcode]; if (adaptive_opcode) { - if (_PyOpcode_InlineCacheEntries[opcode]) { - instructions[i] = _Py_MAKECODEUNIT(adaptive_opcode, oparg); - previous_opcode = -1; - i += _PyOpcode_InlineCacheEntries[opcode]; - } - else if (previous_opcode != EXTENDED_ARG) { - int new_oparg = oparg_from_instruction_and_update_offset( - i, opcode, oparg, &cache_offset - ); - if (new_oparg < 0) { - /* Not possible to allocate a cache for this instruction */ - previous_opcode = opcode; - continue; - } - previous_opcode = adaptive_opcode; - int entries_needed = cache_requirements[opcode]; - if (entries_needed) { - /* Initialize the adpative cache entry */ - int cache0_offset = cache_offset-entries_needed; - SpecializedCacheEntry *cache = - _GetSpecializedCacheEntry(instructions, cache0_offset); - cache->adaptive.original_oparg = oparg; - cache->adaptive.counter = 0; - } else { - // oparg is the adaptive cache counter - new_oparg = 0; - } - instructions[i] = _Py_MAKECODEUNIT(adaptive_opcode, new_oparg); - } + instructions[i] = _Py_MAKECODEUNIT(adaptive_opcode, oparg); + int caches = _PyOpcode_InlineCacheEntries[opcode]; + // Make sure the adaptive counter is zero: + assert((caches ? instructions[i + 1] : oparg) == 0); + previous_opcode = -1; + previous_oparg = -1; + i += caches; } else { - /* Super instructions don't use the cache, - * so no need to update the offset. */ + assert(!_PyOpcode_InlineCacheEntries[opcode]); switch (opcode) { case JUMP_ABSOLUTE: instructions[i] = _Py_MAKECODEUNIT(JUMP_ABSOLUTE_QUICK, oparg); @@ -423,23 +320,28 @@ optimize(SpecializedCacheOrInstruction *quickened, int len) case LOAD_FAST: switch(previous_opcode) { case LOAD_FAST: + assert(0 <= previous_oparg); instructions[i-1] = _Py_MAKECODEUNIT(LOAD_FAST__LOAD_FAST, previous_oparg); break; case STORE_FAST: + assert(0 <= previous_oparg); instructions[i-1] = _Py_MAKECODEUNIT(STORE_FAST__LOAD_FAST, previous_oparg); break; case LOAD_CONST: + assert(0 <= previous_oparg); instructions[i-1] = _Py_MAKECODEUNIT(LOAD_CONST__LOAD_FAST, previous_oparg); break; } break; case STORE_FAST: if (previous_opcode == STORE_FAST) { + assert(0 <= previous_oparg); instructions[i-1] = _Py_MAKECODEUNIT(STORE_FAST__STORE_FAST, previous_oparg); } break; case LOAD_CONST: if (previous_opcode == LOAD_FAST) { + assert(0 <= previous_oparg); instructions[i-1] = _Py_MAKECODEUNIT(LOAD_FAST__LOAD_CONST, previous_oparg); } break; @@ -448,7 +350,6 @@ optimize(SpecializedCacheOrInstruction *quickened, int len) previous_oparg = oparg; } } - assert(cache_offset+1 == get_cache_count(quickened)); } int @@ -462,16 +363,14 @@ _Py_Quicken(PyCodeObject *code) { code->co_warmup = QUICKENING_WARMUP_COLDEST; return 0; } - int entry_count = entries_needed(code->co_firstinstr, instr_count); - SpecializedCacheOrInstruction *quickened = allocate(entry_count, instr_count); + _Py_CODEUNIT *quickened = allocate(instr_count); if (quickened == NULL) { return -1; } - _Py_CODEUNIT *new_instructions = first_instruction(quickened); - memcpy(new_instructions, code->co_firstinstr, size); + memcpy(quickened, code->co_firstinstr, size); optimize(quickened, instr_count); code->co_quickened = quickened; - code->co_firstinstr = new_instructions; + code->co_firstinstr = quickened; return 0; } @@ -1516,9 +1415,8 @@ _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *ins } static int -specialize_class_call( - PyObject *callable, _Py_CODEUNIT *instr, - int nargs, PyObject *kwnames, SpecializedCacheEntry *cache) +specialize_class_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, + PyObject *kwnames, int oparg) { assert(_Py_OPCODE(*instr) == PRECALL_ADAPTIVE); PyTypeObject *tp = _PyType_CAST(callable); @@ -1527,7 +1425,7 @@ specialize_class_call( return -1; } if (tp->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) { - if (nargs == 1 && kwnames == NULL && cache->adaptive.original_oparg == 1) { + if (nargs == 1 && kwnames == NULL && oparg == 1) { if (tp == &PyUnicode_Type) { *instr = _Py_MAKECODEUNIT(PRECALL_NO_KW_STR_1, _Py_OPARG(*instr)); return 0; @@ -1577,28 +1475,15 @@ builtin_call_fail_kind(int ml_flags) } #endif -static PyMethodDescrObject *_list_append = NULL; - static int -specialize_method_descriptor( - PyMethodDescrObject *descr, _Py_CODEUNIT *instr, - int nargs, PyObject *kwnames, SpecializedCacheEntry *cache) +specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr, + int nargs, PyObject *kwnames, int oparg) { assert(_Py_OPCODE(*instr) == PRECALL_ADAPTIVE); if (kwnames) { SPECIALIZATION_FAIL(PRECALL, SPEC_FAIL_CALL_KWNAMES); return -1; } - if (_list_append == NULL) { - _list_append = (PyMethodDescrObject *)_PyType_Lookup(&PyList_Type, - &_Py_ID(append)); - } - assert(_list_append != NULL); - if (nargs == 2 && descr == _list_append && cache->adaptive.original_oparg == 1) { - cache[-1].obj.obj = (PyObject *)_list_append; - *instr = _Py_MAKECODEUNIT(PRECALL_NO_KW_LIST_APPEND, _Py_OPARG(*instr)); - return 0; - } switch (descr->d_method->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | @@ -1614,9 +1499,16 @@ specialize_method_descriptor( } case METH_O: { if (nargs != 2) { - SPECIALIZATION_FAIL(PRECALL, SPEC_FAIL_OUT_OF_RANGE); + SPECIALIZATION_FAIL(PRECALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); return -1; } + PyInterpreterState *interp = _PyInterpreterState_GET(); + PyObject *list_append = interp->callable_cache.list_append; + if ((PyObject *)descr == list_append && oparg == 1) { + *instr = _Py_MAKECODEUNIT(PRECALL_NO_KW_LIST_APPEND, + _Py_OPARG(*instr)); + return 0; + } *instr = _Py_MAKECODEUNIT(PRECALL_NO_KW_METHOD_DESCRIPTOR_O, _Py_OPARG(*instr)); return 0; @@ -1632,12 +1524,11 @@ specialize_method_descriptor( } static int -specialize_py_call( - PyFunctionObject *func, _Py_CODEUNIT *instr, - int nargs, PyObject *kwnames, SpecializedCacheEntry *cache) +specialize_py_call(PyFunctionObject *func, _Py_CODEUNIT *instr, int nargs, + PyObject *kwnames) { + _PyCallCache *cache = (_PyCallCache *)(instr + 1); assert(_Py_OPCODE(*instr) == CALL_ADAPTIVE); - _PyCallCache *cache1 = &cache[-1].call; PyCodeObject *code = (PyCodeObject *)func->func_code; int kind = function_kind(code); if (kwnames) { @@ -1649,10 +1540,6 @@ specialize_py_call( return -1; } int argcount = code->co_argcount; - if (argcount > 0xffff) { - SPECIALIZATION_FAIL(CALL, SPEC_FAIL_OUT_OF_RANGE); - return -1; - } int defcount = func->func_defaults == NULL ? 0 : (int)PyTuple_GET_SIZE(func->func_defaults); assert(defcount <= argcount); int min_args = argcount-defcount; @@ -1663,7 +1550,7 @@ specialize_py_call( assert(nargs <= argcount && nargs >= min_args); assert(min_args >= 0 && defcount >= 0); assert(defcount == 0 || func->func_defaults != NULL); - if (min_args > 0xffff || defcount > 0xffff) { + if (min_args > 0xffff) { SPECIALIZATION_FAIL(CALL, SPEC_FAIL_OUT_OF_RANGE); return -1; } @@ -1672,10 +1559,8 @@ specialize_py_call( SPECIALIZATION_FAIL(CALL, SPEC_FAIL_OUT_OF_VERSIONS); return -1; } - cache[0].adaptive.index = nargs; - cache1->func_version = version; - cache1->min_args = min_args; - cache1->defaults_len = defcount; + write_u32(cache->func_version, version); + cache->min_args = min_args; if (argcount == nargs) { *instr = _Py_MAKECODEUNIT(CALL_PY_EXACT_ARGS, _Py_OPARG(*instr)); } @@ -1687,10 +1572,9 @@ specialize_py_call( static int specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, - PyObject *kwnames, SpecializedCacheEntry *cache, PyObject *builtins) + PyObject *kwnames) { assert(_Py_OPCODE(*instr) == PRECALL_ADAPTIVE); - _PyObjectCache *cache1 = &cache[-1].obj; if (PyCFunction_GET_FUNCTION(callable) == NULL) { return 1; } @@ -1707,9 +1591,8 @@ specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, return 1; } /* len(o) */ - PyObject *builtin_len = PyDict_GetItemString(builtins, "len"); - if (callable == builtin_len) { - cache1->obj = builtin_len; // borrowed + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (callable == interp->callable_cache.len) { *instr = _Py_MAKECODEUNIT(PRECALL_NO_KW_LEN, _Py_OPARG(*instr)); return 0; @@ -1725,10 +1608,8 @@ specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, } if (nargs == 2) { /* isinstance(o1, o2) */ - PyObject *builtin_isinstance = PyDict_GetItemString( - builtins, "isinstance"); - if (callable == builtin_isinstance) { - cache1->obj = builtin_isinstance; // borrowed + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (callable == interp->callable_cache.isinstance) { *instr = _Py_MAKECODEUNIT(PRECALL_NO_KW_ISINSTANCE, _Py_OPARG(*instr)); return 0; @@ -1793,44 +1674,44 @@ call_fail_kind(PyObject *callable) int -_Py_Specialize_Precall( - PyObject *callable, _Py_CODEUNIT *instr, - int nargs, PyObject *kwnames, - SpecializedCacheEntry *cache, PyObject *builtins) +_Py_Specialize_Precall(PyObject *callable, _Py_CODEUNIT *instr, int nargs, + PyObject *kwnames, int oparg) { - _PyAdaptiveEntry *cache0 = &cache->adaptive; + assert(_PyOpcode_InlineCacheEntries[PRECALL] == + INLINE_CACHE_ENTRIES_PRECALL); + _PyPrecallCache *cache = (_PyPrecallCache *)(instr + 1); int fail; if (PyCFunction_CheckExact(callable)) { - fail = specialize_c_call(callable, instr, nargs, kwnames, cache, builtins); + fail = specialize_c_call(callable, instr, nargs, kwnames); } else if (PyFunction_Check(callable)) { *instr = _Py_MAKECODEUNIT(PRECALL_PYFUNC, _Py_OPARG(*instr)); fail = 0; } else if (PyType_Check(callable)) { - fail = specialize_class_call(callable, instr, nargs, kwnames, cache); + fail = specialize_class_call(callable, instr, nargs, kwnames, oparg); } else if (Py_IS_TYPE(callable, &PyMethodDescr_Type)) { - fail = specialize_method_descriptor( - (PyMethodDescrObject *)callable, instr, nargs, kwnames, cache); + fail = specialize_method_descriptor((PyMethodDescrObject *)callable, + instr, nargs, kwnames, oparg); } else if (Py_TYPE(callable) == &PyMethod_Type) { *instr = _Py_MAKECODEUNIT(PRECALL_BOUND_METHOD, _Py_OPARG(*instr)); fail = 0; } else { - SPECIALIZATION_FAIL(CALL, call_fail_kind(callable)); + SPECIALIZATION_FAIL(PRECALL, call_fail_kind(callable)); fail = -1; } if (fail) { - STAT_INC(CALL, failure); + STAT_INC(PRECALL, failure); assert(!PyErr_Occurred()); - cache_backoff(cache0); + cache->counter = ADAPTIVE_CACHE_BACKOFF; } else { - STAT_INC(CALL, success); + STAT_INC(PRECALL, success); assert(!PyErr_Occurred()); - cache0->counter = initial_counter_value(); + cache->counter = initial_counter_value(); } return 0; } @@ -1840,15 +1721,15 @@ _Py_Specialize_Precall( - Specialize calling classes. */ int -_Py_Specialize_Call( - PyObject *callable, _Py_CODEUNIT *instr, - int nargs, PyObject *kwnames, - SpecializedCacheEntry *cache) +_Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, + PyObject *kwnames) { - _PyAdaptiveEntry *cache0 = &cache->adaptive; + assert(_PyOpcode_InlineCacheEntries[CALL] == INLINE_CACHE_ENTRIES_CALL); + _PyCallCache *cache = (_PyCallCache *)(instr + 1); int fail; if (PyFunction_Check(callable)) { - fail = specialize_py_call((PyFunctionObject *)callable, instr, nargs, kwnames, cache); + fail = specialize_py_call((PyFunctionObject *)callable, instr, nargs, + kwnames); } else { SPECIALIZATION_FAIL(CALL, call_fail_kind(callable)); @@ -1857,12 +1738,12 @@ _Py_Specialize_Call( if (fail) { STAT_INC(CALL, failure); assert(!PyErr_Occurred()); - cache_backoff(cache0); + cache->counter = ADAPTIVE_CACHE_BACKOFF; } else { STAT_INC(CALL, success); assert(!PyErr_Occurred()); - cache0->counter = initial_counter_value(); + cache->counter = initial_counter_value(); } return 0; } @@ -2238,10 +2119,4 @@ int return SPEC_FAIL_OTHER; } -int -_PySpecialization_ClassifyCallable(PyObject *callable) -{ - return call_fail_kind(callable); -} - #endif From webhook-mailer at python.org Mon Mar 7 15:11:30 2022 From: webhook-mailer at python.org (zooba) Date: Mon, 07 Mar 2022 20:11:30 -0000 Subject: [Python-checkins] bpo-44549: Update bzip2 to 1.0.8 in Windows builds to mitigate CVE-2016-3189 and CVE-2019-12900 (GH-31732) Message-ID: https://github.com/python/cpython/commit/e1639f361ee0dfbf08bb8538839d3d557c1a995c commit: e1639f361ee0dfbf08bb8538839d3d557c1a995c branch: 3.9 author: Steve Dower committer: zooba date: 2022-03-07T20:11:25Z summary: bpo-44549: Update bzip2 to 1.0.8 in Windows builds to mitigate CVE-2016-3189 and CVE-2019-12900 (GH-31732) files: A Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst M PCbuild/get_externals.bat M PCbuild/python.props M PCbuild/readme.txt diff --git a/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst b/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst new file mode 100644 index 0000000000000..0f1ef9af6c617 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst @@ -0,0 +1,2 @@ +Update bzip2 to 1.0.8 in Windows builds to mitigate CVE-2016-3189 and +CVE-2019-12900 diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index accc464f7c204..462e0db361d09 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -51,7 +51,7 @@ if NOT DEFINED PYTHON ( echo.Fetching external libraries... set libraries= -set libraries=%libraries% bzip2-1.0.6 +set libraries=%libraries% bzip2-1.0.8 if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.3.0 if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1m set libraries=%libraries% sqlite-3.37.2.0 diff --git a/PCbuild/python.props b/PCbuild/python.props index 99d448fc1da95..eddb65879d3ab 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -58,7 +58,7 @@ $([System.IO.Path]::GetFullPath(`$(PySourcePath)externals`)) $(ExternalsDir)\ $(ExternalsDir)sqlite-3.37.2.0\ - $(ExternalsDir)bzip2-1.0.6\ + $(ExternalsDir)bzip2-1.0.8\ $(ExternalsDir)xz-5.2.2\ $(ExternalsDir)libffi-3.3.0\ $(ExternalsDir)libffi-3.3.0\$(ArchName)\ diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index b53696f00835e..e8a973c167895 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -158,7 +158,7 @@ interpreter, but they do implement several major features. See the about getting the source for building these libraries. The sub-projects are: _bz2 - Python wrapper for version 1.0.6 of the libbzip2 compression library + Python wrapper for version 1.0.8 of the libbzip2 compression library Homepage: http://www.bzip.org/ _lzma From webhook-mailer at python.org Mon Mar 7 16:46:24 2022 From: webhook-mailer at python.org (zooba) Date: Mon, 07 Mar 2022 21:46:24 -0000 Subject: [Python-checkins] bpo-46932: Update bundled libexpat to 2.4.7 (GH-31736) Message-ID: https://github.com/python/cpython/commit/176835c3d5c70f4c1b152cc2062b549144e37094 commit: 176835c3d5c70f4c1b152cc2062b549144e37094 branch: main author: Steve Dower committer: zooba date: 2022-03-07T21:46:18Z summary: bpo-46932: Update bundled libexpat to 2.4.7 (GH-31736) files: A Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst M Modules/expat/expat.h M Modules/expat/xmlparse.c diff --git a/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst b/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst new file mode 100644 index 0000000000000..8545c656eab89 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst @@ -0,0 +1 @@ +Update bundled libexpat to 2.4.7 diff --git a/Modules/expat/expat.h b/Modules/expat/expat.h index 46a0e1bcd22de..c9214f64070a8 100644 --- a/Modules/expat/expat.h +++ b/Modules/expat/expat.h @@ -15,6 +15,7 @@ Copyright (c) 2016 Cristian Rodr?guez Copyright (c) 2016 Thomas Beutlich Copyright (c) 2017 Rhodri James + Copyright (c) 2022 Thijs Schreijer Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -174,8 +175,10 @@ struct XML_cp { }; /* This is called for an element declaration. See above for - description of the model argument. It's the caller's responsibility - to free model when finished with it. + description of the model argument. It's the user code's responsibility + to free model when finished with it. See XML_FreeContentModel. + There is no need to free the model from the handler, it can be kept + around and freed at a later stage. */ typedef void(XMLCALL *XML_ElementDeclHandler)(void *userData, const XML_Char *name, @@ -237,6 +240,17 @@ XML_ParserCreate(const XML_Char *encoding); and the local part will be concatenated without any separator. It is a programming error to use the separator '\0' with namespace triplets (see XML_SetReturnNSTriplet). + If a namespace separator is chosen that can be part of a URI or + part of an XML name, splitting an expanded name back into its + 1, 2 or 3 original parts on application level in the element handler + may end up vulnerable, so these are advised against; sane choices for + a namespace separator are e.g. '\n' (line feed) and '|' (pipe). + + Note that Expat does not validate namespace URIs (beyond encoding) + against RFC 3986 today (and is not required to do so with regard to + the XML 1.0 namespaces specification) but it may start doing that + in future releases. Before that, an application using Expat must + be ready to receive namespace URIs containing non-URI characters. */ XMLPARSEAPI(XML_Parser) XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); @@ -317,7 +331,7 @@ typedef void(XMLCALL *XML_StartDoctypeDeclHandler)(void *userData, const XML_Char *pubid, int has_internal_subset); -/* This is called for the start of the DOCTYPE declaration when the +/* This is called for the end of the DOCTYPE declaration when the closing > is encountered, but after processing any external subset. */ @@ -1041,7 +1055,7 @@ XML_SetBillionLaughsAttackProtectionActivationThreshold( */ #define XML_MAJOR_VERSION 2 #define XML_MINOR_VERSION 4 -#define XML_MICRO_VERSION 6 +#define XML_MICRO_VERSION 7 #ifdef __cplusplus } diff --git a/Modules/expat/xmlparse.c b/Modules/expat/xmlparse.c index 7db28d07acbcd..05216d997b07f 100644 --- a/Modules/expat/xmlparse.c +++ b/Modules/expat/xmlparse.c @@ -1,4 +1,4 @@ -/* a30d2613dcfdef81475a9d1a349134d2d42722172fdaa7d5bb12ed2aa74b9596 (2.4.6+) +/* fcb1a62fefa945567301146eb98e3ad3413e823a41c4378e84e8b6b6f308d824 (2.4.7+) __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| @@ -34,6 +34,7 @@ Copyright (c) 2019 Vadim Zeitlin Copyright (c) 2021 Dong-hee Na Copyright (c) 2022 Samanta Navarro + Copyright (c) 2022 Jeffrey Walton Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -133,7 +134,7 @@ * BSD / macOS (including <10.7) (arc4random): HAVE_ARC4RANDOM, \ * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \ * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \ - * Linux (including <3.17) / BSD / macOS (including <10.7) (/dev/urandom): XML_DEV_URANDOM, \ + * Linux (including <3.17) / BSD / macOS (including <10.7) / Solaris >=8 (/dev/urandom): XML_DEV_URANDOM, \ * Windows >=Vista (rand_s): _WIN32. \ \ If insist on not using any of these, bypass this error by defining \ @@ -722,6 +723,7 @@ XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) { return XML_ParserCreate_MM(encodingName, NULL, tmp); } +// "xml=http://www.w3.org/XML/1998/namespace" static const XML_Char implicitContext[] = {ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, @@ -3704,12 +3706,124 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, return XML_ERROR_NONE; } +static XML_Bool +is_rfc3986_uri_char(XML_Char candidate) { + // For the RFC 3986 ANBF grammar see + // https://datatracker.ietf.org/doc/html/rfc3986#appendix-A + + switch (candidate) { + // From rule "ALPHA" (uppercase half) + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + + // From rule "ALPHA" (lowercase half) + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': + + // From rule "DIGIT" + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + + // From rule "pct-encoded" + case '%': + + // From rule "unreserved" + case '-': + case '.': + case '_': + case '~': + + // From rule "gen-delims" + case ':': + case '/': + case '?': + case '#': + case '[': + case ']': + case '@': + + // From rule "sub-delims" + case '!': + case '$': + case '&': + case '\'': + case '(': + case ')': + case '*': + case '+': + case ',': + case ';': + case '=': + return XML_TRUE; + + default: + return XML_FALSE; + } +} + /* addBinding() overwrites the value of prefix->binding without checking. Therefore one must keep track of the old value outside of addBinding(). */ static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr) { + // "http://www.w3.org/XML/1998/namespace" static const XML_Char xmlNamespace[] = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, @@ -3720,6 +3834,7 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'}; static const int xmlLen = (int)sizeof(xmlNamespace) / sizeof(XML_Char) - 1; + // "http://www.w3.org/2000/xmlns/" static const XML_Char xmlnsNamespace[] = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, @@ -3760,14 +3875,26 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, && (len > xmlnsLen || uri[len] != xmlnsNamespace[len])) isXMLNS = XML_FALSE; - // NOTE: While Expat does not validate namespace URIs against RFC 3986, - // we have to at least make sure that the XML processor on top of - // Expat (that is splitting tag names by namespace separator into - // 2- or 3-tuples (uri-local or uri-local-prefix)) cannot be confused - // by an attacker putting additional namespace separator characters - // into namespace declarations. That would be ambiguous and not to - // be expected. - if (parser->m_ns && (uri[len] == parser->m_namespaceSeparator)) { + // NOTE: While Expat does not validate namespace URIs against RFC 3986 + // today (and is not REQUIRED to do so with regard to the XML 1.0 + // namespaces specification) we have to at least make sure, that + // the application on top of Expat (that is likely splitting expanded + // element names ("qualified names") of form + // "[uri sep] local [sep prefix] '\0'" back into 1, 2 or 3 pieces + // in its element handler code) cannot be confused by an attacker + // putting additional namespace separator characters into namespace + // declarations. That would be ambiguous and not to be expected. + // + // While the HTML API docs of function XML_ParserCreateNS have been + // advising against use of a namespace separator character that can + // appear in a URI for >20 years now, some widespread applications + // are using URI characters (':' (colon) in particular) for a + // namespace separator, in practice. To keep these applications + // functional, we only reject namespaces URIs containing the + // application-chosen namespace separator if the chosen separator + // is a non-URI character with regard to RFC 3986. + if (parser->m_ns && (uri[len] == parser->m_namespaceSeparator) + && ! is_rfc3986_uri_char(uri[len])) { return XML_ERROR_SYNTAX; } } From webhook-mailer at python.org Mon Mar 7 17:17:38 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 07 Mar 2022 22:17:38 -0000 Subject: [Python-checkins] bpo-46932: Update bundled libexpat to 2.4.7 (GH-31736) Message-ID: https://github.com/python/cpython/commit/1e52e782f9742242923dec43c2bf8c1455a531e7 commit: 1e52e782f9742242923dec43c2bf8c1455a531e7 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-07T14:17:29-08:00 summary: bpo-46932: Update bundled libexpat to 2.4.7 (GH-31736) (cherry picked from commit 176835c3d5c70f4c1b152cc2062b549144e37094) Co-authored-by: Steve Dower files: A Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst M Modules/expat/expat.h M Modules/expat/xmlparse.c diff --git a/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst b/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst new file mode 100644 index 0000000000000..8545c656eab89 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst @@ -0,0 +1 @@ +Update bundled libexpat to 2.4.7 diff --git a/Modules/expat/expat.h b/Modules/expat/expat.h index 46a0e1bcd22de..c9214f64070a8 100644 --- a/Modules/expat/expat.h +++ b/Modules/expat/expat.h @@ -15,6 +15,7 @@ Copyright (c) 2016 Cristian Rodr?guez Copyright (c) 2016 Thomas Beutlich Copyright (c) 2017 Rhodri James + Copyright (c) 2022 Thijs Schreijer Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -174,8 +175,10 @@ struct XML_cp { }; /* This is called for an element declaration. See above for - description of the model argument. It's the caller's responsibility - to free model when finished with it. + description of the model argument. It's the user code's responsibility + to free model when finished with it. See XML_FreeContentModel. + There is no need to free the model from the handler, it can be kept + around and freed at a later stage. */ typedef void(XMLCALL *XML_ElementDeclHandler)(void *userData, const XML_Char *name, @@ -237,6 +240,17 @@ XML_ParserCreate(const XML_Char *encoding); and the local part will be concatenated without any separator. It is a programming error to use the separator '\0' with namespace triplets (see XML_SetReturnNSTriplet). + If a namespace separator is chosen that can be part of a URI or + part of an XML name, splitting an expanded name back into its + 1, 2 or 3 original parts on application level in the element handler + may end up vulnerable, so these are advised against; sane choices for + a namespace separator are e.g. '\n' (line feed) and '|' (pipe). + + Note that Expat does not validate namespace URIs (beyond encoding) + against RFC 3986 today (and is not required to do so with regard to + the XML 1.0 namespaces specification) but it may start doing that + in future releases. Before that, an application using Expat must + be ready to receive namespace URIs containing non-URI characters. */ XMLPARSEAPI(XML_Parser) XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); @@ -317,7 +331,7 @@ typedef void(XMLCALL *XML_StartDoctypeDeclHandler)(void *userData, const XML_Char *pubid, int has_internal_subset); -/* This is called for the start of the DOCTYPE declaration when the +/* This is called for the end of the DOCTYPE declaration when the closing > is encountered, but after processing any external subset. */ @@ -1041,7 +1055,7 @@ XML_SetBillionLaughsAttackProtectionActivationThreshold( */ #define XML_MAJOR_VERSION 2 #define XML_MINOR_VERSION 4 -#define XML_MICRO_VERSION 6 +#define XML_MICRO_VERSION 7 #ifdef __cplusplus } diff --git a/Modules/expat/xmlparse.c b/Modules/expat/xmlparse.c index 7db28d07acbcd..05216d997b07f 100644 --- a/Modules/expat/xmlparse.c +++ b/Modules/expat/xmlparse.c @@ -1,4 +1,4 @@ -/* a30d2613dcfdef81475a9d1a349134d2d42722172fdaa7d5bb12ed2aa74b9596 (2.4.6+) +/* fcb1a62fefa945567301146eb98e3ad3413e823a41c4378e84e8b6b6f308d824 (2.4.7+) __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| @@ -34,6 +34,7 @@ Copyright (c) 2019 Vadim Zeitlin Copyright (c) 2021 Dong-hee Na Copyright (c) 2022 Samanta Navarro + Copyright (c) 2022 Jeffrey Walton Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -133,7 +134,7 @@ * BSD / macOS (including <10.7) (arc4random): HAVE_ARC4RANDOM, \ * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \ * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \ - * Linux (including <3.17) / BSD / macOS (including <10.7) (/dev/urandom): XML_DEV_URANDOM, \ + * Linux (including <3.17) / BSD / macOS (including <10.7) / Solaris >=8 (/dev/urandom): XML_DEV_URANDOM, \ * Windows >=Vista (rand_s): _WIN32. \ \ If insist on not using any of these, bypass this error by defining \ @@ -722,6 +723,7 @@ XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) { return XML_ParserCreate_MM(encodingName, NULL, tmp); } +// "xml=http://www.w3.org/XML/1998/namespace" static const XML_Char implicitContext[] = {ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, @@ -3704,12 +3706,124 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, return XML_ERROR_NONE; } +static XML_Bool +is_rfc3986_uri_char(XML_Char candidate) { + // For the RFC 3986 ANBF grammar see + // https://datatracker.ietf.org/doc/html/rfc3986#appendix-A + + switch (candidate) { + // From rule "ALPHA" (uppercase half) + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + + // From rule "ALPHA" (lowercase half) + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': + + // From rule "DIGIT" + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + + // From rule "pct-encoded" + case '%': + + // From rule "unreserved" + case '-': + case '.': + case '_': + case '~': + + // From rule "gen-delims" + case ':': + case '/': + case '?': + case '#': + case '[': + case ']': + case '@': + + // From rule "sub-delims" + case '!': + case '$': + case '&': + case '\'': + case '(': + case ')': + case '*': + case '+': + case ',': + case ';': + case '=': + return XML_TRUE; + + default: + return XML_FALSE; + } +} + /* addBinding() overwrites the value of prefix->binding without checking. Therefore one must keep track of the old value outside of addBinding(). */ static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr) { + // "http://www.w3.org/XML/1998/namespace" static const XML_Char xmlNamespace[] = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, @@ -3720,6 +3834,7 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'}; static const int xmlLen = (int)sizeof(xmlNamespace) / sizeof(XML_Char) - 1; + // "http://www.w3.org/2000/xmlns/" static const XML_Char xmlnsNamespace[] = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, @@ -3760,14 +3875,26 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, && (len > xmlnsLen || uri[len] != xmlnsNamespace[len])) isXMLNS = XML_FALSE; - // NOTE: While Expat does not validate namespace URIs against RFC 3986, - // we have to at least make sure that the XML processor on top of - // Expat (that is splitting tag names by namespace separator into - // 2- or 3-tuples (uri-local or uri-local-prefix)) cannot be confused - // by an attacker putting additional namespace separator characters - // into namespace declarations. That would be ambiguous and not to - // be expected. - if (parser->m_ns && (uri[len] == parser->m_namespaceSeparator)) { + // NOTE: While Expat does not validate namespace URIs against RFC 3986 + // today (and is not REQUIRED to do so with regard to the XML 1.0 + // namespaces specification) we have to at least make sure, that + // the application on top of Expat (that is likely splitting expanded + // element names ("qualified names") of form + // "[uri sep] local [sep prefix] '\0'" back into 1, 2 or 3 pieces + // in its element handler code) cannot be confused by an attacker + // putting additional namespace separator characters into namespace + // declarations. That would be ambiguous and not to be expected. + // + // While the HTML API docs of function XML_ParserCreateNS have been + // advising against use of a namespace separator character that can + // appear in a URI for >20 years now, some widespread applications + // are using URI characters (':' (colon) in particular) for a + // namespace separator, in practice. To keep these applications + // functional, we only reject namespaces URIs containing the + // application-chosen namespace separator if the chosen separator + // is a non-URI character with regard to RFC 3986. + if (parser->m_ns && (uri[len] == parser->m_namespaceSeparator) + && ! is_rfc3986_uri_char(uri[len])) { return XML_ERROR_SYNTAX; } } From webhook-mailer at python.org Mon Mar 7 17:18:33 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 07 Mar 2022 22:18:33 -0000 Subject: [Python-checkins] bpo-46932: Update bundled libexpat to 2.4.7 (GH-31736) Message-ID: https://github.com/python/cpython/commit/f46a04469114047ff7a4078619450c590ae3f287 commit: f46a04469114047ff7a4078619450c590ae3f287 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-07T14:18:24-08:00 summary: bpo-46932: Update bundled libexpat to 2.4.7 (GH-31736) (cherry picked from commit 176835c3d5c70f4c1b152cc2062b549144e37094) Co-authored-by: Steve Dower files: A Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst M Modules/expat/expat.h M Modules/expat/xmlparse.c diff --git a/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst b/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst new file mode 100644 index 0000000000000..8545c656eab89 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst @@ -0,0 +1 @@ +Update bundled libexpat to 2.4.7 diff --git a/Modules/expat/expat.h b/Modules/expat/expat.h index 46a0e1bcd22de..c9214f64070a8 100644 --- a/Modules/expat/expat.h +++ b/Modules/expat/expat.h @@ -15,6 +15,7 @@ Copyright (c) 2016 Cristian Rodr?guez Copyright (c) 2016 Thomas Beutlich Copyright (c) 2017 Rhodri James + Copyright (c) 2022 Thijs Schreijer Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -174,8 +175,10 @@ struct XML_cp { }; /* This is called for an element declaration. See above for - description of the model argument. It's the caller's responsibility - to free model when finished with it. + description of the model argument. It's the user code's responsibility + to free model when finished with it. See XML_FreeContentModel. + There is no need to free the model from the handler, it can be kept + around and freed at a later stage. */ typedef void(XMLCALL *XML_ElementDeclHandler)(void *userData, const XML_Char *name, @@ -237,6 +240,17 @@ XML_ParserCreate(const XML_Char *encoding); and the local part will be concatenated without any separator. It is a programming error to use the separator '\0' with namespace triplets (see XML_SetReturnNSTriplet). + If a namespace separator is chosen that can be part of a URI or + part of an XML name, splitting an expanded name back into its + 1, 2 or 3 original parts on application level in the element handler + may end up vulnerable, so these are advised against; sane choices for + a namespace separator are e.g. '\n' (line feed) and '|' (pipe). + + Note that Expat does not validate namespace URIs (beyond encoding) + against RFC 3986 today (and is not required to do so with regard to + the XML 1.0 namespaces specification) but it may start doing that + in future releases. Before that, an application using Expat must + be ready to receive namespace URIs containing non-URI characters. */ XMLPARSEAPI(XML_Parser) XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); @@ -317,7 +331,7 @@ typedef void(XMLCALL *XML_StartDoctypeDeclHandler)(void *userData, const XML_Char *pubid, int has_internal_subset); -/* This is called for the start of the DOCTYPE declaration when the +/* This is called for the end of the DOCTYPE declaration when the closing > is encountered, but after processing any external subset. */ @@ -1041,7 +1055,7 @@ XML_SetBillionLaughsAttackProtectionActivationThreshold( */ #define XML_MAJOR_VERSION 2 #define XML_MINOR_VERSION 4 -#define XML_MICRO_VERSION 6 +#define XML_MICRO_VERSION 7 #ifdef __cplusplus } diff --git a/Modules/expat/xmlparse.c b/Modules/expat/xmlparse.c index 7db28d07acbcd..05216d997b07f 100644 --- a/Modules/expat/xmlparse.c +++ b/Modules/expat/xmlparse.c @@ -1,4 +1,4 @@ -/* a30d2613dcfdef81475a9d1a349134d2d42722172fdaa7d5bb12ed2aa74b9596 (2.4.6+) +/* fcb1a62fefa945567301146eb98e3ad3413e823a41c4378e84e8b6b6f308d824 (2.4.7+) __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| @@ -34,6 +34,7 @@ Copyright (c) 2019 Vadim Zeitlin Copyright (c) 2021 Dong-hee Na Copyright (c) 2022 Samanta Navarro + Copyright (c) 2022 Jeffrey Walton Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -133,7 +134,7 @@ * BSD / macOS (including <10.7) (arc4random): HAVE_ARC4RANDOM, \ * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \ * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \ - * Linux (including <3.17) / BSD / macOS (including <10.7) (/dev/urandom): XML_DEV_URANDOM, \ + * Linux (including <3.17) / BSD / macOS (including <10.7) / Solaris >=8 (/dev/urandom): XML_DEV_URANDOM, \ * Windows >=Vista (rand_s): _WIN32. \ \ If insist on not using any of these, bypass this error by defining \ @@ -722,6 +723,7 @@ XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) { return XML_ParserCreate_MM(encodingName, NULL, tmp); } +// "xml=http://www.w3.org/XML/1998/namespace" static const XML_Char implicitContext[] = {ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, @@ -3704,12 +3706,124 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, return XML_ERROR_NONE; } +static XML_Bool +is_rfc3986_uri_char(XML_Char candidate) { + // For the RFC 3986 ANBF grammar see + // https://datatracker.ietf.org/doc/html/rfc3986#appendix-A + + switch (candidate) { + // From rule "ALPHA" (uppercase half) + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + + // From rule "ALPHA" (lowercase half) + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': + + // From rule "DIGIT" + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + + // From rule "pct-encoded" + case '%': + + // From rule "unreserved" + case '-': + case '.': + case '_': + case '~': + + // From rule "gen-delims" + case ':': + case '/': + case '?': + case '#': + case '[': + case ']': + case '@': + + // From rule "sub-delims" + case '!': + case '$': + case '&': + case '\'': + case '(': + case ')': + case '*': + case '+': + case ',': + case ';': + case '=': + return XML_TRUE; + + default: + return XML_FALSE; + } +} + /* addBinding() overwrites the value of prefix->binding without checking. Therefore one must keep track of the old value outside of addBinding(). */ static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr) { + // "http://www.w3.org/XML/1998/namespace" static const XML_Char xmlNamespace[] = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, @@ -3720,6 +3834,7 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'}; static const int xmlLen = (int)sizeof(xmlNamespace) / sizeof(XML_Char) - 1; + // "http://www.w3.org/2000/xmlns/" static const XML_Char xmlnsNamespace[] = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, @@ -3760,14 +3875,26 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, && (len > xmlnsLen || uri[len] != xmlnsNamespace[len])) isXMLNS = XML_FALSE; - // NOTE: While Expat does not validate namespace URIs against RFC 3986, - // we have to at least make sure that the XML processor on top of - // Expat (that is splitting tag names by namespace separator into - // 2- or 3-tuples (uri-local or uri-local-prefix)) cannot be confused - // by an attacker putting additional namespace separator characters - // into namespace declarations. That would be ambiguous and not to - // be expected. - if (parser->m_ns && (uri[len] == parser->m_namespaceSeparator)) { + // NOTE: While Expat does not validate namespace URIs against RFC 3986 + // today (and is not REQUIRED to do so with regard to the XML 1.0 + // namespaces specification) we have to at least make sure, that + // the application on top of Expat (that is likely splitting expanded + // element names ("qualified names") of form + // "[uri sep] local [sep prefix] '\0'" back into 1, 2 or 3 pieces + // in its element handler code) cannot be confused by an attacker + // putting additional namespace separator characters into namespace + // declarations. That would be ambiguous and not to be expected. + // + // While the HTML API docs of function XML_ParserCreateNS have been + // advising against use of a namespace separator character that can + // appear in a URI for >20 years now, some widespread applications + // are using URI characters (':' (colon) in particular) for a + // namespace separator, in practice. To keep these applications + // functional, we only reject namespaces URIs containing the + // application-chosen namespace separator if the chosen separator + // is a non-URI character with regard to RFC 3986. + if (parser->m_ns && (uri[len] == parser->m_namespaceSeparator) + && ! is_rfc3986_uri_char(uri[len])) { return XML_ERROR_SYNTAX; } } From webhook-mailer at python.org Mon Mar 7 17:18:58 2022 From: webhook-mailer at python.org (tiran) Date: Mon, 07 Mar 2022 22:18:58 -0000 Subject: [Python-checkins] bpo-46933: Fix make distclean regression (GH-31737) Message-ID: https://github.com/python/cpython/commit/47cca0492b3c379823d4bdb600be56a633e5bb88 commit: 47cca0492b3c379823d4bdb600be56a633e5bb88 branch: main author: Erlend Egeberg Aasland committer: tiran date: 2022-03-07T23:18:54+01:00 summary: bpo-46933: Fix make distclean regression (GH-31737) files: M Makefile.pre.in diff --git a/Makefile.pre.in b/Makefile.pre.in index d2b1a7ce458d9..1b40764b2ef95 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -2384,7 +2384,7 @@ distclean: clobber for file in $(srcdir)/Lib/test/data/* ; do \ if test "$$file" != "$(srcdir)/Lib/test/data/README"; then rm "$$file"; fi; \ done - -rm -f core Makefile Makefile.pre config.status Modules/Setup.local + -rm -f core Makefile Makefile.pre config.status Modules/Setup.local \ Modules/Setup.bootstrap Modules/Setup.stdlib \ Modules/ld_so_aix Modules/python.exp Misc/python.pc \ Misc/python-embed.pc Misc/python-config.sh From webhook-mailer at python.org Mon Mar 7 18:11:56 2022 From: webhook-mailer at python.org (ned-deily) Date: Mon, 07 Mar 2022 23:11:56 -0000 Subject: [Python-checkins] bpo-46932: Update bundled libexpat to 2.4.7 (GH-31736) (GH-31741) Message-ID: https://github.com/python/cpython/commit/f656bc1cdbdfaaa07f66ed97e011b258b97e2788 commit: f656bc1cdbdfaaa07f66ed97e011b258b97e2788 branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ned-deily date: 2022-03-07T18:11:09-05:00 summary: bpo-46932: Update bundled libexpat to 2.4.7 (GH-31736) (GH-31741) (cherry picked from commit 176835c3d5c70f4c1b152cc2062b549144e37094) Co-authored-by: Steve Dower files: A Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst M Modules/expat/expat.h M Modules/expat/xmlparse.c diff --git a/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst b/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst new file mode 100644 index 0000000000000..8545c656eab89 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst @@ -0,0 +1 @@ +Update bundled libexpat to 2.4.7 diff --git a/Modules/expat/expat.h b/Modules/expat/expat.h index 46a0e1bcd22de..c9214f64070a8 100644 --- a/Modules/expat/expat.h +++ b/Modules/expat/expat.h @@ -15,6 +15,7 @@ Copyright (c) 2016 Cristian Rodr?guez Copyright (c) 2016 Thomas Beutlich Copyright (c) 2017 Rhodri James + Copyright (c) 2022 Thijs Schreijer Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -174,8 +175,10 @@ struct XML_cp { }; /* This is called for an element declaration. See above for - description of the model argument. It's the caller's responsibility - to free model when finished with it. + description of the model argument. It's the user code's responsibility + to free model when finished with it. See XML_FreeContentModel. + There is no need to free the model from the handler, it can be kept + around and freed at a later stage. */ typedef void(XMLCALL *XML_ElementDeclHandler)(void *userData, const XML_Char *name, @@ -237,6 +240,17 @@ XML_ParserCreate(const XML_Char *encoding); and the local part will be concatenated without any separator. It is a programming error to use the separator '\0' with namespace triplets (see XML_SetReturnNSTriplet). + If a namespace separator is chosen that can be part of a URI or + part of an XML name, splitting an expanded name back into its + 1, 2 or 3 original parts on application level in the element handler + may end up vulnerable, so these are advised against; sane choices for + a namespace separator are e.g. '\n' (line feed) and '|' (pipe). + + Note that Expat does not validate namespace URIs (beyond encoding) + against RFC 3986 today (and is not required to do so with regard to + the XML 1.0 namespaces specification) but it may start doing that + in future releases. Before that, an application using Expat must + be ready to receive namespace URIs containing non-URI characters. */ XMLPARSEAPI(XML_Parser) XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); @@ -317,7 +331,7 @@ typedef void(XMLCALL *XML_StartDoctypeDeclHandler)(void *userData, const XML_Char *pubid, int has_internal_subset); -/* This is called for the start of the DOCTYPE declaration when the +/* This is called for the end of the DOCTYPE declaration when the closing > is encountered, but after processing any external subset. */ @@ -1041,7 +1055,7 @@ XML_SetBillionLaughsAttackProtectionActivationThreshold( */ #define XML_MAJOR_VERSION 2 #define XML_MINOR_VERSION 4 -#define XML_MICRO_VERSION 6 +#define XML_MICRO_VERSION 7 #ifdef __cplusplus } diff --git a/Modules/expat/xmlparse.c b/Modules/expat/xmlparse.c index 7db28d07acbcd..05216d997b07f 100644 --- a/Modules/expat/xmlparse.c +++ b/Modules/expat/xmlparse.c @@ -1,4 +1,4 @@ -/* a30d2613dcfdef81475a9d1a349134d2d42722172fdaa7d5bb12ed2aa74b9596 (2.4.6+) +/* fcb1a62fefa945567301146eb98e3ad3413e823a41c4378e84e8b6b6f308d824 (2.4.7+) __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| @@ -34,6 +34,7 @@ Copyright (c) 2019 Vadim Zeitlin Copyright (c) 2021 Dong-hee Na Copyright (c) 2022 Samanta Navarro + Copyright (c) 2022 Jeffrey Walton Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -133,7 +134,7 @@ * BSD / macOS (including <10.7) (arc4random): HAVE_ARC4RANDOM, \ * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \ * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \ - * Linux (including <3.17) / BSD / macOS (including <10.7) (/dev/urandom): XML_DEV_URANDOM, \ + * Linux (including <3.17) / BSD / macOS (including <10.7) / Solaris >=8 (/dev/urandom): XML_DEV_URANDOM, \ * Windows >=Vista (rand_s): _WIN32. \ \ If insist on not using any of these, bypass this error by defining \ @@ -722,6 +723,7 @@ XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) { return XML_ParserCreate_MM(encodingName, NULL, tmp); } +// "xml=http://www.w3.org/XML/1998/namespace" static const XML_Char implicitContext[] = {ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, @@ -3704,12 +3706,124 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, return XML_ERROR_NONE; } +static XML_Bool +is_rfc3986_uri_char(XML_Char candidate) { + // For the RFC 3986 ANBF grammar see + // https://datatracker.ietf.org/doc/html/rfc3986#appendix-A + + switch (candidate) { + // From rule "ALPHA" (uppercase half) + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + + // From rule "ALPHA" (lowercase half) + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': + + // From rule "DIGIT" + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + + // From rule "pct-encoded" + case '%': + + // From rule "unreserved" + case '-': + case '.': + case '_': + case '~': + + // From rule "gen-delims" + case ':': + case '/': + case '?': + case '#': + case '[': + case ']': + case '@': + + // From rule "sub-delims" + case '!': + case '$': + case '&': + case '\'': + case '(': + case ')': + case '*': + case '+': + case ',': + case ';': + case '=': + return XML_TRUE; + + default: + return XML_FALSE; + } +} + /* addBinding() overwrites the value of prefix->binding without checking. Therefore one must keep track of the old value outside of addBinding(). */ static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr) { + // "http://www.w3.org/XML/1998/namespace" static const XML_Char xmlNamespace[] = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, @@ -3720,6 +3834,7 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'}; static const int xmlLen = (int)sizeof(xmlNamespace) / sizeof(XML_Char) - 1; + // "http://www.w3.org/2000/xmlns/" static const XML_Char xmlnsNamespace[] = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, @@ -3760,14 +3875,26 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, && (len > xmlnsLen || uri[len] != xmlnsNamespace[len])) isXMLNS = XML_FALSE; - // NOTE: While Expat does not validate namespace URIs against RFC 3986, - // we have to at least make sure that the XML processor on top of - // Expat (that is splitting tag names by namespace separator into - // 2- or 3-tuples (uri-local or uri-local-prefix)) cannot be confused - // by an attacker putting additional namespace separator characters - // into namespace declarations. That would be ambiguous and not to - // be expected. - if (parser->m_ns && (uri[len] == parser->m_namespaceSeparator)) { + // NOTE: While Expat does not validate namespace URIs against RFC 3986 + // today (and is not REQUIRED to do so with regard to the XML 1.0 + // namespaces specification) we have to at least make sure, that + // the application on top of Expat (that is likely splitting expanded + // element names ("qualified names") of form + // "[uri sep] local [sep prefix] '\0'" back into 1, 2 or 3 pieces + // in its element handler code) cannot be confused by an attacker + // putting additional namespace separator characters into namespace + // declarations. That would be ambiguous and not to be expected. + // + // While the HTML API docs of function XML_ParserCreateNS have been + // advising against use of a namespace separator character that can + // appear in a URI for >20 years now, some widespread applications + // are using URI characters (':' (colon) in particular) for a + // namespace separator, in practice. To keep these applications + // functional, we only reject namespaces URIs containing the + // application-chosen namespace separator if the chosen separator + // is a non-URI character with regard to RFC 3986. + if (parser->m_ns && (uri[len] == parser->m_namespaceSeparator) + && ! is_rfc3986_uri_char(uri[len])) { return XML_ERROR_SYNTAX; } } From webhook-mailer at python.org Mon Mar 7 22:50:17 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Tue, 08 Mar 2022 03:50:17 -0000 Subject: [Python-checkins] bpo-45680: Improve docs on subscriptions w.r.t. `GenericAlias` objects (GH-29479) Message-ID: https://github.com/python/cpython/commit/50731297a9b6d57eec3b3f89522785b23f7b3e71 commit: 50731297a9b6d57eec3b3f89522785b23f7b3e71 branch: main author: Alex Waygood committer: JelleZijlstra date: 2022-03-07T19:49:28-08:00 summary: bpo-45680: Improve docs on subscriptions w.r.t. `GenericAlias` objects (GH-29479) files: M Doc/reference/expressions.rst diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 0a6651ea5ed67..bb6d1dc1cdd04 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -815,30 +815,44 @@ Subscriptions object: dictionary pair: sequence; item -Subscription of a sequence (string, tuple or list) or mapping (dictionary) -object usually selects an item from the collection: +The subscription of an instance of a :ref:`container class ` +will generally select an element from the container. The subscription of a +:term:`generic class ` will generally return a +:ref:`GenericAlias ` object. .. productionlist:: python-grammar subscription: `primary` "[" `expression_list` "]" -The primary must evaluate to an object that supports subscription (lists or -dictionaries for example). User-defined objects can support subscription by -defining a :meth:`__getitem__` method. +When an object is subscripted, the interpreter will evaluate the primary and +the expression list. -For built-in objects, there are two types of objects that support subscription: +The primary must evaluate to an object that supports subscription. An object +may support subscription through defining one or both of +:meth:`~object.__getitem__` and :meth:`~object.__class_getitem__`. When the +primary is subscripted, the evaluated result of the expression list will be +passed to one of these methods. For more details on when ``__class_getitem__`` +is called instead of ``__getitem__``, see :ref:`classgetitem-versus-getitem`. -If the primary is a mapping, the expression list must evaluate to an object -whose value is one of the keys of the mapping, and the subscription selects the -value in the mapping that corresponds to that key. (The expression list is a -tuple except if it has exactly one item.) +If the expression list contains at least one comma, it will evaluate to a +:class:`tuple` containing the items of the expression list. Otherwise, the +expression list will evaluate to the value of the list's sole member. -If the primary is a sequence, the expression list must evaluate to an integer -or a slice (as discussed in the following section). +For built-in objects, there are two types of objects that support subscription +via :meth:`~object.__getitem__`: + +1. Mappings. If the primary is a :term:`mapping`, the expression list must + evaluate to an object whose value is one of the keys of the mapping, and the + subscription selects the value in the mapping that corresponds to that key. + An example of a builtin mapping class is the :class:`dict` class. +2. Sequences. If the primary is a :term:`sequence`, the expression list must + evaluate to an :class:`int` or a :class:`slice` (as discussed in the + following section). Examples of builtin sequence classes include the + :class:`str`, :class:`list` and :class:`tuple` classes. The formal syntax makes no special provision for negative indices in -sequences; however, built-in sequences all provide a :meth:`__getitem__` +:term:`sequences `. However, built-in sequences all provide a :meth:`~object.__getitem__` method that interprets negative indices by adding the length of the sequence -to the index (so that ``x[-1]`` selects the last item of ``x``). The +to the index so that, for example, ``x[-1]`` selects the last item of ``x``. The resulting value must be a nonnegative integer less than the number of items in the sequence, and the subscription selects the item whose index is that value (counting from zero). Since the support for negative indices and slicing @@ -849,14 +863,10 @@ this method will need to explicitly add that support. single: character pair: string; item -A string's items are characters. A character is not a separate data type but a +A :class:`string ` is a special kind of sequence whose items are +*characters*. A character is not a separate data type but a string of exactly one character. -Subscription of certain :term:`classes ` or :term:`types ` -creates a :ref:`generic alias `. -In this case, user-defined classes can support subscription by providing a -:meth:`__class_getitem__` classmethod. - .. _slicings: From webhook-mailer at python.org Mon Mar 7 22:50:52 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Tue, 08 Mar 2022 03:50:52 -0000 Subject: [Python-checkins] bpo-46170: Improve the error message when subclassing NewType (GH-30268) Message-ID: https://github.com/python/cpython/commit/f391f9bf28f0bba7939d9f9e5a7a6396d2b0df62 commit: f391f9bf28f0bba7939d9f9e5a7a6396d2b0df62 branch: main author: James Hilton-Balfe committer: JelleZijlstra date: 2022-03-07T19:50:46-08:00 summary: bpo-46170: Improve the error message when subclassing NewType (GH-30268) Co-authored-by: Alex Waygood Co-authored-by: Nikita Sobolev Co-authored-by: Ken Jin <28750310+Fidget-Spinner at users.noreply.github.com> files: A Misc/NEWS.d/next/Library/2021-12-26-14-45-51.bpo-46170.AQ7kSM.rst M Lib/test/test_typing.py M Lib/typing.py diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 17d78cffcb4fa..c76aa0adefeb9 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -4423,6 +4423,17 @@ def test_missing__name__(self): ) exec(code, {}) + def test_error_message_when_subclassing(self): + with self.assertRaisesRegex( + TypeError, + re.escape( + "Cannot subclass an instance of NewType. Perhaps you were looking for: " + "`ProUserId = NewType('ProUserId', UserId)`" + ) + ): + class ProUserId(UserId): + ... + class NewTypePythonTests(NewTypeTests, BaseTestCase): module = py_typing diff --git a/Lib/typing.py b/Lib/typing.py index 360129e3db34e..721afb7a03fd9 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -2639,6 +2639,21 @@ def __init__(self, name, tp): if def_mod != 'typing': self.__module__ = def_mod + def __mro_entries__(self, bases): + # We defined __mro_entries__ to get a better error message + # if a user attempts to subclass a NewType instance. bpo-46170 + superclass_name = self.__name__ + + class Dummy: + def __init_subclass__(cls): + subclass_name = cls.__name__ + raise TypeError( + f"Cannot subclass an instance of NewType. Perhaps you were looking for: " + f"`{subclass_name} = NewType({subclass_name!r}, {superclass_name})`" + ) + + return (Dummy,) + def __repr__(self): return f'{self.__module__}.{self.__qualname__}' diff --git a/Misc/NEWS.d/next/Library/2021-12-26-14-45-51.bpo-46170.AQ7kSM.rst b/Misc/NEWS.d/next/Library/2021-12-26-14-45-51.bpo-46170.AQ7kSM.rst new file mode 100644 index 0000000000000..5f266a29ce1cc --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-12-26-14-45-51.bpo-46170.AQ7kSM.rst @@ -0,0 +1 @@ +Improve the error message when you try to subclass an instance of :class:`typing.NewType`. From webhook-mailer at python.org Mon Mar 7 22:56:11 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Tue, 08 Mar 2022 03:56:11 -0000 Subject: [Python-checkins] importlib.metadata: Remove empty footnote section (GH-30451) Message-ID: https://github.com/python/cpython/commit/13331a12c3c4d5007e2ab61514ba1d76cedd8b84 commit: 13331a12c3c4d5007e2ab61514ba1d76cedd8b84 branch: main author: Ned Batchelder committer: JelleZijlstra date: 2022-03-07T19:55:41-08:00 summary: importlib.metadata: Remove empty footnote section (GH-30451) files: M Doc/library/importlib.metadata.rst diff --git a/Doc/library/importlib.metadata.rst b/Doc/library/importlib.metadata.rst index 99bcfeb2d1b55..50fc904535b09 100644 --- a/Doc/library/importlib.metadata.rst +++ b/Doc/library/importlib.metadata.rst @@ -335,6 +335,3 @@ a custom finder, return instances of this derived ``Distribution`` in the .. _`entry point API`: https://setuptools.readthedocs.io/en/latest/pkg_resources.html#entry-points .. _`metadata API`: https://setuptools.readthedocs.io/en/latest/pkg_resources.html#metadata-api .. _`importlib_resources`: https://importlib-resources.readthedocs.io/en/latest/index.html - - -.. rubric:: Footnotes From webhook-mailer at python.org Mon Mar 7 23:03:37 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Tue, 08 Mar 2022 04:03:37 -0000 Subject: [Python-checkins] bpo-43224: Implement PEP 646 changes to typing.py (GH-31021) Message-ID: https://github.com/python/cpython/commit/7a793a388b017be635ea41ef75b0fd8bcf75a309 commit: 7a793a388b017be635ea41ef75b0fd8bcf75a309 branch: main author: Matthew Rahtz committer: JelleZijlstra date: 2022-03-07T20:02:55-08:00 summary: bpo-43224: Implement PEP 646 changes to typing.py (GH-31021) Co-authored-by: Jelle Zijlstra files: A Misc/NEWS.d/next/Library/2022-01-30-22-05-53.bpo-43224.E-eT22.rst M Lib/test/test_typing.py M Lib/typing.py diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index c76aa0adefeb9..5c1e907070ee4 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -10,7 +10,7 @@ from copy import copy, deepcopy from typing import Any, NoReturn, Never, assert_never -from typing import TypeVar, AnyStr +from typing import TypeVar, TypeVarTuple, Unpack, AnyStr from typing import T, KT, VT # Not in __all__. from typing import Union, Optional, Literal from typing import Tuple, List, Dict, MutableMapping @@ -370,6 +370,431 @@ def test_bad_var_substitution(self): list[T][arg] +class UnpackTests(BaseTestCase): + + def test_accepts_single_type(self): + Unpack[Tuple[int]] + + def test_rejects_multiple_types(self): + with self.assertRaises(TypeError): + Unpack[Tuple[int], Tuple[str]] + + def test_rejects_multiple_parameterization(self): + with self.assertRaises(TypeError): + Unpack[Tuple[int]][Tuple[int]] + + def test_cannot_be_called(self): + with self.assertRaises(TypeError): + Unpack() + + +class TypeVarTupleTests(BaseTestCase): + + def test_instance_is_equal_to_itself(self): + Ts = TypeVarTuple('Ts') + self.assertEqual(Ts, Ts) + + def test_different_instances_are_different(self): + self.assertNotEqual(TypeVarTuple('Ts'), TypeVarTuple('Ts')) + + def test_instance_isinstance_of_typevartuple(self): + Ts = TypeVarTuple('Ts') + self.assertIsInstance(Ts, TypeVarTuple) + + def test_cannot_call_instance(self): + Ts = TypeVarTuple('Ts') + with self.assertRaises(TypeError): + Ts() + + def test_unpacked_typevartuple_is_equal_to_itself(self): + Ts = TypeVarTuple('Ts') + self.assertEqual(Unpack[Ts], Unpack[Ts]) + + def test_parameterised_tuple_is_equal_to_itself(self): + Ts = TypeVarTuple('Ts') + self.assertEqual(tuple[Unpack[Ts]], tuple[Unpack[Ts]]) + self.assertEqual(Tuple[Unpack[Ts]], Tuple[Unpack[Ts]]) + + def tests_tuple_arg_ordering_matters(self): + Ts1 = TypeVarTuple('Ts1') + Ts2 = TypeVarTuple('Ts2') + self.assertNotEqual( + tuple[Unpack[Ts1], Unpack[Ts2]], + tuple[Unpack[Ts2], Unpack[Ts1]], + ) + self.assertNotEqual( + Tuple[Unpack[Ts1], Unpack[Ts2]], + Tuple[Unpack[Ts2], Unpack[Ts1]], + ) + + def test_tuple_args_and_parameters_are_correct(self): + Ts = TypeVarTuple('Ts') + t1 = tuple[Unpack[Ts]] + self.assertEqual(t1.__args__, (Unpack[Ts],)) + self.assertEqual(t1.__parameters__, (Ts,)) + t2 = Tuple[Unpack[Ts]] + self.assertEqual(t2.__args__, (Unpack[Ts],)) + self.assertEqual(t2.__parameters__, (Ts,)) + + def test_repr_is_correct(self): + Ts = TypeVarTuple('Ts') + self.assertEqual(repr(Ts), 'Ts') + self.assertEqual(repr(Unpack[Ts]), '*Ts') + self.assertEqual(repr(tuple[Unpack[Ts]]), 'tuple[*Ts]') + self.assertEqual(repr(Tuple[Unpack[Ts]]), 'typing.Tuple[*Ts]') + self.assertEqual(repr(Unpack[tuple[Unpack[Ts]]]), '*tuple[*Ts]') + self.assertEqual(repr(Unpack[Tuple[Unpack[Ts]]]), '*typing.Tuple[*Ts]') + + def test_variadic_class_repr_is_correct(self): + Ts = TypeVarTuple('Ts') + class A(Generic[Unpack[Ts]]): pass + + self.assertTrue(repr(A[()]).endswith('A[()]')) + self.assertTrue(repr(A[float]).endswith('A[float]')) + self.assertTrue(repr(A[float, str]).endswith('A[float, str]')) + self.assertTrue(repr( + A[Unpack[tuple[int, ...]]] + ).endswith( + 'A[*tuple[int, ...]]' + )) + self.assertTrue(repr( + A[float, Unpack[tuple[int, ...]]] + ).endswith( + 'A[float, *tuple[int, ...]]' + )) + self.assertTrue(repr( + A[Unpack[tuple[int, ...]], str] + ).endswith( + 'A[*tuple[int, ...], str]' + )) + self.assertTrue(repr( + A[float, Unpack[tuple[int, ...]], str] + ).endswith( + 'A[float, *tuple[int, ...], str]' + )) + + def test_variadic_class_alias_repr_is_correct(self): + Ts = TypeVarTuple('Ts') + class A(Generic[Unpack[Ts]]): pass + + B = A[Unpack[Ts]] + self.assertTrue(repr(B).endswith('A[*Ts]')) + with self.assertRaises(NotImplementedError): + B[()] + with self.assertRaises(NotImplementedError): + B[float] + with self.assertRaises(NotImplementedError): + B[float, str] + + C = A[Unpack[Ts], int] + self.assertTrue(repr(C).endswith('A[*Ts, int]')) + with self.assertRaises(NotImplementedError): + C[()] + with self.assertRaises(NotImplementedError): + C[float] + with self.assertRaises(NotImplementedError): + C[float, str] + + D = A[int, Unpack[Ts]] + self.assertTrue(repr(D).endswith('A[int, *Ts]')) + with self.assertRaises(NotImplementedError): + D[()] + with self.assertRaises(NotImplementedError): + D[float] + with self.assertRaises(NotImplementedError): + D[float, str] + + E = A[int, Unpack[Ts], str] + self.assertTrue(repr(E).endswith('A[int, *Ts, str]')) + with self.assertRaises(NotImplementedError): + E[()] + with self.assertRaises(NotImplementedError): + E[float] + with self.assertRaises(NotImplementedError): + E[float, bool] + + F = A[Unpack[Ts], Unpack[tuple[str, ...]]] + self.assertTrue(repr(F).endswith('A[*Ts, *tuple[str, ...]]')) + with self.assertRaises(NotImplementedError): + F[()] + with self.assertRaises(NotImplementedError): + F[float] + with self.assertRaises(NotImplementedError): + F[float, int] + + def test_cannot_subclass_class(self): + with self.assertRaises(TypeError): + class C(TypeVarTuple): pass + + def test_cannot_subclass_instance(self): + Ts = TypeVarTuple('Ts') + with self.assertRaises(TypeError): + class C(Ts): pass + with self.assertRaises(TypeError): + class C(Unpack[Ts]): pass + + def test_variadic_class_args_are_correct(self): + T = TypeVar('T') + Ts = TypeVarTuple('Ts') + class A(Generic[Unpack[Ts]]): pass + B = A[()] + self.assertEqual(B.__args__, ()) + C = A[int] + self.assertEqual(C.__args__, (int,)) + D = A[int, str] + self.assertEqual(D.__args__, (int, str)) + E = A[T] + self.assertEqual(E.__args__, (T,)) + F = A[Unpack[Ts]] + self.assertEqual(F.__args__, (Unpack[Ts],)) + G = A[T, Unpack[Ts]] + self.assertEqual(G.__args__, (T, Unpack[Ts])) + H = A[Unpack[Ts], T] + self.assertEqual(H.__args__, (Unpack[Ts], T)) + + def test_variadic_class_origin_is_correct(self): + Ts = TypeVarTuple('Ts') + class D(Generic[Unpack[Ts]]): pass + self.assertIs(D[int].__origin__, D) + self.assertIs(D[T].__origin__, D) + self.assertIs(D[Unpack[Ts]].__origin__, D) + + def test_tuple_args_are_correct(self): + Ts = TypeVarTuple('Ts') + + self.assertEqual(tuple[Unpack[Ts]].__args__, (Unpack[Ts],)) + self.assertEqual(Tuple[Unpack[Ts]].__args__, (Unpack[Ts],)) + + self.assertEqual(tuple[Unpack[Ts], int].__args__, (Unpack[Ts], int)) + self.assertEqual(Tuple[Unpack[Ts], int].__args__, (Unpack[Ts], int)) + + self.assertEqual(tuple[int, Unpack[Ts]].__args__, (int, Unpack[Ts])) + self.assertEqual(Tuple[int, Unpack[Ts]].__args__, (int, Unpack[Ts])) + + self.assertEqual(tuple[int, Unpack[Ts], str].__args__, + (int, Unpack[Ts], str)) + self.assertEqual(Tuple[int, Unpack[Ts], str].__args__, + (int, Unpack[Ts], str)) + + self.assertEqual(tuple[Unpack[Ts], int].__args__, (Unpack[Ts], int)) + self.assertEqual(Tuple[Unpack[Ts]].__args__, (Unpack[Ts],)) + + def test_callable_args_are_correct(self): + Ts = TypeVarTuple('Ts') + Ts1 = TypeVarTuple('Ts1') + Ts2 = TypeVarTuple('Ts2') + + # TypeVarTuple in the arguments + + a = Callable[[Unpack[Ts]], None] + self.assertEqual(a.__args__, (Unpack[Ts], type(None))) + + b = Callable[[int, Unpack[Ts]], None] + self.assertEqual(b.__args__, (int, Unpack[Ts], type(None))) + + c = Callable[[Unpack[Ts], int], None] + self.assertEqual(c.__args__, (Unpack[Ts], int, type(None))) + + d = Callable[[str, Unpack[Ts], int], None] + self.assertEqual(d.__args__, (str, Unpack[Ts], int, type(None))) + + # TypeVarTuple as the return + + e = Callable[[None], Unpack[Ts]] + self.assertEqual(e.__args__, (type(None), Unpack[Ts])) + + f = Callable[[None], tuple[int, Unpack[Ts]]] + self.assertEqual(f.__args__, (type(None), tuple[int, Unpack[Ts]])) + + g = Callable[[None], tuple[Unpack[Ts], int]] + self.assertEqual(g.__args__, (type(None), tuple[Unpack[Ts], int])) + + h = Callable[[None], tuple[str, Unpack[Ts], int]] + self.assertEqual(h.__args__, (type(None), tuple[str, Unpack[Ts], int])) + + # TypeVarTuple in both + + i = Callable[[Unpack[Ts]], Unpack[Ts]] + self.assertEqual(i.__args__, (Unpack[Ts], Unpack[Ts])) + + j = Callable[[Unpack[Ts1]], Unpack[Ts2]] + self.assertEqual(j.__args__, (Unpack[Ts1], Unpack[Ts2])) + + def test_variadic_class_with_duplicate_typevartuples_fails(self): + Ts1 = TypeVarTuple('Ts1') + Ts2 = TypeVarTuple('Ts2') + with self.assertRaises(TypeError): + class C(Generic[Unpack[Ts1], Unpack[Ts1]]): pass + with self.assertRaises(TypeError): + class C(Generic[Unpack[Ts1], Unpack[Ts2], Unpack[Ts1]]): pass + + def test_type_concatenation_in_variadic_class_argument_list_succeeds(self): + Ts = TypeVarTuple('Ts') + class C(Generic[Unpack[Ts]]): pass + C[int, Unpack[Ts]] + C[Unpack[Ts], int] + C[int, Unpack[Ts], str] + C[int, bool, Unpack[Ts], float, str] + + def test_type_concatenation_in_tuple_argument_list_succeeds(self): + Ts = TypeVarTuple('Ts') + + tuple[int, Unpack[Ts]] + tuple[Unpack[Ts], int] + tuple[int, Unpack[Ts], str] + tuple[int, bool, Unpack[Ts], float, str] + + Tuple[int, Unpack[Ts]] + Tuple[Unpack[Ts], int] + Tuple[int, Unpack[Ts], str] + Tuple[int, bool, Unpack[Ts], float, str] + + def test_variadic_class_definition_using_packed_typevartuple_fails(self): + Ts = TypeVarTuple('Ts') + with self.assertRaises(TypeError): + class C(Generic[Ts]): pass + + def test_variadic_class_definition_using_concrete_types_fails(self): + Ts = TypeVarTuple('Ts') + with self.assertRaises(TypeError): + class E(Generic[Unpack[Ts], int]): pass + + def test_variadic_class_with_2_typevars_accepts_2_or_more_args(self): + Ts = TypeVarTuple('Ts') + T1 = TypeVar('T1') + T2 = TypeVar('T2') + + class A(Generic[T1, T2, Unpack[Ts]]): pass + A[int, str] + A[int, str, float] + A[int, str, float, bool] + + class B(Generic[T1, Unpack[Ts], T2]): pass + B[int, str] + B[int, str, float] + B[int, str, float, bool] + + class C(Generic[Unpack[Ts], T1, T2]): pass + C[int, str] + C[int, str, float] + C[int, str, float, bool] + + def test_variadic_args_annotations_are_correct(self): + Ts = TypeVarTuple('Ts') + def f(*args: Unpack[Ts]): pass + self.assertEqual(f.__annotations__, {'args': Unpack[Ts]}) + + def test_variadic_args_with_ellipsis_annotations_are_correct(self): + Ts = TypeVarTuple('Ts') + + def a(*args: Unpack[tuple[int, ...]]): pass + self.assertEqual(a.__annotations__, + {'args': Unpack[tuple[int, ...]]}) + + def b(*args: Unpack[Tuple[int, ...]]): pass + self.assertEqual(b.__annotations__, + {'args': Unpack[Tuple[int, ...]]}) + + def test_concatenation_in_variadic_args_annotations_are_correct(self): + Ts = TypeVarTuple('Ts') + + # Unpacking using `Unpack`, native `tuple` type + + def a(*args: Unpack[tuple[int, Unpack[Ts]]]): pass + self.assertEqual( + a.__annotations__, + {'args': Unpack[tuple[int, Unpack[Ts]]]}, + ) + + def b(*args: Unpack[tuple[Unpack[Ts], int]]): pass + self.assertEqual( + b.__annotations__, + {'args': Unpack[tuple[Unpack[Ts], int]]}, + ) + + def c(*args: Unpack[tuple[str, Unpack[Ts], int]]): pass + self.assertEqual( + c.__annotations__, + {'args': Unpack[tuple[str, Unpack[Ts], int]]}, + ) + + def d(*args: Unpack[tuple[int, bool, Unpack[Ts], float, str]]): pass + self.assertEqual( + d.__annotations__, + {'args': Unpack[tuple[int, bool, Unpack[Ts], float, str]]}, + ) + + # Unpacking using `Unpack`, `Tuple` type from typing.py + + def e(*args: Unpack[Tuple[int, Unpack[Ts]]]): pass + self.assertEqual( + e.__annotations__, + {'args': Unpack[Tuple[int, Unpack[Ts]]]}, + ) + + def f(*args: Unpack[Tuple[Unpack[Ts], int]]): pass + self.assertEqual( + f.__annotations__, + {'args': Unpack[Tuple[Unpack[Ts], int]]}, + ) + + def g(*args: Unpack[Tuple[str, Unpack[Ts], int]]): pass + self.assertEqual( + g.__annotations__, + {'args': Unpack[Tuple[str, Unpack[Ts], int]]}, + ) + + def h(*args: Unpack[Tuple[int, bool, Unpack[Ts], float, str]]): pass + self.assertEqual( + h.__annotations__, + {'args': Unpack[Tuple[int, bool, Unpack[Ts], float, str]]}, + ) + + def test_variadic_class_same_args_results_in_equalty(self): + Ts = TypeVarTuple('Ts') + class C(Generic[Unpack[Ts]]): pass + + self.assertEqual(C[int], C[int]) + + Ts1 = TypeVarTuple('Ts1') + Ts2 = TypeVarTuple('Ts2') + self.assertEqual( + C[Unpack[Ts1]], + C[Unpack[Ts1]], + ) + self.assertEqual( + C[Unpack[Ts1], Unpack[Ts2]], + C[Unpack[Ts1], Unpack[Ts2]], + ) + self.assertEqual( + C[int, Unpack[Ts1], Unpack[Ts2]], + C[int, Unpack[Ts1], Unpack[Ts2]], + ) + + def test_variadic_class_arg_ordering_matters(self): + Ts = TypeVarTuple('Ts') + class C(Generic[Unpack[Ts]]): pass + + self.assertNotEqual( + C[int, str], + C[str, int], + ) + + Ts1 = TypeVarTuple('Ts1') + Ts2 = TypeVarTuple('Ts2') + self.assertNotEqual( + C[Unpack[Ts1], Unpack[Ts2]], + C[Unpack[Ts2], Unpack[Ts1]], + ) + + def test_variadic_class_arg_typevartuple_identity_matters(self): + Ts = TypeVarTuple('Ts') + class C(Generic[Unpack[Ts]]): pass + Ts1 = TypeVarTuple('Ts1') + Ts2 = TypeVarTuple('Ts2') + self.assertNotEqual(C[Unpack[Ts1]], C[Unpack[Ts2]]) + + class UnionTests(BaseTestCase): def test_basics(self): @@ -1819,6 +2244,11 @@ class NewGeneric(Generic): ... class MyGeneric(Generic[T], Generic[S]): ... with self.assertRaises(TypeError): class MyGeneric(List[T], Generic[S]): ... + with self.assertRaises(TypeError): + Generic[()] + class C(Generic[T]): pass + with self.assertRaises(TypeError): + C[()] def test_init(self): T = TypeVar('T') diff --git a/Lib/typing.py b/Lib/typing.py index 721afb7a03fd9..abb8bcefc5c04 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -5,7 +5,7 @@ * Imports and exports, all public names should be explicitly added to __all__. * Internal helper functions: these should never be used in code outside this module. * _SpecialForm and its instances (special forms): - Any, NoReturn, Never, ClassVar, Union, Optional, Concatenate + Any, NoReturn, Never, ClassVar, Union, Optional, Concatenate, Unpack * Classes whose instances can be type arguments in addition to types: ForwardRef, TypeVar and ParamSpec * The core of internal generics API: _GenericAlias and _VariadicGenericAlias, the latter is @@ -56,6 +56,7 @@ def _idfunc(_, x): 'Tuple', 'Type', 'TypeVar', + 'TypeVarTuple', 'Union', # ABCs (from collections.abc). @@ -139,6 +140,7 @@ def _idfunc(_, x): 'TYPE_CHECKING', 'TypeAlias', 'TypeGuard', + 'Unpack', ] # The pseudo-submodules 're' and 'io' are part of the public @@ -182,7 +184,7 @@ def _type_check(arg, msg, is_argument=True, module=None, *, allow_special_forms= if isinstance(arg, _SpecialForm) or arg in (Generic, Protocol): raise TypeError(f"Plain {arg} is not valid as type argument") if isinstance(arg, (type, TypeVar, ForwardRef, types.UnionType, ParamSpec, - ParamSpecArgs, ParamSpecKwargs)): + ParamSpecArgs, ParamSpecKwargs, TypeVarTuple)): return arg if not callable(arg): raise TypeError(f"{msg} Got {arg!r:.100}.") @@ -793,8 +795,28 @@ def __repr__(self): module_repr = f', module={self.__forward_module__!r}' return f'ForwardRef({self.__forward_arg__!r}{module_repr})' -class _TypeVarLike: - """Mixin for TypeVar-like types (TypeVar and ParamSpec).""" + +def _is_unpacked_typevartuple(x: Any) -> bool: + return ( + isinstance(x, _UnpackGenericAlias) + # If x is Unpack[tuple[...]], __parameters__ will be empty. + and x.__parameters__ + and isinstance(x.__parameters__[0], TypeVarTuple) + ) + + +def _is_typevar_like(x: Any) -> bool: + return isinstance(x, (TypeVar, ParamSpec)) or _is_unpacked_typevartuple(x) + + +class _BoundVarianceMixin: + """Mixin giving __init__ bound and variance arguments. + + This is used by TypeVar and ParamSpec, which both employ the notions of + a type 'bound' (restricting type arguments to be a subtype of some + specified type) and type 'variance' (determining subtype relations between + generic types). + """ def __init__(self, bound, covariant, contravariant): """Used to setup TypeVars and ParamSpec's bound, covariant and contravariant attributes. @@ -827,7 +849,7 @@ def __reduce__(self): return self.__name__ -class TypeVar( _Final, _Immutable, _TypeVarLike, _root=True): +class TypeVar(_Final, _Immutable, _BoundVarianceMixin, _root=True): """Type variable. Usage:: @@ -886,6 +908,39 @@ def __init__(self, name, *constraints, bound=None, self.__module__ = def_mod +class TypeVarTuple(_Final, _Immutable, _root=True): + """Type variable tuple. + + Usage: + + Ts = TypeVarTuple('Ts') # Can be given any name + + Just as a TypeVar (type variable) is a placeholder for a single type, + a TypeVarTuple is a placeholder for an *arbitrary* number of types. For + example, if we define a generic class using a TypeVarTuple: + + class C(Generic[*Ts]): ... + + Then we can parameterize that class with an arbitrary number of type + arguments: + + C[int] # Fine + C[int, str] # Also fine + C[()] # Even this is fine + + For more details, see PEP 646. + """ + + def __init__(self, name): + self._name = name + + def __iter__(self): + yield Unpack[self] + + def __repr__(self): + return self._name + + class ParamSpecArgs(_Final, _Immutable, _root=True): """The args for a ParamSpec object. @@ -934,7 +989,7 @@ def __eq__(self, other): return self.__origin__ == other.__origin__ -class ParamSpec(_Final, _Immutable, _TypeVarLike, _root=True): +class ParamSpec(_Final, _Immutable, _BoundVarianceMixin, _root=True): """Parameter specification variable. Usage:: @@ -1065,6 +1120,45 @@ def __dir__(self): return list(set(super().__dir__() + [attr for attr in dir(self.__origin__) if not _is_dunder(attr)])) + +def _is_unpacked_tuple(x: Any) -> bool: + # Is `x` something like `*tuple[int]` or `*tuple[int, ...]`? + if not isinstance(x, _UnpackGenericAlias): + return False + # Alright, `x` is `Unpack[something]`. + + # `x` will always have `__args__`, because Unpack[] and Unpack[()] + # aren't legal. + unpacked_type = x.__args__[0] + + return getattr(unpacked_type, '__origin__', None) is tuple + + +def _is_unpacked_arbitrary_length_tuple(x: Any) -> bool: + if not _is_unpacked_tuple(x): + return False + unpacked_tuple = x.__args__[0] + + if not hasattr(unpacked_tuple, '__args__'): + # It's `Unpack[tuple]`. We can't make any assumptions about the length + # of the tuple, so it's effectively an arbitrary-length tuple. + return True + + tuple_args = unpacked_tuple.__args__ + if not tuple_args: + # It's `Unpack[tuple[()]]`. + return False + + last_arg = tuple_args[-1] + if last_arg is Ellipsis: + # It's `Unpack[tuple[something, ...]]`, which is arbitrary-length. + return True + + # If the arguments didn't end with an ellipsis, then it's not an + # arbitrary-length tuple. + return False + + # Special typing constructs Union, Optional, Generic, Callable and Tuple # use three special attributes for internal bookkeeping of generic types: # * __parameters__ is a tuple of unique free type parameters of a generic @@ -1103,7 +1197,7 @@ class _GenericAlias(_BaseGenericAlias, _root=True): # TypeVar[bool] def __init__(self, origin, args, *, inst=True, name=None, - _typevar_types=TypeVar, + _typevar_types=(TypeVar, TypeVarTuple), _paramspec_tvars=False): super().__init__(origin, inst=inst, name=name) if not isinstance(args, tuple): @@ -1160,7 +1254,10 @@ def __getitem__(self, args): if (self._paramspec_tvars and any(isinstance(t, ParamSpec) for t in self.__parameters__)): args = _prepare_paramspec_params(self, args) - else: + elif not any(isinstance(p, TypeVarTuple) for p in self.__parameters__): + # We only run this if there are no TypeVarTuples, because we + # don't check variadic generic arity at runtime (to reduce + # complexity of typing.py). _check_generic(self, args, len(self.__parameters__)) new_args = self._determine_new_args(args) @@ -1182,6 +1279,10 @@ def _determine_new_args(self, args): # anything more exotic than a plain `TypeVar`, we need to consider # edge cases. + if any(isinstance(p, TypeVarTuple) for p in self.__parameters__): + raise NotImplementedError( + "Type substitution for TypeVarTuples is not yet implemented" + ) # In the example above, this would be {T3: str} new_arg_by_param = dict(zip(self.__parameters__, args)) @@ -1195,6 +1296,10 @@ def _determine_new_args(self, args): f"ParamSpec, or Concatenate. Got {new_arg}") elif isinstance(old_arg, self._typevar_types): new_arg = new_arg_by_param[old_arg] + elif (TypeVarTuple in self._typevar_types + and _is_unpacked_typevartuple(old_arg)): + original_typevartuple = old_arg.__parameters__[0] + new_arg = new_arg_by_param[original_typevartuple] elif isinstance(old_arg, (_GenericAlias, GenericAlias, types.UnionType)): subparams = old_arg.__parameters__ if not subparams: @@ -1217,6 +1322,17 @@ def _determine_new_args(self, args): # ...we need to be careful; `new_args` should end up as # `(int, str, float)` rather than `([int, str], float)`. new_args.extend(new_arg) + elif _is_unpacked_typevartuple(old_arg): + # Consider the following `_GenericAlias`, `B`: + # class A(Generic[*Ts]): ... + # B = A[T, *Ts] + # If we then do: + # B[float, int, str] + # The `new_arg` corresponding to `T` will be `float`, and the + # `new_arg` corresponding to `*Ts` will be `(int, str)`. We + # should join all these types together in a flat list + # `(float, int, str)` - so again, we should `extend`. + new_args.extend(new_arg) else: new_args.append(new_arg) @@ -1230,7 +1346,11 @@ def __repr__(self): name = 'typing.' + self._name else: name = _type_repr(self.__origin__) - args = ", ".join([_type_repr(a) for a in self.__args__]) + if self.__args__: + args = ", ".join([_type_repr(a) for a in self.__args__]) + else: + # To ensure the repr is eval-able. + args = "()" return f'{name}[{args}]' def __reduce__(self): @@ -1258,6 +1378,9 @@ def __mro_entries__(self, bases): return () return (self.__origin__,) + def __iter__(self): + yield Unpack[self] + # _nparams is the number of accepted parameters, e.g. 0 for Hashable, # 1 for List and 2 for Dict. It may be -1 if variable number of @@ -1365,10 +1488,10 @@ def __getitem__(self, params): return self.copy_with((_TypingEmpty,)) if not isinstance(params, tuple): params = (params,) - if len(params) == 2 and params[1] is ...: + if len(params) >= 2 and params[-1] is ...: msg = "Tuple[t, ...]: t must be a type." - p = _type_check(params[0], msg) - return self.copy_with((p, _TypingEllipsis)) + params = tuple(_type_check(p, msg) for p in params[:-1]) + return self.copy_with((*params, _TypingEllipsis)) msg = "Tuple[t0, t1, ...]: each t must be a type." params = tuple(_type_check(p, msg) for p in params) return self.copy_with(params) @@ -1441,6 +1564,48 @@ def copy_with(self, params): return super().copy_with(params) + at _SpecialForm +def Unpack(self, parameters): + """Type unpack operator. + + The type unpack operator takes the child types from some container type, + such as `tuple[int, str]` or a `TypeVarTuple`, and 'pulls them out'. For + example: + + # For some generic class `Foo`: + Foo[Unpack[tuple[int, str]]] # Equivalent to Foo[int, str] + + Ts = TypeVarTuple('Ts') + # Specifies that `Bar` is generic in an arbitrary number of types. + # (Think of `Ts` as a tuple of an arbitrary number of individual + # `TypeVar`s, which the `Unpack` is 'pulling out' directly into the + # `Generic[]`.) + class Bar(Generic[Unpack[Ts]]): ... + Bar[int] # Valid + Bar[int, str] # Also valid + + From Python 3.11, this can also be done using the `*` operator: + + Foo[*tuple[int, str]] + class Bar(Generic[*Ts]): ... + + Note that there is only some runtime checking of this operator. Not + everything the runtime allows may be accepted by static type checkers. + + For more information, see PEP 646. + """ + item = _type_check(parameters, f'{self} accepts only single type.') + return _UnpackGenericAlias(origin=self, args=(item,)) + + +class _UnpackGenericAlias(_GenericAlias, _root=True): + + def __repr__(self): + # `Unpack` only takes one argument, so __args__ should contain only + # a single item. + return '*' + repr(self.__args__[0]) + + class Generic: """Abstract base class for generic types. @@ -1466,15 +1631,36 @@ def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT: @_tp_cache def __class_getitem__(cls, params): + """Parameterizes a generic class. + + At least, parameterizing a generic class is the *main* thing this method + does. For example, for some generic class `Foo`, this is called when we + do `Foo[int]` - there, with `cls=Foo` and `params=int`. + + However, note that this method is also called when defining generic + classes in the first place with `class Foo(Generic[T]): ...`. + """ if not isinstance(params, tuple): params = (params,) - if not params and cls is not Tuple: - raise TypeError( - f"Parameter list to {cls.__qualname__}[...] cannot be empty") + + if not params: + # We're only ok with `params` being empty if the class's only type + # parameter is a `TypeVarTuple` (which can contain zero types). + class_params = getattr(cls, "__parameters__", None) + only_class_parameter_is_typevartuple = ( + class_params is not None + and len(class_params) == 1 + and isinstance(class_params[0], TypeVarTuple) + ) + if not only_class_parameter_is_typevartuple: + raise TypeError( + f"Parameter list to {cls.__qualname__}[...] cannot be empty" + ) + params = tuple(_type_convert(p) for p in params) if cls in (Generic, Protocol): # Generic and Protocol can only be subscripted with unique type variables. - if not all(isinstance(p, (TypeVar, ParamSpec)) for p in params): + if not all(_is_typevar_like(p) for p in params): raise TypeError( f"Parameters to {cls.__name__}[...] must all be type variables " f"or parameter specification variables.") @@ -1485,11 +1671,16 @@ def __class_getitem__(cls, params): # Subscripting a regular Generic subclass. if any(isinstance(t, ParamSpec) for t in cls.__parameters__): params = _prepare_paramspec_params(cls, params) - else: + elif not any(isinstance(p, TypeVarTuple) for p in cls.__parameters__): + # We only run this if there are no TypeVarTuples, because we + # don't check variadic generic arity at runtime (to reduce + # complexity of typing.py). _check_generic(cls, params, len(cls.__parameters__)) - return _GenericAlias(cls, params, - _typevar_types=(TypeVar, ParamSpec), - _paramspec_tvars=True) + return _GenericAlias( + cls, params, + _typevar_types=(TypeVar, TypeVarTuple, ParamSpec), + _paramspec_tvars=True, + ) def __init_subclass__(cls, *args, **kwargs): super().__init_subclass__(*args, **kwargs) @@ -1501,7 +1692,9 @@ def __init_subclass__(cls, *args, **kwargs): if error: raise TypeError("Cannot inherit from plain Generic") if '__orig_bases__' in cls.__dict__: - tvars = _collect_type_vars(cls.__orig_bases__, (TypeVar, ParamSpec)) + tvars = _collect_type_vars( + cls.__orig_bases__, (TypeVar, TypeVarTuple, ParamSpec) + ) # Look for Generic[T1, ..., Tn]. # If found, tvars must be a subset of it. # If not found, tvars is it. diff --git a/Misc/NEWS.d/next/Library/2022-01-30-22-05-53.bpo-43224.E-eT22.rst b/Misc/NEWS.d/next/Library/2022-01-30-22-05-53.bpo-43224.E-eT22.rst new file mode 100644 index 0000000000000..c248dd7b28778 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-01-30-22-05-53.bpo-43224.E-eT22.rst @@ -0,0 +1 @@ +Implement support for PEP 646 in typing.py. From webhook-mailer at python.org Mon Mar 7 23:04:11 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Tue, 08 Mar 2022 04:04:11 -0000 Subject: [Python-checkins] bpo-46494: Mention the typing_extensions pkg in typing docs (GH-31260) Message-ID: https://github.com/python/cpython/commit/8debeed3075bf4d7e568e65da16bec63cf276f4f commit: 8debeed3075bf4d7e568e65da16bec63cf276f4f branch: main author: Meer Suri <46469858+meersuri at users.noreply.github.com> committer: JelleZijlstra date: 2022-03-07T20:04:04-08:00 summary: bpo-46494: Mention the typing_extensions pkg in typing docs (GH-31260) files: M Doc/library/typing.rst diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index bfcbeb8c7e680..935a261362658 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -32,6 +32,10 @@ In the function ``greeting``, the argument ``name`` is expected to be of type :class:`str` and the return type :class:`str`. Subtypes are accepted as arguments. +New features are frequently added to the ``typing`` module. +The `typing_extensions `_ package +provides backports of these new features to older versions of Python. + .. _relevant-peps: Relevant PEPs From webhook-mailer at python.org Mon Mar 7 23:13:35 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Tue, 08 Mar 2022 04:13:35 -0000 Subject: [Python-checkins] Removed ambiguity in __init_subclass__ docs (GH-31540) Message-ID: https://github.com/python/cpython/commit/ab014978aef303ac60465c9010505d798dc34df8 commit: ab014978aef303ac60465c9010505d798dc34df8 branch: main author: David Gilbertson committer: JelleZijlstra date: 2022-03-07T20:13:01-08:00 summary: Removed ambiguity in __init_subclass__ docs (GH-31540) files: M Doc/reference/datamodel.rst diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index a773b73ce3243..0bcb9dc94f58a 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1971,7 +1971,7 @@ Customizing class creation -------------------------- Whenever a class inherits from another class, :meth:`~object.__init_subclass__` is -called on that class. This way, it is possible to write classes which +called on the parent class. This way, it is possible to write classes which change the behavior of subclasses. This is closely related to class decorators, but where class decorators only affect the specific class they're applied to, ``__init_subclass__`` solely applies to future subclasses of the From webhook-mailer at python.org Mon Mar 7 23:13:35 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 08 Mar 2022 04:13:35 -0000 Subject: [Python-checkins] bpo-45680: Improve docs on subscriptions w.r.t. `GenericAlias` objects (GH-29479) Message-ID: https://github.com/python/cpython/commit/06108c08ddbb4efda804eb74dd33928348102e6f commit: 06108c08ddbb4efda804eb74dd33928348102e6f branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-07T20:12:59-08:00 summary: bpo-45680: Improve docs on subscriptions w.r.t. `GenericAlias` objects (GH-29479) (cherry picked from commit 50731297a9b6d57eec3b3f89522785b23f7b3e71) Co-authored-by: Alex Waygood files: M Doc/reference/expressions.rst diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index d4aae29725fb4..9f136c9a88ff3 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -810,30 +810,44 @@ Subscriptions object: dictionary pair: sequence; item -Subscription of a sequence (string, tuple or list) or mapping (dictionary) -object usually selects an item from the collection: +The subscription of an instance of a :ref:`container class ` +will generally select an element from the container. The subscription of a +:term:`generic class ` will generally return a +:ref:`GenericAlias ` object. .. productionlist:: python-grammar subscription: `primary` "[" `expression_list` "]" -The primary must evaluate to an object that supports subscription (lists or -dictionaries for example). User-defined objects can support subscription by -defining a :meth:`__getitem__` method. +When an object is subscripted, the interpreter will evaluate the primary and +the expression list. -For built-in objects, there are two types of objects that support subscription: +The primary must evaluate to an object that supports subscription. An object +may support subscription through defining one or both of +:meth:`~object.__getitem__` and :meth:`~object.__class_getitem__`. When the +primary is subscripted, the evaluated result of the expression list will be +passed to one of these methods. For more details on when ``__class_getitem__`` +is called instead of ``__getitem__``, see :ref:`classgetitem-versus-getitem`. -If the primary is a mapping, the expression list must evaluate to an object -whose value is one of the keys of the mapping, and the subscription selects the -value in the mapping that corresponds to that key. (The expression list is a -tuple except if it has exactly one item.) +If the expression list contains at least one comma, it will evaluate to a +:class:`tuple` containing the items of the expression list. Otherwise, the +expression list will evaluate to the value of the list's sole member. -If the primary is a sequence, the expression list must evaluate to an integer -or a slice (as discussed in the following section). +For built-in objects, there are two types of objects that support subscription +via :meth:`~object.__getitem__`: + +1. Mappings. If the primary is a :term:`mapping`, the expression list must + evaluate to an object whose value is one of the keys of the mapping, and the + subscription selects the value in the mapping that corresponds to that key. + An example of a builtin mapping class is the :class:`dict` class. +2. Sequences. If the primary is a :term:`sequence`, the expression list must + evaluate to an :class:`int` or a :class:`slice` (as discussed in the + following section). Examples of builtin sequence classes include the + :class:`str`, :class:`list` and :class:`tuple` classes. The formal syntax makes no special provision for negative indices in -sequences; however, built-in sequences all provide a :meth:`__getitem__` +:term:`sequences `. However, built-in sequences all provide a :meth:`~object.__getitem__` method that interprets negative indices by adding the length of the sequence -to the index (so that ``x[-1]`` selects the last item of ``x``). The +to the index so that, for example, ``x[-1]`` selects the last item of ``x``. The resulting value must be a nonnegative integer less than the number of items in the sequence, and the subscription selects the item whose index is that value (counting from zero). Since the support for negative indices and slicing @@ -844,14 +858,10 @@ this method will need to explicitly add that support. single: character pair: string; item -A string's items are characters. A character is not a separate data type but a +A :class:`string ` is a special kind of sequence whose items are +*characters*. A character is not a separate data type but a string of exactly one character. -Subscription of certain :term:`classes ` or :term:`types ` -creates a :ref:`generic alias `. -In this case, user-defined classes can support subscription by providing a -:meth:`__class_getitem__` classmethod. - .. _slicings: From webhook-mailer at python.org Mon Mar 7 23:14:54 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Tue, 08 Mar 2022 04:14:54 -0000 Subject: [Python-checkins] docs: Don't use code formatting for emphasis (GH-30519) Message-ID: https://github.com/python/cpython/commit/badb637c8ce91625122d5f4d71276bfe1a8ed5e9 commit: badb637c8ce91625122d5f4d71276bfe1a8ed5e9 branch: main author: William Andrea committer: JelleZijlstra date: 2022-03-07T20:14:47-08:00 summary: docs: Don't use code formatting for emphasis (GH-30519) files: M Doc/tutorial/controlflow.rst diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index 589263edd3571..f6e013b23e7e5 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -884,7 +884,7 @@ zero or more normal arguments may occur. :: file.write(separator.join(args)) -Normally, these ``variadic`` arguments will be last in the list of formal +Normally, these *variadic* arguments will be last in the list of formal parameters, because they scoop up all remaining input arguments that are passed to the function. Any formal parameters which occur after the ``*args`` parameter are 'keyword-only' arguments, meaning that they can only be used as From webhook-mailer at python.org Mon Mar 7 23:16:01 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 08 Mar 2022 04:16:01 -0000 Subject: [Python-checkins] bpo-45680: Improve docs on subscriptions w.r.t. `GenericAlias` objects (GH-29479) Message-ID: https://github.com/python/cpython/commit/e83f084084296a9b16b83b324a715045d3614c92 commit: e83f084084296a9b16b83b324a715045d3614c92 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-07T20:15:55-08:00 summary: bpo-45680: Improve docs on subscriptions w.r.t. `GenericAlias` objects (GH-29479) (cherry picked from commit 50731297a9b6d57eec3b3f89522785b23f7b3e71) Co-authored-by: Alex Waygood files: M Doc/reference/expressions.rst diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 606e773456032..4ffb6512107f2 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -802,30 +802,44 @@ Subscriptions object: dictionary pair: sequence; item -Subscription of a sequence (string, tuple or list) or mapping (dictionary) -object usually selects an item from the collection: +The subscription of an instance of a :ref:`container class ` +will generally select an element from the container. The subscription of a +:term:`generic class ` will generally return a +:ref:`GenericAlias ` object. .. productionlist:: python-grammar subscription: `primary` "[" `expression_list` "]" -The primary must evaluate to an object that supports subscription (lists or -dictionaries for example). User-defined objects can support subscription by -defining a :meth:`__getitem__` method. +When an object is subscripted, the interpreter will evaluate the primary and +the expression list. -For built-in objects, there are two types of objects that support subscription: +The primary must evaluate to an object that supports subscription. An object +may support subscription through defining one or both of +:meth:`~object.__getitem__` and :meth:`~object.__class_getitem__`. When the +primary is subscripted, the evaluated result of the expression list will be +passed to one of these methods. For more details on when ``__class_getitem__`` +is called instead of ``__getitem__``, see :ref:`classgetitem-versus-getitem`. -If the primary is a mapping, the expression list must evaluate to an object -whose value is one of the keys of the mapping, and the subscription selects the -value in the mapping that corresponds to that key. (The expression list is a -tuple except if it has exactly one item.) +If the expression list contains at least one comma, it will evaluate to a +:class:`tuple` containing the items of the expression list. Otherwise, the +expression list will evaluate to the value of the list's sole member. -If the primary is a sequence, the expression list must evaluate to an integer -or a slice (as discussed in the following section). +For built-in objects, there are two types of objects that support subscription +via :meth:`~object.__getitem__`: + +1. Mappings. If the primary is a :term:`mapping`, the expression list must + evaluate to an object whose value is one of the keys of the mapping, and the + subscription selects the value in the mapping that corresponds to that key. + An example of a builtin mapping class is the :class:`dict` class. +2. Sequences. If the primary is a :term:`sequence`, the expression list must + evaluate to an :class:`int` or a :class:`slice` (as discussed in the + following section). Examples of builtin sequence classes include the + :class:`str`, :class:`list` and :class:`tuple` classes. The formal syntax makes no special provision for negative indices in -sequences; however, built-in sequences all provide a :meth:`__getitem__` +:term:`sequences `. However, built-in sequences all provide a :meth:`~object.__getitem__` method that interprets negative indices by adding the length of the sequence -to the index (so that ``x[-1]`` selects the last item of ``x``). The +to the index so that, for example, ``x[-1]`` selects the last item of ``x``. The resulting value must be a nonnegative integer less than the number of items in the sequence, and the subscription selects the item whose index is that value (counting from zero). Since the support for negative indices and slicing @@ -836,14 +850,10 @@ this method will need to explicitly add that support. single: character pair: string; item -A string's items are characters. A character is not a separate data type but a +A :class:`string ` is a special kind of sequence whose items are +*characters*. A character is not a separate data type but a string of exactly one character. -Subscription of certain :term:`classes ` or :term:`types ` -creates a :ref:`generic alias `. -In this case, user-defined classes can support subscription by providing a -:meth:`__class_getitem__` classmethod. - .. _slicings: From webhook-mailer at python.org Mon Mar 7 23:18:53 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Tue, 08 Mar 2022 04:18:53 -0000 Subject: [Python-checkins] bpo-46878: Purge 'non-standard' from sqlite3 docstrings (GH-31612) Message-ID: https://github.com/python/cpython/commit/4d95fa1ac5d31ff450fb2f31b55ce1eb99d6efcb commit: 4d95fa1ac5d31ff450fb2f31b55ce1eb99d6efcb branch: main author: Erlend Egeberg Aasland committer: JelleZijlstra date: 2022-03-07T20:18:41-08:00 summary: bpo-46878: Purge 'non-standard' from sqlite3 docstrings (GH-31612) files: M Modules/_sqlite/clinic/connection.c.h M Modules/_sqlite/clinic/cursor.c.h M Modules/_sqlite/clinic/module.c.h M Modules/_sqlite/connection.c M Modules/_sqlite/cursor.c M Modules/_sqlite/module.c diff --git a/Modules/_sqlite/clinic/connection.c.h b/Modules/_sqlite/clinic/connection.c.h index 16ad2ee254eca..111e344fd2ae1 100644 --- a/Modules/_sqlite/clinic/connection.c.h +++ b/Modules/_sqlite/clinic/connection.c.h @@ -203,7 +203,7 @@ PyDoc_STRVAR(pysqlite_connection_create_function__doc__, "create_function($self, /, name, narg, func, *, deterministic=False)\n" "--\n" "\n" -"Creates a new function. Non-standard."); +"Creates a new function."); #define PYSQLITE_CONNECTION_CREATE_FUNCTION_METHODDEF \ {"create_function", (PyCFunction)(void(*)(void))pysqlite_connection_create_function, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_create_function__doc__}, @@ -239,7 +239,7 @@ PyDoc_STRVAR(pysqlite_connection_create_aggregate__doc__, "create_aggregate($self, /, name, n_arg, aggregate_class)\n" "--\n" "\n" -"Creates a new aggregate. Non-standard."); +"Creates a new aggregate."); #define PYSQLITE_CONNECTION_CREATE_AGGREGATE_METHODDEF \ {"create_aggregate", (PyCFunction)(void(*)(void))pysqlite_connection_create_aggregate, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_create_aggregate__doc__}, @@ -274,7 +274,7 @@ PyDoc_STRVAR(pysqlite_connection_set_authorizer__doc__, "set_authorizer($self, /, authorizer_callback)\n" "--\n" "\n" -"Sets authorizer callback. Non-standard."); +"Sets authorizer callback."); #define PYSQLITE_CONNECTION_SET_AUTHORIZER_METHODDEF \ {"set_authorizer", (PyCFunction)(void(*)(void))pysqlite_connection_set_authorizer, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_set_authorizer__doc__}, @@ -306,7 +306,7 @@ PyDoc_STRVAR(pysqlite_connection_set_progress_handler__doc__, "set_progress_handler($self, /, progress_handler, n)\n" "--\n" "\n" -"Sets progress handler callback. Non-standard."); +"Sets progress handler callback."); #define PYSQLITE_CONNECTION_SET_PROGRESS_HANDLER_METHODDEF \ {"set_progress_handler", (PyCFunction)(void(*)(void))pysqlite_connection_set_progress_handler, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_set_progress_handler__doc__}, @@ -339,9 +339,7 @@ PyDoc_STRVAR(pysqlite_connection_set_trace_callback__doc__, "set_trace_callback($self, /, trace_callback)\n" "--\n" "\n" -"Sets a trace callback called for each SQL statement (passed as unicode).\n" -"\n" -"Non-standard."); +"Sets a trace callback called for each SQL statement (passed as unicode)."); #define PYSQLITE_CONNECTION_SET_TRACE_CALLBACK_METHODDEF \ {"set_trace_callback", (PyCFunction)(void(*)(void))pysqlite_connection_set_trace_callback, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_set_trace_callback__doc__}, @@ -375,7 +373,7 @@ PyDoc_STRVAR(pysqlite_connection_enable_load_extension__doc__, "enable_load_extension($self, enable, /)\n" "--\n" "\n" -"Enable dynamic loading of SQLite extension modules. Non-standard."); +"Enable dynamic loading of SQLite extension modules."); #define PYSQLITE_CONNECTION_ENABLE_LOAD_EXTENSION_METHODDEF \ {"enable_load_extension", (PyCFunction)pysqlite_connection_enable_load_extension, METH_O, pysqlite_connection_enable_load_extension__doc__}, @@ -408,7 +406,7 @@ PyDoc_STRVAR(pysqlite_connection_load_extension__doc__, "load_extension($self, name, /)\n" "--\n" "\n" -"Load SQLite extension module. Non-standard."); +"Load SQLite extension module."); #define PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF \ {"load_extension", (PyCFunction)pysqlite_connection_load_extension, METH_O, pysqlite_connection_load_extension__doc__}, @@ -448,7 +446,7 @@ PyDoc_STRVAR(pysqlite_connection_execute__doc__, "execute($self, sql, parameters=, /)\n" "--\n" "\n" -"Executes a SQL statement. Non-standard."); +"Executes an SQL statement."); #define PYSQLITE_CONNECTION_EXECUTE_METHODDEF \ {"execute", (PyCFunction)(void(*)(void))pysqlite_connection_execute, METH_FASTCALL, pysqlite_connection_execute__doc__}, @@ -490,7 +488,7 @@ PyDoc_STRVAR(pysqlite_connection_executemany__doc__, "executemany($self, sql, parameters, /)\n" "--\n" "\n" -"Repeatedly executes a SQL statement. Non-standard."); +"Repeatedly executes an SQL statement."); #define PYSQLITE_CONNECTION_EXECUTEMANY_METHODDEF \ {"executemany", (PyCFunction)(void(*)(void))pysqlite_connection_executemany, METH_FASTCALL, pysqlite_connection_executemany__doc__}, @@ -528,7 +526,7 @@ PyDoc_STRVAR(pysqlite_connection_executescript__doc__, "executescript($self, sql_script, /)\n" "--\n" "\n" -"Executes multiple SQL statements at once. Non-standard."); +"Executes multiple SQL statements at once."); #define PYSQLITE_CONNECTION_EXECUTESCRIPT_METHODDEF \ {"executescript", (PyCFunction)pysqlite_connection_executescript, METH_O, pysqlite_connection_executescript__doc__}, @@ -537,7 +535,7 @@ PyDoc_STRVAR(pysqlite_connection_interrupt__doc__, "interrupt($self, /)\n" "--\n" "\n" -"Abort any pending database operation. Non-standard."); +"Abort any pending database operation."); #define PYSQLITE_CONNECTION_INTERRUPT_METHODDEF \ {"interrupt", (PyCFunction)pysqlite_connection_interrupt, METH_NOARGS, pysqlite_connection_interrupt__doc__}, @@ -555,9 +553,7 @@ PyDoc_STRVAR(pysqlite_connection_iterdump__doc__, "iterdump($self, /)\n" "--\n" "\n" -"Returns iterator to the dump of the database in an SQL text format.\n" -"\n" -"Non-standard."); +"Returns iterator to the dump of the database in an SQL text format."); #define PYSQLITE_CONNECTION_ITERDUMP_METHODDEF \ {"iterdump", (PyCFunction)pysqlite_connection_iterdump, METH_NOARGS, pysqlite_connection_iterdump__doc__}, @@ -576,7 +572,7 @@ PyDoc_STRVAR(pysqlite_connection_backup__doc__, " sleep=0.25)\n" "--\n" "\n" -"Makes a backup of the database. Non-standard."); +"Makes a backup of the database."); #define PYSQLITE_CONNECTION_BACKUP_METHODDEF \ {"backup", (PyCFunction)(void(*)(void))pysqlite_connection_backup, METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_backup__doc__}, @@ -667,7 +663,7 @@ PyDoc_STRVAR(pysqlite_connection_create_collation__doc__, "create_collation($self, name, callback, /)\n" "--\n" "\n" -"Creates a collation function. Non-standard."); +"Creates a collation function."); #define PYSQLITE_CONNECTION_CREATE_COLLATION_METHODDEF \ {"create_collation", (PyCFunction)(void(*)(void))pysqlite_connection_create_collation, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_create_collation__doc__}, @@ -836,4 +832,4 @@ getlimit(pysqlite_Connection *self, PyObject *arg) #ifndef PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF #define PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF #endif /* !defined(PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF) */ -/*[clinic end generated code: output=c2faf6563397091b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=176c9095219b17c4 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/cursor.c.h b/Modules/_sqlite/clinic/cursor.c.h index d8a36ac38aaf0..a8de7f216b2bb 100644 --- a/Modules/_sqlite/clinic/cursor.c.h +++ b/Modules/_sqlite/clinic/cursor.c.h @@ -115,7 +115,7 @@ PyDoc_STRVAR(pysqlite_cursor_executescript__doc__, "executescript($self, sql_script, /)\n" "--\n" "\n" -"Executes multiple SQL statements at once. Non-standard."); +"Executes multiple SQL statements at once."); #define PYSQLITE_CURSOR_EXECUTESCRIPT_METHODDEF \ {"executescript", (PyCFunction)pysqlite_cursor_executescript, METH_O, pysqlite_cursor_executescript__doc__}, @@ -289,4 +289,4 @@ pysqlite_cursor_close(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) { return pysqlite_cursor_close_impl(self); } -/*[clinic end generated code: output=514f6eb4e4974671 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ab1375c060ff7021 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/module.c.h b/Modules/_sqlite/clinic/module.c.h index 667343da97f74..f3e0e054a3d2f 100644 --- a/Modules/_sqlite/clinic/module.c.h +++ b/Modules/_sqlite/clinic/module.c.h @@ -118,7 +118,7 @@ PyDoc_STRVAR(pysqlite_complete_statement__doc__, "complete_statement($module, /, statement)\n" "--\n" "\n" -"Checks if a string contains a complete SQL statement. Non-standard."); +"Checks if a string contains a complete SQL statement."); #define PYSQLITE_COMPLETE_STATEMENT_METHODDEF \ {"complete_statement", (PyCFunction)(void(*)(void))pysqlite_complete_statement, METH_FASTCALL|METH_KEYWORDS, pysqlite_complete_statement__doc__}, @@ -164,7 +164,10 @@ PyDoc_STRVAR(pysqlite_enable_shared_cache__doc__, "\n" "Enable or disable shared cache mode for the calling thread.\n" "\n" -"Experimental/Non-standard."); +"This method is deprecated and will be removed in Python 3.12.\n" +"Shared cache is strongly discouraged by the SQLite 3 documentation.\n" +"If shared cache must be used, open the database in URI mode using\n" +"the cache=shared query parameter."); #define PYSQLITE_ENABLE_SHARED_CACHE_METHODDEF \ {"enable_shared_cache", (PyCFunction)(void(*)(void))pysqlite_enable_shared_cache, METH_FASTCALL|METH_KEYWORDS, pysqlite_enable_shared_cache__doc__}, @@ -199,7 +202,7 @@ PyDoc_STRVAR(pysqlite_register_adapter__doc__, "register_adapter($module, type, caster, /)\n" "--\n" "\n" -"Registers an adapter with pysqlite\'s adapter registry. Non-standard."); +"Registers an adapter with sqlite3\'s adapter registry."); #define PYSQLITE_REGISTER_ADAPTER_METHODDEF \ {"register_adapter", (PyCFunction)(void(*)(void))pysqlite_register_adapter, METH_FASTCALL, pysqlite_register_adapter__doc__}, @@ -230,7 +233,7 @@ PyDoc_STRVAR(pysqlite_register_converter__doc__, "register_converter($module, name, converter, /)\n" "--\n" "\n" -"Registers a converter with pysqlite. Non-standard."); +"Registers a converter with sqlite3."); #define PYSQLITE_REGISTER_CONVERTER_METHODDEF \ {"register_converter", (PyCFunction)(void(*)(void))pysqlite_register_converter, METH_FASTCALL, pysqlite_register_converter__doc__}, @@ -296,7 +299,7 @@ PyDoc_STRVAR(pysqlite_adapt__doc__, "adapt($module, obj, proto=PrepareProtocolType, alt=, /)\n" "--\n" "\n" -"Adapt given object to given protocol. Non-standard."); +"Adapt given object to given protocol."); #define PYSQLITE_ADAPT_METHODDEF \ {"adapt", (PyCFunction)(void(*)(void))pysqlite_adapt, METH_FASTCALL, pysqlite_adapt__doc__}, @@ -331,4 +334,4 @@ pysqlite_adapt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=ef03fdbf018d3391 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2cf05d1b089c7be4 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 9f12e691f8912..e4b8ecb5e2d7f 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -916,7 +916,7 @@ _sqlite3.Connection.create_function as pysqlite_connection_create_function * deterministic: bool = False -Creates a new function. Non-standard. +Creates a new function. [clinic start generated code]*/ static PyObject * @@ -924,7 +924,7 @@ pysqlite_connection_create_function_impl(pysqlite_Connection *self, PyTypeObject *cls, const char *name, int narg, PyObject *func, int deterministic) -/*[clinic end generated code: output=8a811529287ad240 input=f0f99754bfeafd8d]*/ +/*[clinic end generated code: output=8a811529287ad240 input=b3e8e1d8ddaffbef]*/ { int rc; int flags = SQLITE_UTF8; @@ -974,7 +974,7 @@ _sqlite3.Connection.create_aggregate as pysqlite_connection_create_aggregate n_arg: int aggregate_class: object -Creates a new aggregate. Non-standard. +Creates a new aggregate. [clinic start generated code]*/ static PyObject * @@ -982,7 +982,7 @@ pysqlite_connection_create_aggregate_impl(pysqlite_Connection *self, PyTypeObject *cls, const char *name, int n_arg, PyObject *aggregate_class) -/*[clinic end generated code: output=1b02d0f0aec7ff96 input=bd527067e6c2e33f]*/ +/*[clinic end generated code: output=1b02d0f0aec7ff96 input=68a2a26366d4c686]*/ { int rc; @@ -1125,14 +1125,14 @@ _sqlite3.Connection.set_authorizer as pysqlite_connection_set_authorizer / authorizer_callback as callable: object -Sets authorizer callback. Non-standard. +Sets authorizer callback. [clinic start generated code]*/ static PyObject * pysqlite_connection_set_authorizer_impl(pysqlite_Connection *self, PyTypeObject *cls, PyObject *callable) -/*[clinic end generated code: output=75fa60114fc971c3 input=9f3e90d3d642c4a0]*/ +/*[clinic end generated code: output=75fa60114fc971c3 input=605d32ba92dd3eca]*/ { if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; @@ -1168,14 +1168,14 @@ _sqlite3.Connection.set_progress_handler as pysqlite_connection_set_progress_han progress_handler as callable: object n: int -Sets progress handler callback. Non-standard. +Sets progress handler callback. [clinic start generated code]*/ static PyObject * pysqlite_connection_set_progress_handler_impl(pysqlite_Connection *self, PyTypeObject *cls, PyObject *callable, int n) -/*[clinic end generated code: output=0739957fd8034a50 input=83e8dcbb4ce183f7]*/ +/*[clinic end generated code: output=0739957fd8034a50 input=f7c1837984bd86db]*/ { if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; @@ -1205,15 +1205,13 @@ _sqlite3.Connection.set_trace_callback as pysqlite_connection_set_trace_callback trace_callback as callable: object Sets a trace callback called for each SQL statement (passed as unicode). - -Non-standard. [clinic start generated code]*/ static PyObject * pysqlite_connection_set_trace_callback_impl(pysqlite_Connection *self, PyTypeObject *cls, PyObject *callable) -/*[clinic end generated code: output=d91048c03bfcee05 input=96f03acec3ec8044]*/ +/*[clinic end generated code: output=d91048c03bfcee05 input=351a94210c5f81bb]*/ { if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; @@ -1257,13 +1255,13 @@ _sqlite3.Connection.enable_load_extension as pysqlite_connection_enable_load_ext enable as onoff: bool(accept={int}) / -Enable dynamic loading of SQLite extension modules. Non-standard. +Enable dynamic loading of SQLite extension modules. [clinic start generated code]*/ static PyObject * pysqlite_connection_enable_load_extension_impl(pysqlite_Connection *self, int onoff) -/*[clinic end generated code: output=9cac37190d388baf input=5c0da5b121121cbc]*/ +/*[clinic end generated code: output=9cac37190d388baf input=5f00e93f7a9d3540]*/ { int rc; @@ -1293,13 +1291,13 @@ _sqlite3.Connection.load_extension as pysqlite_connection_load_extension name as extension_name: str / -Load SQLite extension module. Non-standard. +Load SQLite extension module. [clinic start generated code]*/ static PyObject * pysqlite_connection_load_extension_impl(pysqlite_Connection *self, const char *extension_name) -/*[clinic end generated code: output=47eb1d7312bc97a7 input=0b711574560db9fc]*/ +/*[clinic end generated code: output=47eb1d7312bc97a7 input=edd507389d89d621]*/ { int rc; char* errmsg; @@ -1424,13 +1422,13 @@ _sqlite3.Connection.execute as pysqlite_connection_execute parameters: object = NULL / -Executes a SQL statement. Non-standard. +Executes an SQL statement. [clinic start generated code]*/ static PyObject * pysqlite_connection_execute_impl(pysqlite_Connection *self, PyObject *sql, PyObject *parameters) -/*[clinic end generated code: output=5be05ae01ee17ee4 input=fbd17c75c7140271]*/ +/*[clinic end generated code: output=5be05ae01ee17ee4 input=27aa7792681ddba2]*/ { PyObject* result = 0; @@ -1457,13 +1455,13 @@ _sqlite3.Connection.executemany as pysqlite_connection_executemany parameters: object / -Repeatedly executes a SQL statement. Non-standard. +Repeatedly executes an SQL statement. [clinic start generated code]*/ static PyObject * pysqlite_connection_executemany_impl(pysqlite_Connection *self, PyObject *sql, PyObject *parameters) -/*[clinic end generated code: output=776cd2fd20bfe71f input=4feab80659ffc82b]*/ +/*[clinic end generated code: output=776cd2fd20bfe71f input=495be76551d525db]*/ { PyObject* result = 0; @@ -1489,13 +1487,13 @@ _sqlite3.Connection.executescript as pysqlite_connection_executescript sql_script as script_obj: object / -Executes multiple SQL statements at once. Non-standard. +Executes multiple SQL statements at once. [clinic start generated code]*/ static PyObject * pysqlite_connection_executescript(pysqlite_Connection *self, PyObject *script_obj) -/*[clinic end generated code: output=4c4f9d77aa0ae37d input=b27ae5c24ffb8b43]*/ +/*[clinic end generated code: output=4c4f9d77aa0ae37d input=f6e5f1ccfa313db4]*/ { PyObject* result = 0; @@ -1576,12 +1574,12 @@ collation_callback(void *context, int text1_length, const void *text1_data, /*[clinic input] _sqlite3.Connection.interrupt as pysqlite_connection_interrupt -Abort any pending database operation. Non-standard. +Abort any pending database operation. [clinic start generated code]*/ static PyObject * pysqlite_connection_interrupt_impl(pysqlite_Connection *self) -/*[clinic end generated code: output=f193204bc9e70b47 input=4bd0ad083cf93aa7]*/ +/*[clinic end generated code: output=f193204bc9e70b47 input=75ad03ade7012859]*/ { PyObject* retval = NULL; @@ -1605,13 +1603,11 @@ pysqlite_connection_interrupt_impl(pysqlite_Connection *self) _sqlite3.Connection.iterdump as pysqlite_connection_iterdump Returns iterator to the dump of the database in an SQL text format. - -Non-standard. [clinic start generated code]*/ static PyObject * pysqlite_connection_iterdump_impl(pysqlite_Connection *self) -/*[clinic end generated code: output=586997aaf9808768 input=53bc907cb5eedb85]*/ +/*[clinic end generated code: output=586997aaf9808768 input=1911ca756066da89]*/ { PyObject* retval = NULL; PyObject* module = NULL; @@ -1663,7 +1659,7 @@ _sqlite3.Connection.backup as pysqlite_connection_backup name: str = "main" sleep: double = 0.250 -Makes a backup of the database. Non-standard. +Makes a backup of the database. [clinic start generated code]*/ static PyObject * @@ -1671,7 +1667,7 @@ pysqlite_connection_backup_impl(pysqlite_Connection *self, pysqlite_Connection *target, int pages, PyObject *progress, const char *name, double sleep) -/*[clinic end generated code: output=306a3e6a38c36334 input=c759627ab1ad46ff]*/ +/*[clinic end generated code: output=306a3e6a38c36334 input=c6519d0f59d0fd7f]*/ { int rc; int sleep_ms = (int)(sleep * 1000.0); @@ -1769,7 +1765,7 @@ _sqlite3.Connection.create_collation as pysqlite_connection_create_collation callback as callable: object / -Creates a collation function. Non-standard. +Creates a collation function. [clinic start generated code]*/ static PyObject * @@ -1777,7 +1773,7 @@ pysqlite_connection_create_collation_impl(pysqlite_Connection *self, PyTypeObject *cls, const char *name, PyObject *callable) -/*[clinic end generated code: output=32d339e97869c378 input=fee2c8e5708602ad]*/ +/*[clinic end generated code: output=32d339e97869c378 input=f67ecd2e31e61ad3]*/ { if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index b0dd9dd39c8ee..c8e68218642e8 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -707,13 +707,13 @@ _sqlite3.Cursor.executescript as pysqlite_cursor_executescript sql_script: str / -Executes multiple SQL statements at once. Non-standard. +Executes multiple SQL statements at once. [clinic start generated code]*/ static PyObject * pysqlite_cursor_executescript_impl(pysqlite_Cursor *self, const char *sql_script) -/*[clinic end generated code: output=8fd726dde1c65164 input=1ac0693dc8db02a8]*/ +/*[clinic end generated code: output=8fd726dde1c65164 input=78f093be415a8a2c]*/ { if (!check_cursor(self)) { return NULL; diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index 563105c639100..07f090c4a2614 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -90,12 +90,12 @@ _sqlite3.complete_statement as pysqlite_complete_statement statement: str -Checks if a string contains a complete SQL statement. Non-standard. +Checks if a string contains a complete SQL statement. [clinic start generated code]*/ static PyObject * pysqlite_complete_statement_impl(PyObject *module, const char *statement) -/*[clinic end generated code: output=e55f1ff1952df558 input=f6b24996b31c5c33]*/ +/*[clinic end generated code: output=e55f1ff1952df558 input=ac45d257375bb828]*/ { if (sqlite3_complete(statement)) { return Py_NewRef(Py_True); @@ -111,12 +111,15 @@ _sqlite3.enable_shared_cache as pysqlite_enable_shared_cache Enable or disable shared cache mode for the calling thread. -Experimental/Non-standard. +This method is deprecated and will be removed in Python 3.12. +Shared cache is strongly discouraged by the SQLite 3 documentation. +If shared cache must be used, open the database in URI mode using +the cache=shared query parameter. [clinic start generated code]*/ static PyObject * pysqlite_enable_shared_cache_impl(PyObject *module, int do_enable) -/*[clinic end generated code: output=259c74eedee1516b input=8400e41bc58b6b24]*/ +/*[clinic end generated code: output=259c74eedee1516b input=26e40d5971d3487d]*/ { int rc; @@ -138,13 +141,13 @@ _sqlite3.register_adapter as pysqlite_register_adapter caster: object / -Registers an adapter with pysqlite's adapter registry. Non-standard. +Registers an adapter with sqlite3's adapter registry. [clinic start generated code]*/ static PyObject * pysqlite_register_adapter_impl(PyObject *module, PyTypeObject *type, PyObject *caster) -/*[clinic end generated code: output=a287e8db18e8af23 input=839dad90e2492725]*/ +/*[clinic end generated code: output=a287e8db18e8af23 input=b4bd87afcadc535d]*/ { int rc; @@ -173,13 +176,13 @@ _sqlite3.register_converter as pysqlite_register_converter converter as callable: object / -Registers a converter with pysqlite. Non-standard. +Registers a converter with sqlite3. [clinic start generated code]*/ static PyObject * pysqlite_register_converter_impl(PyObject *module, PyObject *orig_name, PyObject *callable) -/*[clinic end generated code: output=a2f2bfeed7230062 input=e074cf7f4890544f]*/ +/*[clinic end generated code: output=a2f2bfeed7230062 input=90f645419425d6c4]*/ { PyObject* name = NULL; PyObject* retval = NULL; @@ -228,13 +231,13 @@ _sqlite3.adapt as pysqlite_adapt alt: object = NULL / -Adapt given object to given protocol. Non-standard. +Adapt given object to given protocol. [clinic start generated code]*/ static PyObject * pysqlite_adapt_impl(PyObject *module, PyObject *obj, PyObject *proto, PyObject *alt) -/*[clinic end generated code: output=0c3927c5fcd23dd9 input=c8995aeb25d0e542]*/ +/*[clinic end generated code: output=0c3927c5fcd23dd9 input=a53dc9993e81e15f]*/ { pysqlite_state *state = pysqlite_get_state(module); return pysqlite_microprotocols_adapt(state, obj, proto, alt); From webhook-mailer at python.org Mon Mar 7 23:22:05 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 08 Mar 2022 04:22:05 -0000 Subject: [Python-checkins] importlib.metadata: Remove empty footnote section (GH-30451) Message-ID: https://github.com/python/cpython/commit/f6cdf5bdcc7054f0cba2198ca1dc395be6e2d4e6 commit: f6cdf5bdcc7054f0cba2198ca1dc395be6e2d4e6 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-07T20:21:32-08:00 summary: importlib.metadata: Remove empty footnote section (GH-30451) (cherry picked from commit 13331a12c3c4d5007e2ab61514ba1d76cedd8b84) Co-authored-by: Ned Batchelder files: M Doc/library/importlib.metadata.rst diff --git a/Doc/library/importlib.metadata.rst b/Doc/library/importlib.metadata.rst index 99bcfeb2d1b55..50fc904535b09 100644 --- a/Doc/library/importlib.metadata.rst +++ b/Doc/library/importlib.metadata.rst @@ -335,6 +335,3 @@ a custom finder, return instances of this derived ``Distribution`` in the .. _`entry point API`: https://setuptools.readthedocs.io/en/latest/pkg_resources.html#entry-points .. _`metadata API`: https://setuptools.readthedocs.io/en/latest/pkg_resources.html#metadata-api .. _`importlib_resources`: https://importlib-resources.readthedocs.io/en/latest/index.html - - -.. rubric:: Footnotes From webhook-mailer at python.org Mon Mar 7 23:25:51 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 08 Mar 2022 04:25:51 -0000 Subject: [Python-checkins] bpo-46494: Mention the typing_extensions pkg in typing docs (GH-31260) Message-ID: https://github.com/python/cpython/commit/e053f0e9f41791095a924e2aceaaa025a058ed57 commit: e053f0e9f41791095a924e2aceaaa025a058ed57 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-07T20:25:30-08:00 summary: bpo-46494: Mention the typing_extensions pkg in typing docs (GH-31260) (cherry picked from commit 8debeed3075bf4d7e568e65da16bec63cf276f4f) Co-authored-by: Meer Suri <46469858+meersuri at users.noreply.github.com> files: M Doc/library/typing.rst diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 929749bc0b341..e7402affdadee 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -32,6 +32,10 @@ In the function ``greeting``, the argument ``name`` is expected to be of type :class:`str` and the return type :class:`str`. Subtypes are accepted as arguments. +New features are frequently added to the ``typing`` module. +The `typing_extensions `_ package +provides backports of these new features to older versions of Python. + .. _relevant-peps: Relevant PEPs From webhook-mailer at python.org Mon Mar 7 23:29:41 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 08 Mar 2022 04:29:41 -0000 Subject: [Python-checkins] bpo-46494: Mention the typing_extensions pkg in typing docs (GH-31260) Message-ID: https://github.com/python/cpython/commit/0c718e02f60f98275c62e8a2a152f086650e88ea commit: 0c718e02f60f98275c62e8a2a152f086650e88ea branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-07T20:29:09-08:00 summary: bpo-46494: Mention the typing_extensions pkg in typing docs (GH-31260) (cherry picked from commit 8debeed3075bf4d7e568e65da16bec63cf276f4f) Co-authored-by: Meer Suri <46469858+meersuri at users.noreply.github.com> files: M Doc/library/typing.rst diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 2da544884db1d..9e6ef6a642866 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -32,6 +32,10 @@ In the function ``greeting``, the argument ``name`` is expected to be of type :class:`str` and the return type :class:`str`. Subtypes are accepted as arguments. +New features are frequently added to the ``typing`` module. +The `typing_extensions `_ package +provides backports of these new features to older versions of Python. + .. _relevant-peps: Relevant PEPs From webhook-mailer at python.org Mon Mar 7 23:33:45 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 08 Mar 2022 04:33:45 -0000 Subject: [Python-checkins] Removed ambiguity in __init_subclass__ docs (GH-31540) Message-ID: https://github.com/python/cpython/commit/b099363fa701d971ce32a2e99ac90fe7046fae9f commit: b099363fa701d971ce32a2e99ac90fe7046fae9f branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-07T20:33:19-08:00 summary: Removed ambiguity in __init_subclass__ docs (GH-31540) (cherry picked from commit ab014978aef303ac60465c9010505d798dc34df8) Co-authored-by: David Gilbertson files: M Doc/reference/datamodel.rst diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index be1f714113293..55ac99c392755 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1904,7 +1904,7 @@ Customizing class creation -------------------------- Whenever a class inherits from another class, :meth:`~object.__init_subclass__` is -called on that class. This way, it is possible to write classes which +called on the parent class. This way, it is possible to write classes which change the behavior of subclasses. This is closely related to class decorators, but where class decorators only affect the specific class they're applied to, ``__init_subclass__`` solely applies to future subclasses of the From webhook-mailer at python.org Mon Mar 7 23:36:31 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 08 Mar 2022 04:36:31 -0000 Subject: [Python-checkins] docs: Don't use code formatting for emphasis (GH-30519) Message-ID: https://github.com/python/cpython/commit/24ebaf6323d6775e582e99874b08b6c520fae484 commit: 24ebaf6323d6775e582e99874b08b6c520fae484 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-07T20:35:54-08:00 summary: docs: Don't use code formatting for emphasis (GH-30519) (cherry picked from commit badb637c8ce91625122d5f4d71276bfe1a8ed5e9) Co-authored-by: William Andrea files: M Doc/tutorial/controlflow.rst diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index 08202f0344ea3..289d44239822b 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -710,7 +710,7 @@ zero or more normal arguments may occur. :: file.write(separator.join(args)) -Normally, these ``variadic`` arguments will be last in the list of formal +Normally, these *variadic* arguments will be last in the list of formal parameters, because they scoop up all remaining input arguments that are passed to the function. Any formal parameters which occur after the ``*args`` parameter are 'keyword-only' arguments, meaning that they can only be used as From webhook-mailer at python.org Mon Mar 7 23:40:55 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 08 Mar 2022 04:40:55 -0000 Subject: [Python-checkins] Removed ambiguity in __init_subclass__ docs (GH-31540) Message-ID: https://github.com/python/cpython/commit/89c360125bf6562c99fcc17489dc234c624aa387 commit: 89c360125bf6562c99fcc17489dc234c624aa387 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-07T20:40:16-08:00 summary: Removed ambiguity in __init_subclass__ docs (GH-31540) (cherry picked from commit ab014978aef303ac60465c9010505d798dc34df8) Co-authored-by: David Gilbertson files: M Doc/reference/datamodel.rst diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 967308b95ffcb..f4320db60c92a 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1895,7 +1895,7 @@ Customizing class creation -------------------------- Whenever a class inherits from another class, :meth:`~object.__init_subclass__` is -called on that class. This way, it is possible to write classes which +called on the parent class. This way, it is possible to write classes which change the behavior of subclasses. This is closely related to class decorators, but where class decorators only affect the specific class they're applied to, ``__init_subclass__`` solely applies to future subclasses of the From webhook-mailer at python.org Tue Mar 8 03:26:44 2022 From: webhook-mailer at python.org (encukou) Date: Tue, 08 Mar 2022 08:26:44 -0000 Subject: [Python-checkins] bpo-40059: Add tomllib (PEP-680) (GH-31498) Message-ID: https://github.com/python/cpython/commit/591f6754b56cb7f6c31fce8c22528bdf0a99556c commit: 591f6754b56cb7f6c31fce8c22528bdf0a99556c branch: main author: Taneli Hukkinen <3275109+hukkin at users.noreply.github.com> committer: encukou date: 2022-03-08T09:26:13+01:00 summary: bpo-40059: Add tomllib (PEP-680) (GH-31498) This adds a new standard library module, `tomllib`, for parsing TOML. The implementation is based on Tomli (https://github.com/hukkin/tomli). ## Steps taken (converting `tomli` to `tomllib`) - Move everything in `tomli:src/tomli` to `Lib/tomllib`. Exclude `py.typed`. - Remove `__version__ = ...` line from `Lib/tomllib/__init__.py` - Move everything in `tomli:tests` to `Lib/test/test_tomllib`. Exclude the following test data dirs recursively: - `tomli:tests/data/invalid/_external/` - `tomli:tests/data/valid/_external/` - Create `Lib/test/test_tomllib/__main__.py`: ```python import unittest from . import load_tests unittest.main() ``` - Add the following to `Lib/test/test_tomllib/__init__.py`: ```python import os from test.support import load_package_tests def load_tests(*args): return load_package_tests(os.path.dirname(__file__), *args) ``` Also change `import tomli as tomllib` to `import tomllib`. - In `cpython/Lib/tomllib/_parser.py` replace `__fp` with `fp` and `__s` with `s`. Add the `/` to `load` and `loads` function signatures. - Run `make regen-stdlib-module-names` - Create `Doc/library/tomllib.rst` and reference it in `Doc/library/fileformats.rst` files: A Doc/library/tomllib.rst A Lib/test/test_tomllib/__init__.py A Lib/test/test_tomllib/__main__.py A Lib/test/test_tomllib/burntsushi.py A Lib/test/test_tomllib/data/invalid/array-missing-comma.toml A Lib/test/test_tomllib/data/invalid/array-of-tables/overwrite-array-in-parent.toml A Lib/test/test_tomllib/data/invalid/array-of-tables/overwrite-bool-with-aot.toml A Lib/test/test_tomllib/data/invalid/array/file-end-after-val.toml A Lib/test/test_tomllib/data/invalid/array/unclosed-after-item.toml A Lib/test/test_tomllib/data/invalid/array/unclosed-empty.toml A Lib/test/test_tomllib/data/invalid/basic-str-ends-in-escape.toml A Lib/test/test_tomllib/data/invalid/boolean/invalid-false-casing.toml A Lib/test/test_tomllib/data/invalid/boolean/invalid-true-casing.toml A Lib/test/test_tomllib/data/invalid/dates-and-times/invalid-day.toml A Lib/test/test_tomllib/data/invalid/dotted-keys/access-non-table.toml A Lib/test/test_tomllib/data/invalid/dotted-keys/extend-defined-aot.toml A Lib/test/test_tomllib/data/invalid/dotted-keys/extend-defined-table-with-subtable.toml A Lib/test/test_tomllib/data/invalid/dotted-keys/extend-defined-table.toml A Lib/test/test_tomllib/data/invalid/inline-table-missing-comma.toml A Lib/test/test_tomllib/data/invalid/inline-table/define-twice-in-subtable.toml A Lib/test/test_tomllib/data/invalid/inline-table/define-twice.toml A Lib/test/test_tomllib/data/invalid/inline-table/file-end-after-key-val.toml A Lib/test/test_tomllib/data/invalid/inline-table/mutate.toml A Lib/test/test_tomllib/data/invalid/inline-table/override-val-in-table.toml A Lib/test/test_tomllib/data/invalid/inline-table/override-val-with-array.toml A Lib/test/test_tomllib/data/invalid/inline-table/override-val-with-table.toml A Lib/test/test_tomllib/data/invalid/inline-table/overwrite-implicitly.toml A Lib/test/test_tomllib/data/invalid/inline-table/overwrite-value-in-inner-array.toml A Lib/test/test_tomllib/data/invalid/inline-table/overwrite-value-in-inner-table.toml A Lib/test/test_tomllib/data/invalid/inline-table/unclosed-empty.toml A Lib/test/test_tomllib/data/invalid/invalid-comment-char.toml A Lib/test/test_tomllib/data/invalid/invalid-escaped-unicode.toml A Lib/test/test_tomllib/data/invalid/invalid-hex.toml A Lib/test/test_tomllib/data/invalid/keys-and-vals/ends-early-table-def.toml A Lib/test/test_tomllib/data/invalid/keys-and-vals/ends-early.toml A Lib/test/test_tomllib/data/invalid/keys-and-vals/no-value.toml A Lib/test/test_tomllib/data/invalid/keys-and-vals/only-ws-after-dot.toml A Lib/test/test_tomllib/data/invalid/keys-and-vals/overwrite-with-deep-table.toml A Lib/test/test_tomllib/data/invalid/literal-str/unclosed.toml A Lib/test/test_tomllib/data/invalid/missing-closing-double-square-bracket.toml A Lib/test/test_tomllib/data/invalid/missing-closing-square-bracket.toml A Lib/test/test_tomllib/data/invalid/multiline-basic-str/carriage-return.toml A Lib/test/test_tomllib/data/invalid/multiline-basic-str/escape-only.toml A Lib/test/test_tomllib/data/invalid/multiline-basic-str/file-ends-after-opening.toml A Lib/test/test_tomllib/data/invalid/multiline-basic-str/last-line-escape.toml A Lib/test/test_tomllib/data/invalid/multiline-basic-str/unclosed-ends-in-whitespace-escape.toml A Lib/test/test_tomllib/data/invalid/multiline-literal-str/file-ends-after-opening.toml A Lib/test/test_tomllib/data/invalid/multiline-literal-str/unclosed.toml A Lib/test/test_tomllib/data/invalid/non-scalar-escaped.toml A Lib/test/test_tomllib/data/invalid/table/eof-after-opening.toml A Lib/test/test_tomllib/data/invalid/table/redefine-1.toml A Lib/test/test_tomllib/data/invalid/table/redefine-2.toml A Lib/test/test_tomllib/data/invalid/unclosed-multiline-string.toml A Lib/test/test_tomllib/data/invalid/unclosed-string.toml A Lib/test/test_tomllib/data/valid/apostrophes-in-literal-string.json A Lib/test/test_tomllib/data/valid/apostrophes-in-literal-string.toml A Lib/test/test_tomllib/data/valid/array/array-subtables.json A Lib/test/test_tomllib/data/valid/array/array-subtables.toml A Lib/test/test_tomllib/data/valid/array/open-parent-table.json A Lib/test/test_tomllib/data/valid/array/open-parent-table.toml A Lib/test/test_tomllib/data/valid/boolean.json A Lib/test/test_tomllib/data/valid/boolean.toml A Lib/test/test_tomllib/data/valid/dates-and-times/datetimes.json A Lib/test/test_tomllib/data/valid/dates-and-times/datetimes.toml A Lib/test/test_tomllib/data/valid/dates-and-times/localtime.json A Lib/test/test_tomllib/data/valid/dates-and-times/localtime.toml A Lib/test/test_tomllib/data/valid/empty-inline-table.json A Lib/test/test_tomllib/data/valid/empty-inline-table.toml A Lib/test/test_tomllib/data/valid/five-quotes.json A Lib/test/test_tomllib/data/valid/five-quotes.toml A Lib/test/test_tomllib/data/valid/hex-char.json A Lib/test/test_tomllib/data/valid/hex-char.toml A Lib/test/test_tomllib/data/valid/multiline-basic-str/ends-in-whitespace-escape.json A Lib/test/test_tomllib/data/valid/multiline-basic-str/ends-in-whitespace-escape.toml A Lib/test/test_tomllib/data/valid/no-newlines.json A Lib/test/test_tomllib/data/valid/no-newlines.toml A Lib/test/test_tomllib/data/valid/trailing-comma.json A Lib/test/test_tomllib/data/valid/trailing-comma.toml A Lib/test/test_tomllib/test_data.py A Lib/test/test_tomllib/test_error.py A Lib/test/test_tomllib/test_misc.py A Lib/tomllib/__init__.py A Lib/tomllib/_parser.py A Lib/tomllib/_re.py A Lib/tomllib/_types.py A Misc/NEWS.d/next/Library/2022-02-23-01-11-08.bpo-40059.Iwc9UH.rst M .github/CODEOWNERS M Doc/library/fileformats.rst M Doc/whatsnew/3.11.rst M Python/stdlib_module_names.h diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index ff7ffe1414605..33a3ebb3a3870 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -141,6 +141,8 @@ Lib/ast.py @isidentical **/*cgi* @ethanfurman **/*tarfile* @ethanfurman +**/*tomllib* @encukou + # macOS /Mac/ @python/macos-team **/*osx_support* @python/macos-team diff --git a/Doc/library/fileformats.rst b/Doc/library/fileformats.rst index e9c2e1fbbdf3e..bb099fe2d3d6e 100644 --- a/Doc/library/fileformats.rst +++ b/Doc/library/fileformats.rst @@ -12,6 +12,7 @@ that aren't markup languages and are not related to e-mail. csv.rst configparser.rst + tomllib.rst netrc.rst xdrlib.rst plistlib.rst diff --git a/Doc/library/tomllib.rst b/Doc/library/tomllib.rst new file mode 100644 index 0000000000000..918576eb37eae --- /dev/null +++ b/Doc/library/tomllib.rst @@ -0,0 +1,117 @@ +:mod:`tomllib` --- Parse TOML files +=================================== + +.. module:: tomllib + :synopsis: Parse TOML files. + +.. versionadded:: 3.11 + +.. moduleauthor:: Taneli Hukkinen +.. sectionauthor:: Taneli Hukkinen + +**Source code:** :source:`Lib/tomllib` + +-------------- + +This module provides an interface for parsing TOML (Tom's Obvious Minimal +Language, `https://toml.io `_). This module does not +support writing TOML. + +.. seealso:: + + The `Tomli-W package `__ + is a TOML writer that can be used in conjunction with this module, + providing a write API familiar to users of the standard library + :mod:`marshal` and :mod:`pickle` modules. + +.. seealso:: + + The `TOML Kit package `__ + is a style-preserving TOML library with both read and write capability. + It is a recommended replacement for this module for editing already + existing TOML files. + + +This module defines the following functions: + +.. function:: load(fp, /, *, parse_float=float) + + Read a TOML file. The first argument should be a readable and binary file object. + Return a :class:`dict`. Convert TOML types to Python using this + :ref:`conversion table `. + + *parse_float* will be called with the string of every TOML + float to be decoded. By default, this is equivalent to ``float(num_str)``. + This can be used to use another datatype or parser for TOML floats + (e.g. :class:`decimal.Decimal`). The callable must not return a + :class:`dict` or a :class:`list`, else a :exc:`ValueError` is raised. + + A :exc:`TOMLDecodeError` will be raised on an invalid TOML document. + + +.. function:: loads(s, /, *, parse_float=float) + + Load TOML from a :class:`str` object. Return a :class:`dict`. Convert TOML + types to Python using this :ref:`conversion table `. The + *parse_float* argument has the same meaning as in :func:`load`. + + A :exc:`TOMLDecodeError` will be raised on an invalid TOML document. + + +The following exceptions are available: + +.. exception:: TOMLDecodeError + + Subclass of :exc:`ValueError`. + + +Examples +-------- + +Parsing a TOML file:: + + import tomllib + + with open("pyproject.toml", "rb") as f: + data = tomllib.load(f) + +Parsing a TOML string:: + + import tomllib + + toml_str = """ + python-version = "3.11.0" + python-implementation = "CPython" + """ + + data = tomllib.loads(toml_str) + + +Conversion Table +---------------- + +.. _toml-to-py-table: + ++------------------+--------------------------------------------------------------------------------------+ +| TOML | Python | ++==================+======================================================================================+ +| table | dict | ++------------------+--------------------------------------------------------------------------------------+ +| string | str | ++------------------+--------------------------------------------------------------------------------------+ +| integer | int | ++------------------+--------------------------------------------------------------------------------------+ +| float | float (configurable with *parse_float*) | ++------------------+--------------------------------------------------------------------------------------+ +| boolean | bool | ++------------------+--------------------------------------------------------------------------------------+ +| offset date-time | datetime.datetime (``tzinfo`` attribute set to an instance of ``datetime.timezone``) | ++------------------+--------------------------------------------------------------------------------------+ +| local date-time | datetime.datetime (``tzinfo`` attribute set to ``None``) | ++------------------+--------------------------------------------------------------------------------------+ +| local date | datetime.date | ++------------------+--------------------------------------------------------------------------------------+ +| local time | datetime.time | ++------------------+--------------------------------------------------------------------------------------+ +| array | list | ++------------------+--------------------------------------------------------------------------------------+ diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 4a64e044c4a16..9b82de7f4a1a2 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -214,7 +214,8 @@ Other CPython Implementation Changes New Modules =========== -* None yet. +* A new module, :mod:`tomllib`, was added for parsing TOML. + (Contributed by Taneli Hukkinen in :issue:`40059`.) Improved Modules diff --git a/Lib/test/test_tomllib/__init__.py b/Lib/test/test_tomllib/__init__.py new file mode 100644 index 0000000000000..6204c6e47f0f1 --- /dev/null +++ b/Lib/test/test_tomllib/__init__.py @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: MIT +# SPDX-FileCopyrightText: 2021 Taneli Hukkinen +# Licensed to PSF under a Contributor Agreement. + +__all__ = ("tomllib",) + +# By changing this one line, we can run the tests against +# a different module name. +import tomllib + +import os +from test.support import load_package_tests + +def load_tests(*args): + return load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_tomllib/__main__.py b/Lib/test/test_tomllib/__main__.py new file mode 100644 index 0000000000000..dd06365343743 --- /dev/null +++ b/Lib/test/test_tomllib/__main__.py @@ -0,0 +1,6 @@ +import unittest + +from . import load_tests + + +unittest.main() diff --git a/Lib/test/test_tomllib/burntsushi.py b/Lib/test/test_tomllib/burntsushi.py new file mode 100644 index 0000000000000..71228c6536957 --- /dev/null +++ b/Lib/test/test_tomllib/burntsushi.py @@ -0,0 +1,120 @@ +# SPDX-License-Identifier: MIT +# SPDX-FileCopyrightText: 2021 Taneli Hukkinen +# Licensed to PSF under a Contributor Agreement. + +"""Utilities for tests that are in the "burntsushi" format.""" + +import datetime +from typing import Any + +# Aliases for converting TOML compliance format [1] to BurntSushi format [2] +# [1] https://github.com/toml-lang/compliance/blob/db7c3211fda30ff9ddb10292f4aeda7e2e10abc4/docs/json-encoding.md # noqa: E501 +# [2] https://github.com/BurntSushi/toml-test/blob/4634fdf3a6ecd6aaea5f4cdcd98b2733c2694993/README.md # noqa: E501 +_aliases = { + "boolean": "bool", + "offset datetime": "datetime", + "local datetime": "datetime-local", + "local date": "date-local", + "local time": "time-local", +} + + +def convert(obj): # noqa: C901 + if isinstance(obj, str): + return {"type": "string", "value": obj} + elif isinstance(obj, bool): + return {"type": "bool", "value": str(obj).lower()} + elif isinstance(obj, int): + return {"type": "integer", "value": str(obj)} + elif isinstance(obj, float): + return {"type": "float", "value": _normalize_float_str(str(obj))} + elif isinstance(obj, datetime.datetime): + val = _normalize_datetime_str(obj.isoformat()) + if obj.tzinfo: + return {"type": "datetime", "value": val} + return {"type": "datetime-local", "value": val} + elif isinstance(obj, datetime.time): + return { + "type": "time-local", + "value": _normalize_localtime_str(str(obj)), + } + elif isinstance(obj, datetime.date): + return { + "type": "date-local", + "value": str(obj), + } + elif isinstance(obj, list): + return [convert(i) for i in obj] + elif isinstance(obj, dict): + return {k: convert(v) for k, v in obj.items()} + raise Exception("unsupported type") + + +def normalize(obj: Any) -> Any: + """Normalize test objects. + + This normalizes primitive values (e.g. floats), and also converts from + TOML compliance format [1] to BurntSushi format [2]. + + [1] https://github.com/toml-lang/compliance/blob/db7c3211fda30ff9ddb10292f4aeda7e2e10abc4/docs/json-encoding.md # noqa: E501 + [2] https://github.com/BurntSushi/toml-test/blob/4634fdf3a6ecd6aaea5f4cdcd98b2733c2694993/README.md # noqa: E501 + """ + if isinstance(obj, list): + return [normalize(item) for item in obj] + if isinstance(obj, dict): + if "type" in obj and "value" in obj: + type_ = obj["type"] + norm_type = _aliases.get(type_, type_) + value = obj["value"] + if norm_type == "float": + norm_value = _normalize_float_str(value) + elif norm_type in {"datetime", "datetime-local"}: + norm_value = _normalize_datetime_str(value) + elif norm_type == "time-local": + norm_value = _normalize_localtime_str(value) + else: + norm_value = value + + if norm_type == "array": + return [normalize(item) for item in value] + return {"type": norm_type, "value": norm_value} + return {k: normalize(v) for k, v in obj.items()} + raise AssertionError("Burntsushi fixtures should be dicts/lists only") + + +def _normalize_datetime_str(dt_str: str) -> str: + if dt_str[-1].lower() == "z": + dt_str = dt_str[:-1] + "+00:00" + + date = dt_str[:10] + rest = dt_str[11:] + + if "+" in rest: + sign = "+" + elif "-" in rest: + sign = "-" + else: + sign = "" + + if sign: + time, _, offset = rest.partition(sign) + else: + time = rest + offset = "" + + time = time.rstrip("0") if "." in time else time + return date + "T" + time + sign + offset + + +def _normalize_localtime_str(lt_str: str) -> str: + return lt_str.rstrip("0") if "." in lt_str else lt_str + + +def _normalize_float_str(float_str: str) -> str: + as_float = float(float_str) + + # Normalize "-0.0" and "+0.0" + if as_float == 0: + return "0" + + return str(as_float) diff --git a/Lib/test/test_tomllib/data/invalid/array-missing-comma.toml b/Lib/test/test_tomllib/data/invalid/array-missing-comma.toml new file mode 100644 index 0000000000000..9431d90799570 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/array-missing-comma.toml @@ -0,0 +1 @@ +arrr = [true false] diff --git a/Lib/test/test_tomllib/data/invalid/array-of-tables/overwrite-array-in-parent.toml b/Lib/test/test_tomllib/data/invalid/array-of-tables/overwrite-array-in-parent.toml new file mode 100644 index 0000000000000..f867c28deeba4 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/array-of-tables/overwrite-array-in-parent.toml @@ -0,0 +1,4 @@ +[[parent-table.arr]] +[parent-table] +not-arr = 1 +arr = 2 diff --git a/Lib/test/test_tomllib/data/invalid/array-of-tables/overwrite-bool-with-aot.toml b/Lib/test/test_tomllib/data/invalid/array-of-tables/overwrite-bool-with-aot.toml new file mode 100644 index 0000000000000..b1892d6a44906 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/array-of-tables/overwrite-bool-with-aot.toml @@ -0,0 +1,2 @@ +a=true +[[a]] \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/array/file-end-after-val.toml b/Lib/test/test_tomllib/data/invalid/array/file-end-after-val.toml new file mode 100644 index 0000000000000..00196bb03ea81 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/array/file-end-after-val.toml @@ -0,0 +1 @@ +a=[1 \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/array/unclosed-after-item.toml b/Lib/test/test_tomllib/data/invalid/array/unclosed-after-item.toml new file mode 100644 index 0000000000000..9edec37078fb0 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/array/unclosed-after-item.toml @@ -0,0 +1 @@ +v=[1, \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/array/unclosed-empty.toml b/Lib/test/test_tomllib/data/invalid/array/unclosed-empty.toml new file mode 100644 index 0000000000000..1fd099d3683e2 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/array/unclosed-empty.toml @@ -0,0 +1 @@ +v=[ \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/basic-str-ends-in-escape.toml b/Lib/test/test_tomllib/data/invalid/basic-str-ends-in-escape.toml new file mode 100644 index 0000000000000..713ea544f82c2 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/basic-str-ends-in-escape.toml @@ -0,0 +1 @@ +"backslash is the last char\ \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/boolean/invalid-false-casing.toml b/Lib/test/test_tomllib/data/invalid/boolean/invalid-false-casing.toml new file mode 100644 index 0000000000000..336d2d808e781 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/boolean/invalid-false-casing.toml @@ -0,0 +1 @@ +val=falsE \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/boolean/invalid-true-casing.toml b/Lib/test/test_tomllib/data/invalid/boolean/invalid-true-casing.toml new file mode 100644 index 0000000000000..0370d6cdb671a --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/boolean/invalid-true-casing.toml @@ -0,0 +1 @@ +val=trUe \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/dates-and-times/invalid-day.toml b/Lib/test/test_tomllib/data/invalid/dates-and-times/invalid-day.toml new file mode 100644 index 0000000000000..c69f0914451d9 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/dates-and-times/invalid-day.toml @@ -0,0 +1 @@ +"only 28 or 29 days in february" = 1988-02-30 diff --git a/Lib/test/test_tomllib/data/invalid/dotted-keys/access-non-table.toml b/Lib/test/test_tomllib/data/invalid/dotted-keys/access-non-table.toml new file mode 100644 index 0000000000000..ada02005a3eb6 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/dotted-keys/access-non-table.toml @@ -0,0 +1,2 @@ +a = false +a.b = true \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/dotted-keys/extend-defined-aot.toml b/Lib/test/test_tomllib/data/invalid/dotted-keys/extend-defined-aot.toml new file mode 100644 index 0000000000000..1c3c34b8571fa --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/dotted-keys/extend-defined-aot.toml @@ -0,0 +1,3 @@ +[[tab.arr]] +[tab] +arr.val1=1 diff --git a/Lib/test/test_tomllib/data/invalid/dotted-keys/extend-defined-table-with-subtable.toml b/Lib/test/test_tomllib/data/invalid/dotted-keys/extend-defined-table-with-subtable.toml new file mode 100644 index 0000000000000..70e2ac5be8986 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/dotted-keys/extend-defined-table-with-subtable.toml @@ -0,0 +1,4 @@ +[a.b.c.d] + z = 9 +[a] + b.c.d.k.t = 8 diff --git a/Lib/test/test_tomllib/data/invalid/dotted-keys/extend-defined-table.toml b/Lib/test/test_tomllib/data/invalid/dotted-keys/extend-defined-table.toml new file mode 100644 index 0000000000000..c88c179d3c177 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/dotted-keys/extend-defined-table.toml @@ -0,0 +1,4 @@ +[a.b.c] + z = 9 +[a] + b.c.t = 9 diff --git a/Lib/test/test_tomllib/data/invalid/inline-table-missing-comma.toml b/Lib/test/test_tomllib/data/invalid/inline-table-missing-comma.toml new file mode 100644 index 0000000000000..d98b41dd03700 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/inline-table-missing-comma.toml @@ -0,0 +1 @@ +arrr = { comma-missing = true valid-toml = false } diff --git a/Lib/test/test_tomllib/data/invalid/inline-table/define-twice-in-subtable.toml b/Lib/test/test_tomllib/data/invalid/inline-table/define-twice-in-subtable.toml new file mode 100644 index 0000000000000..706834135d1dc --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/inline-table/define-twice-in-subtable.toml @@ -0,0 +1 @@ +table1 = { table2.dupe = 1, table2.dupe = 2 } \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/inline-table/define-twice.toml b/Lib/test/test_tomllib/data/invalid/inline-table/define-twice.toml new file mode 100644 index 0000000000000..8202b98ff2dbf --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/inline-table/define-twice.toml @@ -0,0 +1 @@ +table = { dupe = 1, dupe = 2 } \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/inline-table/file-end-after-key-val.toml b/Lib/test/test_tomllib/data/invalid/inline-table/file-end-after-key-val.toml new file mode 100644 index 0000000000000..52d4e779704bd --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/inline-table/file-end-after-key-val.toml @@ -0,0 +1 @@ +a={b=1 \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/inline-table/mutate.toml b/Lib/test/test_tomllib/data/invalid/inline-table/mutate.toml new file mode 100644 index 0000000000000..4e5e9ff15695f --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/inline-table/mutate.toml @@ -0,0 +1,2 @@ +a = { b = 1 } +a.b = 2 \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/inline-table/override-val-in-table.toml b/Lib/test/test_tomllib/data/invalid/inline-table/override-val-in-table.toml new file mode 100644 index 0000000000000..6e87cfa456d5f --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/inline-table/override-val-in-table.toml @@ -0,0 +1,5 @@ +[tab.nested] +inline-t = { nest = {} } + +[tab] +nested.inline-t.nest = 2 diff --git a/Lib/test/test_tomllib/data/invalid/inline-table/override-val-with-array.toml b/Lib/test/test_tomllib/data/invalid/inline-table/override-val-with-array.toml new file mode 100644 index 0000000000000..79b4f325874ed --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/inline-table/override-val-with-array.toml @@ -0,0 +1,3 @@ +inline-t = { nest = {} } + +[[inline-t.nest]] diff --git a/Lib/test/test_tomllib/data/invalid/inline-table/override-val-with-table.toml b/Lib/test/test_tomllib/data/invalid/inline-table/override-val-with-table.toml new file mode 100644 index 0000000000000..d0cd6b641ac00 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/inline-table/override-val-with-table.toml @@ -0,0 +1,3 @@ +inline-t = { nest = {} } + +[inline-t.nest] diff --git a/Lib/test/test_tomllib/data/invalid/inline-table/overwrite-implicitly.toml b/Lib/test/test_tomllib/data/invalid/inline-table/overwrite-implicitly.toml new file mode 100644 index 0000000000000..462c28f168479 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/inline-table/overwrite-implicitly.toml @@ -0,0 +1 @@ +a = { b = 1, b.c = 2 } diff --git a/Lib/test/test_tomllib/data/invalid/inline-table/overwrite-value-in-inner-array.toml b/Lib/test/test_tomllib/data/invalid/inline-table/overwrite-value-in-inner-array.toml new file mode 100644 index 0000000000000..34ddb85eeec8d --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/inline-table/overwrite-value-in-inner-array.toml @@ -0,0 +1 @@ +tab = { inner.table = [{}], inner.table.val = "bad" } \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/inline-table/overwrite-value-in-inner-table.toml b/Lib/test/test_tomllib/data/invalid/inline-table/overwrite-value-in-inner-table.toml new file mode 100644 index 0000000000000..750853f0d9645 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/inline-table/overwrite-value-in-inner-table.toml @@ -0,0 +1 @@ +tab = { inner = { dog = "best" }, inner.cat = "worst" } \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/inline-table/unclosed-empty.toml b/Lib/test/test_tomllib/data/invalid/inline-table/unclosed-empty.toml new file mode 100644 index 0000000000000..032edb7266c43 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/inline-table/unclosed-empty.toml @@ -0,0 +1 @@ +a={ \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/invalid-comment-char.toml b/Lib/test/test_tomllib/data/invalid/invalid-comment-char.toml new file mode 100644 index 0000000000000..dc5ae336c6a71 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/invalid-comment-char.toml @@ -0,0 +1 @@ +# form feed ( ) not allowed in comments \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/invalid-escaped-unicode.toml b/Lib/test/test_tomllib/data/invalid/invalid-escaped-unicode.toml new file mode 100644 index 0000000000000..8feba3a30a45d --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/invalid-escaped-unicode.toml @@ -0,0 +1 @@ +escaped-unicode = "\uabag" diff --git a/Lib/test/test_tomllib/data/invalid/invalid-hex.toml b/Lib/test/test_tomllib/data/invalid/invalid-hex.toml new file mode 100644 index 0000000000000..5c55fe80c4569 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/invalid-hex.toml @@ -0,0 +1 @@ +hex = 0xgabba00f1 diff --git a/Lib/test/test_tomllib/data/invalid/keys-and-vals/ends-early-table-def.toml b/Lib/test/test_tomllib/data/invalid/keys-and-vals/ends-early-table-def.toml new file mode 100644 index 0000000000000..75d43a37eda3a --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/keys-and-vals/ends-early-table-def.toml @@ -0,0 +1 @@ +[fwfw.wafw \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/keys-and-vals/ends-early.toml b/Lib/test/test_tomllib/data/invalid/keys-and-vals/ends-early.toml new file mode 100644 index 0000000000000..e70e265ae20c0 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/keys-and-vals/ends-early.toml @@ -0,0 +1 @@ +fs.fw \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/keys-and-vals/no-value.toml b/Lib/test/test_tomllib/data/invalid/keys-and-vals/no-value.toml new file mode 100644 index 0000000000000..4f9ab16c61392 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/keys-and-vals/no-value.toml @@ -0,0 +1 @@ +why-no-value= \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/keys-and-vals/only-ws-after-dot.toml b/Lib/test/test_tomllib/data/invalid/keys-and-vals/only-ws-after-dot.toml new file mode 100644 index 0000000000000..abe52587c9eab --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/keys-and-vals/only-ws-after-dot.toml @@ -0,0 +1 @@ +fs. \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/keys-and-vals/overwrite-with-deep-table.toml b/Lib/test/test_tomllib/data/invalid/keys-and-vals/overwrite-with-deep-table.toml new file mode 100644 index 0000000000000..103d928bcf7c2 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/keys-and-vals/overwrite-with-deep-table.toml @@ -0,0 +1,2 @@ +a=1 +[a.b.c.d] diff --git a/Lib/test/test_tomllib/data/invalid/literal-str/unclosed.toml b/Lib/test/test_tomllib/data/invalid/literal-str/unclosed.toml new file mode 100644 index 0000000000000..b1612aa1f6d7e --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/literal-str/unclosed.toml @@ -0,0 +1 @@ +unclosed='dwdd \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/missing-closing-double-square-bracket.toml b/Lib/test/test_tomllib/data/invalid/missing-closing-double-square-bracket.toml new file mode 100644 index 0000000000000..ae1d0d9cf9a67 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/missing-closing-double-square-bracket.toml @@ -0,0 +1,2 @@ +[[closing-bracket.missing] +blaa=2 diff --git a/Lib/test/test_tomllib/data/invalid/missing-closing-square-bracket.toml b/Lib/test/test_tomllib/data/invalid/missing-closing-square-bracket.toml new file mode 100644 index 0000000000000..354d0167fcd7a --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/missing-closing-square-bracket.toml @@ -0,0 +1,2 @@ +[closing-bracket.missing? +blaa=2 diff --git a/Lib/test/test_tomllib/data/invalid/multiline-basic-str/carriage-return.toml b/Lib/test/test_tomllib/data/invalid/multiline-basic-str/carriage-return.toml new file mode 100644 index 0000000000000..4c455cfe0e015 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/multiline-basic-str/carriage-return.toml @@ -0,0 +1,2 @@ +s="""cr is not an allowed line ending but we just tried to use it +""" \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/multiline-basic-str/escape-only.toml b/Lib/test/test_tomllib/data/invalid/multiline-basic-str/escape-only.toml new file mode 100644 index 0000000000000..f3bd9fca2317e --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/multiline-basic-str/escape-only.toml @@ -0,0 +1 @@ +bee = """\""" diff --git a/Lib/test/test_tomllib/data/invalid/multiline-basic-str/file-ends-after-opening.toml b/Lib/test/test_tomllib/data/invalid/multiline-basic-str/file-ends-after-opening.toml new file mode 100644 index 0000000000000..1c2a56444406d --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/multiline-basic-str/file-ends-after-opening.toml @@ -0,0 +1 @@ +a=""" \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/multiline-basic-str/last-line-escape.toml b/Lib/test/test_tomllib/data/invalid/multiline-basic-str/last-line-escape.toml new file mode 100644 index 0000000000000..92b22b065663e --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/multiline-basic-str/last-line-escape.toml @@ -0,0 +1,4 @@ +bee = """ +hee \ + +gee \ """ diff --git a/Lib/test/test_tomllib/data/invalid/multiline-basic-str/unclosed-ends-in-whitespace-escape.toml b/Lib/test/test_tomllib/data/invalid/multiline-basic-str/unclosed-ends-in-whitespace-escape.toml new file mode 100644 index 0000000000000..3ba7febbd0c11 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/multiline-basic-str/unclosed-ends-in-whitespace-escape.toml @@ -0,0 +1,3 @@ +bee = """ +hee +gee\ \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/multiline-literal-str/file-ends-after-opening.toml b/Lib/test/test_tomllib/data/invalid/multiline-literal-str/file-ends-after-opening.toml new file mode 100644 index 0000000000000..9a3924a103f92 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/multiline-literal-str/file-ends-after-opening.toml @@ -0,0 +1 @@ +a=''' \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/multiline-literal-str/unclosed.toml b/Lib/test/test_tomllib/data/invalid/multiline-literal-str/unclosed.toml new file mode 100644 index 0000000000000..decd378991359 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/multiline-literal-str/unclosed.toml @@ -0,0 +1,3 @@ +bee = ''' +hee +gee '' \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/non-scalar-escaped.toml b/Lib/test/test_tomllib/data/invalid/non-scalar-escaped.toml new file mode 100644 index 0000000000000..c787f9ad35428 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/non-scalar-escaped.toml @@ -0,0 +1 @@ +a="\ud800" \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/table/eof-after-opening.toml b/Lib/test/test_tomllib/data/invalid/table/eof-after-opening.toml new file mode 100644 index 0000000000000..8e2f0bef135ba --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/table/eof-after-opening.toml @@ -0,0 +1 @@ +[ \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/invalid/table/redefine-1.toml b/Lib/test/test_tomllib/data/invalid/table/redefine-1.toml new file mode 100644 index 0000000000000..d2c66eb38c71d --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/table/redefine-1.toml @@ -0,0 +1,3 @@ +[t1] +t2.t3.v = 0 +[t1.t2] diff --git a/Lib/test/test_tomllib/data/invalid/table/redefine-2.toml b/Lib/test/test_tomllib/data/invalid/table/redefine-2.toml new file mode 100644 index 0000000000000..918017f892a40 --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/table/redefine-2.toml @@ -0,0 +1,3 @@ +[t1] +t2.t3.v = 0 +[t1.t2.t3] diff --git a/Lib/test/test_tomllib/data/invalid/unclosed-multiline-string.toml b/Lib/test/test_tomllib/data/invalid/unclosed-multiline-string.toml new file mode 100644 index 0000000000000..401adec2a332b --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/unclosed-multiline-string.toml @@ -0,0 +1,4 @@ +not-closed= """ +diibaa +blibae ete +eteta diff --git a/Lib/test/test_tomllib/data/invalid/unclosed-string.toml b/Lib/test/test_tomllib/data/invalid/unclosed-string.toml new file mode 100644 index 0000000000000..89f75acf7718d --- /dev/null +++ b/Lib/test/test_tomllib/data/invalid/unclosed-string.toml @@ -0,0 +1 @@ +"a-string".must-be = "closed \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/valid/apostrophes-in-literal-string.json b/Lib/test/test_tomllib/data/valid/apostrophes-in-literal-string.json new file mode 100644 index 0000000000000..fddafe7769c05 --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/apostrophes-in-literal-string.json @@ -0,0 +1 @@ +{"this-str-has-apostrophes": {"type": "string", "value": "' there's one already\n'' two more\n''"}} diff --git a/Lib/test/test_tomllib/data/valid/apostrophes-in-literal-string.toml b/Lib/test/test_tomllib/data/valid/apostrophes-in-literal-string.toml new file mode 100644 index 0000000000000..4288d080ca37b --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/apostrophes-in-literal-string.toml @@ -0,0 +1,3 @@ +this-str-has-apostrophes='''' there's one already +'' two more +''''' diff --git a/Lib/test/test_tomllib/data/valid/array/array-subtables.json b/Lib/test/test_tomllib/data/valid/array/array-subtables.json new file mode 100644 index 0000000000000..69ad37e98343a --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/array/array-subtables.json @@ -0,0 +1,11 @@ +{"arr": + {"type":"array","value": + [ + {"subtab": + {"val": {"type":"integer","value":"1"} + } + }, + {"subtab": {"val": {"type":"integer","value":"2"}}} + ] + } +} diff --git a/Lib/test/test_tomllib/data/valid/array/array-subtables.toml b/Lib/test/test_tomllib/data/valid/array/array-subtables.toml new file mode 100644 index 0000000000000..7075307841176 --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/array/array-subtables.toml @@ -0,0 +1,7 @@ +[[arr]] +[arr.subtab] +val=1 + +[[arr]] +[arr.subtab] +val=2 diff --git a/Lib/test/test_tomllib/data/valid/array/open-parent-table.json b/Lib/test/test_tomllib/data/valid/array/open-parent-table.json new file mode 100644 index 0000000000000..7dba1b69d6a8a --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/array/open-parent-table.json @@ -0,0 +1,6 @@ +{ + "parent-table": { + "arr": {"type":"array","value":[{},{}]}, + "not-arr": {"type":"integer","value":"1"} + } +} diff --git a/Lib/test/test_tomllib/data/valid/array/open-parent-table.toml b/Lib/test/test_tomllib/data/valid/array/open-parent-table.toml new file mode 100644 index 0000000000000..8eaad12fe3ada --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/array/open-parent-table.toml @@ -0,0 +1,4 @@ +[[parent-table.arr]] +[[parent-table.arr]] +[parent-table] +not-arr = 1 diff --git a/Lib/test/test_tomllib/data/valid/boolean.json b/Lib/test/test_tomllib/data/valid/boolean.json new file mode 100644 index 0000000000000..2540d252776b3 --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/boolean.json @@ -0,0 +1,4 @@ +{ + "a": {"type":"bool","value":"true"}, + "b": {"type":"bool","value":"false"} +} diff --git a/Lib/test/test_tomllib/data/valid/boolean.toml b/Lib/test/test_tomllib/data/valid/boolean.toml new file mode 100644 index 0000000000000..e5aaba35ea8ea --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/boolean.toml @@ -0,0 +1,2 @@ +'a'=true +"b"=false \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/valid/dates-and-times/datetimes.json b/Lib/test/test_tomllib/data/valid/dates-and-times/datetimes.json new file mode 100644 index 0000000000000..99aca873480ec --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/dates-and-times/datetimes.json @@ -0,0 +1,4 @@ +{ + "local-dt": {"type":"datetime-local","value":"1988-10-27t01:01:01"}, + "zulu-dt": {"type":"datetime","value":"1988-10-27t01:01:01z"} +} diff --git a/Lib/test/test_tomllib/data/valid/dates-and-times/datetimes.toml b/Lib/test/test_tomllib/data/valid/dates-and-times/datetimes.toml new file mode 100644 index 0000000000000..cf84159de46fd --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/dates-and-times/datetimes.toml @@ -0,0 +1,2 @@ +local-dt=1988-10-27t01:01:01 +zulu-dt=1988-10-27t01:01:01z diff --git a/Lib/test/test_tomllib/data/valid/dates-and-times/localtime.json b/Lib/test/test_tomllib/data/valid/dates-and-times/localtime.json new file mode 100644 index 0000000000000..4d96abcbc799e --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/dates-and-times/localtime.json @@ -0,0 +1,2 @@ +{"t": + {"type":"time-local","value":"00:00:00.999999"}} diff --git a/Lib/test/test_tomllib/data/valid/dates-and-times/localtime.toml b/Lib/test/test_tomllib/data/valid/dates-and-times/localtime.toml new file mode 100644 index 0000000000000..87547c1cf3bd8 --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/dates-and-times/localtime.toml @@ -0,0 +1 @@ +t=00:00:00.99999999999999 \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/valid/empty-inline-table.json b/Lib/test/test_tomllib/data/valid/empty-inline-table.json new file mode 100644 index 0000000000000..2655cfd3ab0bc --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/empty-inline-table.json @@ -0,0 +1 @@ +{"empty": {}} \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/valid/empty-inline-table.toml b/Lib/test/test_tomllib/data/valid/empty-inline-table.toml new file mode 100644 index 0000000000000..d2d15ab9e08ef --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/empty-inline-table.toml @@ -0,0 +1 @@ +empty ={ }#nothing here diff --git a/Lib/test/test_tomllib/data/valid/five-quotes.json b/Lib/test/test_tomllib/data/valid/five-quotes.json new file mode 100644 index 0000000000000..5cc527408ecf5 --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/five-quotes.json @@ -0,0 +1,4 @@ +{ + "five-quotes": {"type":"string","value":"Closing with five quotes\n\"\""}, + "four-quotes": {"type":"string","value":"Closing with four quotes\n\""} +} diff --git a/Lib/test/test_tomllib/data/valid/five-quotes.toml b/Lib/test/test_tomllib/data/valid/five-quotes.toml new file mode 100644 index 0000000000000..ccc98c07416b7 --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/five-quotes.toml @@ -0,0 +1,6 @@ +five-quotes = """ +Closing with five quotes +""""" +four-quotes = """ +Closing with four quotes +"""" diff --git a/Lib/test/test_tomllib/data/valid/hex-char.json b/Lib/test/test_tomllib/data/valid/hex-char.json new file mode 100644 index 0000000000000..e632e202fad48 --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/hex-char.json @@ -0,0 +1,5 @@ +{ + "a": {"type":"string","value":"a"}, + "b": {"type":"string","value":"b"}, + "c": {"type":"string","value":"c"} +} diff --git a/Lib/test/test_tomllib/data/valid/hex-char.toml b/Lib/test/test_tomllib/data/valid/hex-char.toml new file mode 100644 index 0000000000000..1d9cdf6a437fa --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/hex-char.toml @@ -0,0 +1,3 @@ +a="\u0061" +b="\u0062" +c="\U00000063" \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/valid/multiline-basic-str/ends-in-whitespace-escape.json b/Lib/test/test_tomllib/data/valid/multiline-basic-str/ends-in-whitespace-escape.json new file mode 100644 index 0000000000000..fc54a7c2a3cc0 --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/multiline-basic-str/ends-in-whitespace-escape.json @@ -0,0 +1 @@ +{"beee": {"type": "string", "value": "heeee\ngeeee"}} diff --git a/Lib/test/test_tomllib/data/valid/multiline-basic-str/ends-in-whitespace-escape.toml b/Lib/test/test_tomllib/data/valid/multiline-basic-str/ends-in-whitespace-escape.toml new file mode 100644 index 0000000000000..4dffe55fcb5cf --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/multiline-basic-str/ends-in-whitespace-escape.toml @@ -0,0 +1,6 @@ +beee = """ +heeee +geeee\ + + + """ diff --git a/Lib/test/test_tomllib/data/valid/no-newlines.json b/Lib/test/test_tomllib/data/valid/no-newlines.json new file mode 100644 index 0000000000000..0967ef424bce6 --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/no-newlines.json @@ -0,0 +1 @@ +{} diff --git a/Lib/test/test_tomllib/data/valid/no-newlines.toml b/Lib/test/test_tomllib/data/valid/no-newlines.toml new file mode 100644 index 0000000000000..4b87f4c77c97c --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/no-newlines.toml @@ -0,0 +1 @@ +#no newlines at all here \ No newline at end of file diff --git a/Lib/test/test_tomllib/data/valid/trailing-comma.json b/Lib/test/test_tomllib/data/valid/trailing-comma.json new file mode 100644 index 0000000000000..dc6f1665d1fcc --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/trailing-comma.json @@ -0,0 +1,7 @@ +{"arr": + {"type":"array","value": + [ + {"type":"integer","value":"1"} + ] + } +} diff --git a/Lib/test/test_tomllib/data/valid/trailing-comma.toml b/Lib/test/test_tomllib/data/valid/trailing-comma.toml new file mode 100644 index 0000000000000..c5d5b9b412241 --- /dev/null +++ b/Lib/test/test_tomllib/data/valid/trailing-comma.toml @@ -0,0 +1 @@ +arr=[1,] \ No newline at end of file diff --git a/Lib/test/test_tomllib/test_data.py b/Lib/test/test_tomllib/test_data.py new file mode 100644 index 0000000000000..3483d93022b01 --- /dev/null +++ b/Lib/test/test_tomllib/test_data.py @@ -0,0 +1,64 @@ +# SPDX-License-Identifier: MIT +# SPDX-FileCopyrightText: 2021 Taneli Hukkinen +# Licensed to PSF under a Contributor Agreement. + +import json +from pathlib import Path +import unittest + +from . import burntsushi, tomllib + + +class MissingFile: + def __init__(self, path: Path): + self.path = path + + +DATA_DIR = Path(__file__).parent / "data" + +VALID_FILES = tuple((DATA_DIR / "valid").glob("**/*.toml")) +assert VALID_FILES, "Valid TOML test files not found" + +_expected_files = [] +for p in VALID_FILES: + json_path = p.with_suffix(".json") + try: + text = json.loads(json_path.read_bytes().decode()) + except FileNotFoundError: + text = MissingFile(json_path) + _expected_files.append(text) +VALID_FILES_EXPECTED = tuple(_expected_files) + +INVALID_FILES = tuple((DATA_DIR / "invalid").glob("**/*.toml")) +assert INVALID_FILES, "Invalid TOML test files not found" + + +class TestData(unittest.TestCase): + def test_invalid(self): + for invalid in INVALID_FILES: + with self.subTest(msg=invalid.stem): + toml_bytes = invalid.read_bytes() + try: + toml_str = toml_bytes.decode() + except UnicodeDecodeError: + # Some BurntSushi tests are not valid UTF-8. Skip those. + continue + with self.assertRaises(tomllib.TOMLDecodeError): + tomllib.loads(toml_str) + + def test_valid(self): + for valid, expected in zip(VALID_FILES, VALID_FILES_EXPECTED): + with self.subTest(msg=valid.stem): + if isinstance(expected, MissingFile): + # For a poor man's xfail, assert that this is one of the + # test cases where expected data is known to be missing. + assert valid.stem in { + "qa-array-inline-nested-1000", + "qa-table-inline-nested-1000", + } + continue + toml_str = valid.read_bytes().decode() + actual = tomllib.loads(toml_str) + actual = burntsushi.convert(actual) + expected = burntsushi.normalize(expected) + self.assertEqual(actual, expected) diff --git a/Lib/test/test_tomllib/test_error.py b/Lib/test/test_tomllib/test_error.py new file mode 100644 index 0000000000000..72446267f0475 --- /dev/null +++ b/Lib/test/test_tomllib/test_error.py @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: MIT +# SPDX-FileCopyrightText: 2021 Taneli Hukkinen +# Licensed to PSF under a Contributor Agreement. + +import unittest + +from . import tomllib + + +class TestError(unittest.TestCase): + def test_line_and_col(self): + with self.assertRaises(tomllib.TOMLDecodeError) as exc_info: + tomllib.loads("val=.") + self.assertEqual(str(exc_info.exception), "Invalid value (at line 1, column 5)") + + with self.assertRaises(tomllib.TOMLDecodeError) as exc_info: + tomllib.loads(".") + self.assertEqual( + str(exc_info.exception), "Invalid statement (at line 1, column 1)" + ) + + with self.assertRaises(tomllib.TOMLDecodeError) as exc_info: + tomllib.loads("\n\nval=.") + self.assertEqual(str(exc_info.exception), "Invalid value (at line 3, column 5)") + + with self.assertRaises(tomllib.TOMLDecodeError) as exc_info: + tomllib.loads("\n\n.") + self.assertEqual( + str(exc_info.exception), "Invalid statement (at line 3, column 1)" + ) + + def test_missing_value(self): + with self.assertRaises(tomllib.TOMLDecodeError) as exc_info: + tomllib.loads("\n\nfwfw=") + self.assertEqual(str(exc_info.exception), "Invalid value (at end of document)") + + def test_invalid_char_quotes(self): + with self.assertRaises(tomllib.TOMLDecodeError) as exc_info: + tomllib.loads("v = '\n'") + self.assertTrue(" '\\n' " in str(exc_info.exception)) + + def test_module_name(self): + self.assertEqual(tomllib.TOMLDecodeError().__module__, tomllib.__name__) + + def test_invalid_parse_float(self): + def dict_returner(s: str) -> dict: + return {} + + def list_returner(s: str) -> list: + return [] + + for invalid_parse_float in (dict_returner, list_returner): + with self.assertRaises(ValueError) as exc_info: + tomllib.loads("f=0.1", parse_float=invalid_parse_float) + self.assertEqual( + str(exc_info.exception), "parse_float must not return dicts or lists" + ) diff --git a/Lib/test/test_tomllib/test_misc.py b/Lib/test/test_tomllib/test_misc.py new file mode 100644 index 0000000000000..76fa5905fa49e --- /dev/null +++ b/Lib/test/test_tomllib/test_misc.py @@ -0,0 +1,101 @@ +# SPDX-License-Identifier: MIT +# SPDX-FileCopyrightText: 2021 Taneli Hukkinen +# Licensed to PSF under a Contributor Agreement. + +import copy +import datetime +from decimal import Decimal as D +from pathlib import Path +import tempfile +import unittest + +from . import tomllib + + +class TestMiscellaneous(unittest.TestCase): + def test_load(self): + content = "one=1 \n two='two' \n arr=[]" + expected = {"one": 1, "two": "two", "arr": []} + with tempfile.TemporaryDirectory() as tmp_dir_path: + file_path = Path(tmp_dir_path) / "test.toml" + file_path.write_text(content) + + with open(file_path, "rb") as bin_f: + actual = tomllib.load(bin_f) + self.assertEqual(actual, expected) + + def test_incorrect_load(self): + content = "one=1" + with tempfile.TemporaryDirectory() as tmp_dir_path: + file_path = Path(tmp_dir_path) / "test.toml" + file_path.write_text(content) + + with open(file_path, "r") as txt_f: + with self.assertRaises(TypeError): + tomllib.load(txt_f) # type: ignore[arg-type] + + def test_parse_float(self): + doc = """ + val=0.1 + biggest1=inf + biggest2=+inf + smallest=-inf + notnum1=nan + notnum2=-nan + notnum3=+nan + """ + obj = tomllib.loads(doc, parse_float=D) + expected = { + "val": D("0.1"), + "biggest1": D("inf"), + "biggest2": D("inf"), + "smallest": D("-inf"), + "notnum1": D("nan"), + "notnum2": D("-nan"), + "notnum3": D("nan"), + } + for k, expected_val in expected.items(): + actual_val = obj[k] + self.assertIsInstance(actual_val, D) + if actual_val.is_nan(): + self.assertTrue(expected_val.is_nan()) + else: + self.assertEqual(actual_val, expected_val) + + def test_deepcopy(self): + doc = """ + [bliibaa.diibaa] + offsettime=[1979-05-27T00:32:00.999999-07:00] + """ + obj = tomllib.loads(doc) + obj_copy = copy.deepcopy(obj) + self.assertEqual(obj_copy, obj) + expected_obj = { + "bliibaa": { + "diibaa": { + "offsettime": [ + datetime.datetime( + 1979, + 5, + 27, + 0, + 32, + 0, + 999999, + tzinfo=datetime.timezone(datetime.timedelta(hours=-7)), + ) + ] + } + } + } + self.assertEqual(obj_copy, expected_obj) + + def test_inline_array_recursion_limit(self): + nest_count = 470 + recursive_array_toml = "arr = " + nest_count * "[" + nest_count * "]" + tomllib.loads(recursive_array_toml) + + def test_inline_table_recursion_limit(self): + nest_count = 310 + recursive_table_toml = nest_count * "key = {" + nest_count * "}" + tomllib.loads(recursive_table_toml) diff --git a/Lib/tomllib/__init__.py b/Lib/tomllib/__init__.py new file mode 100644 index 0000000000000..ef91cb9d25dd7 --- /dev/null +++ b/Lib/tomllib/__init__.py @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: MIT +# SPDX-FileCopyrightText: 2021 Taneli Hukkinen +# Licensed to PSF under a Contributor Agreement. + +__all__ = ("loads", "load", "TOMLDecodeError") + +from ._parser import TOMLDecodeError, load, loads + +# Pretend this exception was created here. +TOMLDecodeError.__module__ = __name__ diff --git a/Lib/tomllib/_parser.py b/Lib/tomllib/_parser.py new file mode 100644 index 0000000000000..45ca7a89630f0 --- /dev/null +++ b/Lib/tomllib/_parser.py @@ -0,0 +1,691 @@ +# SPDX-License-Identifier: MIT +# SPDX-FileCopyrightText: 2021 Taneli Hukkinen +# Licensed to PSF under a Contributor Agreement. + +from __future__ import annotations + +from collections.abc import Iterable +import string +from types import MappingProxyType +from typing import Any, BinaryIO, NamedTuple + +from ._re import ( + RE_DATETIME, + RE_LOCALTIME, + RE_NUMBER, + match_to_datetime, + match_to_localtime, + match_to_number, +) +from ._types import Key, ParseFloat, Pos + +ASCII_CTRL = frozenset(chr(i) for i in range(32)) | frozenset(chr(127)) + +# Neither of these sets include quotation mark or backslash. They are +# currently handled as separate cases in the parser functions. +ILLEGAL_BASIC_STR_CHARS = ASCII_CTRL - frozenset("\t") +ILLEGAL_MULTILINE_BASIC_STR_CHARS = ASCII_CTRL - frozenset("\t\n") + +ILLEGAL_LITERAL_STR_CHARS = ILLEGAL_BASIC_STR_CHARS +ILLEGAL_MULTILINE_LITERAL_STR_CHARS = ILLEGAL_MULTILINE_BASIC_STR_CHARS + +ILLEGAL_COMMENT_CHARS = ILLEGAL_BASIC_STR_CHARS + +TOML_WS = frozenset(" \t") +TOML_WS_AND_NEWLINE = TOML_WS | frozenset("\n") +BARE_KEY_CHARS = frozenset(string.ascii_letters + string.digits + "-_") +KEY_INITIAL_CHARS = BARE_KEY_CHARS | frozenset("\"'") +HEXDIGIT_CHARS = frozenset(string.hexdigits) + +BASIC_STR_ESCAPE_REPLACEMENTS = MappingProxyType( + { + "\\b": "\u0008", # backspace + "\\t": "\u0009", # tab + "\\n": "\u000A", # linefeed + "\\f": "\u000C", # form feed + "\\r": "\u000D", # carriage return + '\\"': "\u0022", # quote + "\\\\": "\u005C", # backslash + } +) + + +class TOMLDecodeError(ValueError): + """An error raised if a document is not valid TOML.""" + + +def load(fp: BinaryIO, /, *, parse_float: ParseFloat = float) -> dict[str, Any]: + """Parse TOML from a binary file object.""" + b = fp.read() + try: + s = b.decode() + except AttributeError: + raise TypeError( + "File must be opened in binary mode, e.g. use `open('foo.toml', 'rb')`" + ) from None + return loads(s, parse_float=parse_float) + + +def loads(s: str, /, *, parse_float: ParseFloat = float) -> dict[str, Any]: # noqa: C901 + """Parse TOML from a string.""" + + # The spec allows converting "\r\n" to "\n", even in string + # literals. Let's do so to simplify parsing. + src = s.replace("\r\n", "\n") + pos = 0 + out = Output(NestedDict(), Flags()) + header: Key = () + parse_float = make_safe_parse_float(parse_float) + + # Parse one statement at a time + # (typically means one line in TOML source) + while True: + # 1. Skip line leading whitespace + pos = skip_chars(src, pos, TOML_WS) + + # 2. Parse rules. Expect one of the following: + # - end of file + # - end of line + # - comment + # - key/value pair + # - append dict to list (and move to its namespace) + # - create dict (and move to its namespace) + # Skip trailing whitespace when applicable. + try: + char = src[pos] + except IndexError: + break + if char == "\n": + pos += 1 + continue + if char in KEY_INITIAL_CHARS: + pos = key_value_rule(src, pos, out, header, parse_float) + pos = skip_chars(src, pos, TOML_WS) + elif char == "[": + try: + second_char: str | None = src[pos + 1] + except IndexError: + second_char = None + out.flags.finalize_pending() + if second_char == "[": + pos, header = create_list_rule(src, pos, out) + else: + pos, header = create_dict_rule(src, pos, out) + pos = skip_chars(src, pos, TOML_WS) + elif char != "#": + raise suffixed_err(src, pos, "Invalid statement") + + # 3. Skip comment + pos = skip_comment(src, pos) + + # 4. Expect end of line or end of file + try: + char = src[pos] + except IndexError: + break + if char != "\n": + raise suffixed_err( + src, pos, "Expected newline or end of document after a statement" + ) + pos += 1 + + return out.data.dict + + +class Flags: + """Flags that map to parsed keys/namespaces.""" + + # Marks an immutable namespace (inline array or inline table). + FROZEN = 0 + # Marks a nest that has been explicitly created and can no longer + # be opened using the "[table]" syntax. + EXPLICIT_NEST = 1 + + def __init__(self) -> None: + self._flags: dict[str, dict] = {} + self._pending_flags: set[tuple[Key, int]] = set() + + def add_pending(self, key: Key, flag: int) -> None: + self._pending_flags.add((key, flag)) + + def finalize_pending(self) -> None: + for key, flag in self._pending_flags: + self.set(key, flag, recursive=False) + self._pending_flags.clear() + + def unset_all(self, key: Key) -> None: + cont = self._flags + for k in key[:-1]: + if k not in cont: + return + cont = cont[k]["nested"] + cont.pop(key[-1], None) + + def set(self, key: Key, flag: int, *, recursive: bool) -> None: # noqa: A003 + cont = self._flags + key_parent, key_stem = key[:-1], key[-1] + for k in key_parent: + if k not in cont: + cont[k] = {"flags": set(), "recursive_flags": set(), "nested": {}} + cont = cont[k]["nested"] + if key_stem not in cont: + cont[key_stem] = {"flags": set(), "recursive_flags": set(), "nested": {}} + cont[key_stem]["recursive_flags" if recursive else "flags"].add(flag) + + def is_(self, key: Key, flag: int) -> bool: + if not key: + return False # document root has no flags + cont = self._flags + for k in key[:-1]: + if k not in cont: + return False + inner_cont = cont[k] + if flag in inner_cont["recursive_flags"]: + return True + cont = inner_cont["nested"] + key_stem = key[-1] + if key_stem in cont: + cont = cont[key_stem] + return flag in cont["flags"] or flag in cont["recursive_flags"] + return False + + +class NestedDict: + def __init__(self) -> None: + # The parsed content of the TOML document + self.dict: dict[str, Any] = {} + + def get_or_create_nest( + self, + key: Key, + *, + access_lists: bool = True, + ) -> dict: + cont: Any = self.dict + for k in key: + if k not in cont: + cont[k] = {} + cont = cont[k] + if access_lists and isinstance(cont, list): + cont = cont[-1] + if not isinstance(cont, dict): + raise KeyError("There is no nest behind this key") + return cont + + def append_nest_to_list(self, key: Key) -> None: + cont = self.get_or_create_nest(key[:-1]) + last_key = key[-1] + if last_key in cont: + list_ = cont[last_key] + if not isinstance(list_, list): + raise KeyError("An object other than list found behind this key") + list_.append({}) + else: + cont[last_key] = [{}] + + +class Output(NamedTuple): + data: NestedDict + flags: Flags + + +def skip_chars(src: str, pos: Pos, chars: Iterable[str]) -> Pos: + try: + while src[pos] in chars: + pos += 1 + except IndexError: + pass + return pos + + +def skip_until( + src: str, + pos: Pos, + expect: str, + *, + error_on: frozenset[str], + error_on_eof: bool, +) -> Pos: + try: + new_pos = src.index(expect, pos) + except ValueError: + new_pos = len(src) + if error_on_eof: + raise suffixed_err(src, new_pos, f"Expected {expect!r}") from None + + if not error_on.isdisjoint(src[pos:new_pos]): + while src[pos] not in error_on: + pos += 1 + raise suffixed_err(src, pos, f"Found invalid character {src[pos]!r}") + return new_pos + + +def skip_comment(src: str, pos: Pos) -> Pos: + try: + char: str | None = src[pos] + except IndexError: + char = None + if char == "#": + return skip_until( + src, pos + 1, "\n", error_on=ILLEGAL_COMMENT_CHARS, error_on_eof=False + ) + return pos + + +def skip_comments_and_array_ws(src: str, pos: Pos) -> Pos: + while True: + pos_before_skip = pos + pos = skip_chars(src, pos, TOML_WS_AND_NEWLINE) + pos = skip_comment(src, pos) + if pos == pos_before_skip: + return pos + + +def create_dict_rule(src: str, pos: Pos, out: Output) -> tuple[Pos, Key]: + pos += 1 # Skip "[" + pos = skip_chars(src, pos, TOML_WS) + pos, key = parse_key(src, pos) + + if out.flags.is_(key, Flags.EXPLICIT_NEST) or out.flags.is_(key, Flags.FROZEN): + raise suffixed_err(src, pos, f"Cannot declare {key} twice") + out.flags.set(key, Flags.EXPLICIT_NEST, recursive=False) + try: + out.data.get_or_create_nest(key) + except KeyError: + raise suffixed_err(src, pos, "Cannot overwrite a value") from None + + if not src.startswith("]", pos): + raise suffixed_err(src, pos, "Expected ']' at the end of a table declaration") + return pos + 1, key + + +def create_list_rule(src: str, pos: Pos, out: Output) -> tuple[Pos, Key]: + pos += 2 # Skip "[[" + pos = skip_chars(src, pos, TOML_WS) + pos, key = parse_key(src, pos) + + if out.flags.is_(key, Flags.FROZEN): + raise suffixed_err(src, pos, f"Cannot mutate immutable namespace {key}") + # Free the namespace now that it points to another empty list item... + out.flags.unset_all(key) + # ...but this key precisely is still prohibited from table declaration + out.flags.set(key, Flags.EXPLICIT_NEST, recursive=False) + try: + out.data.append_nest_to_list(key) + except KeyError: + raise suffixed_err(src, pos, "Cannot overwrite a value") from None + + if not src.startswith("]]", pos): + raise suffixed_err(src, pos, "Expected ']]' at the end of an array declaration") + return pos + 2, key + + +def key_value_rule( + src: str, pos: Pos, out: Output, header: Key, parse_float: ParseFloat +) -> Pos: + pos, key, value = parse_key_value_pair(src, pos, parse_float) + key_parent, key_stem = key[:-1], key[-1] + abs_key_parent = header + key_parent + + relative_path_cont_keys = (header + key[:i] for i in range(1, len(key))) + for cont_key in relative_path_cont_keys: + # Check that dotted key syntax does not redefine an existing table + if out.flags.is_(cont_key, Flags.EXPLICIT_NEST): + raise suffixed_err(src, pos, f"Cannot redefine namespace {cont_key}") + # Containers in the relative path can't be opened with the table syntax or + # dotted key/value syntax in following table sections. + out.flags.add_pending(cont_key, Flags.EXPLICIT_NEST) + + if out.flags.is_(abs_key_parent, Flags.FROZEN): + raise suffixed_err( + src, pos, f"Cannot mutate immutable namespace {abs_key_parent}" + ) + + try: + nest = out.data.get_or_create_nest(abs_key_parent) + except KeyError: + raise suffixed_err(src, pos, "Cannot overwrite a value") from None + if key_stem in nest: + raise suffixed_err(src, pos, "Cannot overwrite a value") + # Mark inline table and array namespaces recursively immutable + if isinstance(value, (dict, list)): + out.flags.set(header + key, Flags.FROZEN, recursive=True) + nest[key_stem] = value + return pos + + +def parse_key_value_pair( + src: str, pos: Pos, parse_float: ParseFloat +) -> tuple[Pos, Key, Any]: + pos, key = parse_key(src, pos) + try: + char: str | None = src[pos] + except IndexError: + char = None + if char != "=": + raise suffixed_err(src, pos, "Expected '=' after a key in a key/value pair") + pos += 1 + pos = skip_chars(src, pos, TOML_WS) + pos, value = parse_value(src, pos, parse_float) + return pos, key, value + + +def parse_key(src: str, pos: Pos) -> tuple[Pos, Key]: + pos, key_part = parse_key_part(src, pos) + key: Key = (key_part,) + pos = skip_chars(src, pos, TOML_WS) + while True: + try: + char: str | None = src[pos] + except IndexError: + char = None + if char != ".": + return pos, key + pos += 1 + pos = skip_chars(src, pos, TOML_WS) + pos, key_part = parse_key_part(src, pos) + key += (key_part,) + pos = skip_chars(src, pos, TOML_WS) + + +def parse_key_part(src: str, pos: Pos) -> tuple[Pos, str]: + try: + char: str | None = src[pos] + except IndexError: + char = None + if char in BARE_KEY_CHARS: + start_pos = pos + pos = skip_chars(src, pos, BARE_KEY_CHARS) + return pos, src[start_pos:pos] + if char == "'": + return parse_literal_str(src, pos) + if char == '"': + return parse_one_line_basic_str(src, pos) + raise suffixed_err(src, pos, "Invalid initial character for a key part") + + +def parse_one_line_basic_str(src: str, pos: Pos) -> tuple[Pos, str]: + pos += 1 + return parse_basic_str(src, pos, multiline=False) + + +def parse_array(src: str, pos: Pos, parse_float: ParseFloat) -> tuple[Pos, list]: + pos += 1 + array: list = [] + + pos = skip_comments_and_array_ws(src, pos) + if src.startswith("]", pos): + return pos + 1, array + while True: + pos, val = parse_value(src, pos, parse_float) + array.append(val) + pos = skip_comments_and_array_ws(src, pos) + + c = src[pos : pos + 1] + if c == "]": + return pos + 1, array + if c != ",": + raise suffixed_err(src, pos, "Unclosed array") + pos += 1 + + pos = skip_comments_and_array_ws(src, pos) + if src.startswith("]", pos): + return pos + 1, array + + +def parse_inline_table(src: str, pos: Pos, parse_float: ParseFloat) -> tuple[Pos, dict]: + pos += 1 + nested_dict = NestedDict() + flags = Flags() + + pos = skip_chars(src, pos, TOML_WS) + if src.startswith("}", pos): + return pos + 1, nested_dict.dict + while True: + pos, key, value = parse_key_value_pair(src, pos, parse_float) + key_parent, key_stem = key[:-1], key[-1] + if flags.is_(key, Flags.FROZEN): + raise suffixed_err(src, pos, f"Cannot mutate immutable namespace {key}") + try: + nest = nested_dict.get_or_create_nest(key_parent, access_lists=False) + except KeyError: + raise suffixed_err(src, pos, "Cannot overwrite a value") from None + if key_stem in nest: + raise suffixed_err(src, pos, f"Duplicate inline table key {key_stem!r}") + nest[key_stem] = value + pos = skip_chars(src, pos, TOML_WS) + c = src[pos : pos + 1] + if c == "}": + return pos + 1, nested_dict.dict + if c != ",": + raise suffixed_err(src, pos, "Unclosed inline table") + if isinstance(value, (dict, list)): + flags.set(key, Flags.FROZEN, recursive=True) + pos += 1 + pos = skip_chars(src, pos, TOML_WS) + + +def parse_basic_str_escape( + src: str, pos: Pos, *, multiline: bool = False +) -> tuple[Pos, str]: + escape_id = src[pos : pos + 2] + pos += 2 + if multiline and escape_id in {"\\ ", "\\\t", "\\\n"}: + # Skip whitespace until next non-whitespace character or end of + # the doc. Error if non-whitespace is found before newline. + if escape_id != "\\\n": + pos = skip_chars(src, pos, TOML_WS) + try: + char = src[pos] + except IndexError: + return pos, "" + if char != "\n": + raise suffixed_err(src, pos, "Unescaped '\\' in a string") + pos += 1 + pos = skip_chars(src, pos, TOML_WS_AND_NEWLINE) + return pos, "" + if escape_id == "\\u": + return parse_hex_char(src, pos, 4) + if escape_id == "\\U": + return parse_hex_char(src, pos, 8) + try: + return pos, BASIC_STR_ESCAPE_REPLACEMENTS[escape_id] + except KeyError: + raise suffixed_err(src, pos, "Unescaped '\\' in a string") from None + + +def parse_basic_str_escape_multiline(src: str, pos: Pos) -> tuple[Pos, str]: + return parse_basic_str_escape(src, pos, multiline=True) + + +def parse_hex_char(src: str, pos: Pos, hex_len: int) -> tuple[Pos, str]: + hex_str = src[pos : pos + hex_len] + if len(hex_str) != hex_len or not HEXDIGIT_CHARS.issuperset(hex_str): + raise suffixed_err(src, pos, "Invalid hex value") + pos += hex_len + hex_int = int(hex_str, 16) + if not is_unicode_scalar_value(hex_int): + raise suffixed_err(src, pos, "Escaped character is not a Unicode scalar value") + return pos, chr(hex_int) + + +def parse_literal_str(src: str, pos: Pos) -> tuple[Pos, str]: + pos += 1 # Skip starting apostrophe + start_pos = pos + pos = skip_until( + src, pos, "'", error_on=ILLEGAL_LITERAL_STR_CHARS, error_on_eof=True + ) + return pos + 1, src[start_pos:pos] # Skip ending apostrophe + + +def parse_multiline_str(src: str, pos: Pos, *, literal: bool) -> tuple[Pos, str]: + pos += 3 + if src.startswith("\n", pos): + pos += 1 + + if literal: + delim = "'" + end_pos = skip_until( + src, + pos, + "'''", + error_on=ILLEGAL_MULTILINE_LITERAL_STR_CHARS, + error_on_eof=True, + ) + result = src[pos:end_pos] + pos = end_pos + 3 + else: + delim = '"' + pos, result = parse_basic_str(src, pos, multiline=True) + + # Add at maximum two extra apostrophes/quotes if the end sequence + # is 4 or 5 chars long instead of just 3. + if not src.startswith(delim, pos): + return pos, result + pos += 1 + if not src.startswith(delim, pos): + return pos, result + delim + pos += 1 + return pos, result + (delim * 2) + + +def parse_basic_str(src: str, pos: Pos, *, multiline: bool) -> tuple[Pos, str]: + if multiline: + error_on = ILLEGAL_MULTILINE_BASIC_STR_CHARS + parse_escapes = parse_basic_str_escape_multiline + else: + error_on = ILLEGAL_BASIC_STR_CHARS + parse_escapes = parse_basic_str_escape + result = "" + start_pos = pos + while True: + try: + char = src[pos] + except IndexError: + raise suffixed_err(src, pos, "Unterminated string") from None + if char == '"': + if not multiline: + return pos + 1, result + src[start_pos:pos] + if src.startswith('"""', pos): + return pos + 3, result + src[start_pos:pos] + pos += 1 + continue + if char == "\\": + result += src[start_pos:pos] + pos, parsed_escape = parse_escapes(src, pos) + result += parsed_escape + start_pos = pos + continue + if char in error_on: + raise suffixed_err(src, pos, f"Illegal character {char!r}") + pos += 1 + + +def parse_value( # noqa: C901 + src: str, pos: Pos, parse_float: ParseFloat +) -> tuple[Pos, Any]: + try: + char: str | None = src[pos] + except IndexError: + char = None + + # IMPORTANT: order conditions based on speed of checking and likelihood + + # Basic strings + if char == '"': + if src.startswith('"""', pos): + return parse_multiline_str(src, pos, literal=False) + return parse_one_line_basic_str(src, pos) + + # Literal strings + if char == "'": + if src.startswith("'''", pos): + return parse_multiline_str(src, pos, literal=True) + return parse_literal_str(src, pos) + + # Booleans + if char == "t": + if src.startswith("true", pos): + return pos + 4, True + if char == "f": + if src.startswith("false", pos): + return pos + 5, False + + # Arrays + if char == "[": + return parse_array(src, pos, parse_float) + + # Inline tables + if char == "{": + return parse_inline_table(src, pos, parse_float) + + # Dates and times + datetime_match = RE_DATETIME.match(src, pos) + if datetime_match: + try: + datetime_obj = match_to_datetime(datetime_match) + except ValueError as e: + raise suffixed_err(src, pos, "Invalid date or datetime") from e + return datetime_match.end(), datetime_obj + localtime_match = RE_LOCALTIME.match(src, pos) + if localtime_match: + return localtime_match.end(), match_to_localtime(localtime_match) + + # Integers and "normal" floats. + # The regex will greedily match any type starting with a decimal + # char, so needs to be located after handling of dates and times. + number_match = RE_NUMBER.match(src, pos) + if number_match: + return number_match.end(), match_to_number(number_match, parse_float) + + # Special floats + first_three = src[pos : pos + 3] + if first_three in {"inf", "nan"}: + return pos + 3, parse_float(first_three) + first_four = src[pos : pos + 4] + if first_four in {"-inf", "+inf", "-nan", "+nan"}: + return pos + 4, parse_float(first_four) + + raise suffixed_err(src, pos, "Invalid value") + + +def suffixed_err(src: str, pos: Pos, msg: str) -> TOMLDecodeError: + """Return a `TOMLDecodeError` where error message is suffixed with + coordinates in source.""" + + def coord_repr(src: str, pos: Pos) -> str: + if pos >= len(src): + return "end of document" + line = src.count("\n", 0, pos) + 1 + if line == 1: + column = pos + 1 + else: + column = pos - src.rindex("\n", 0, pos) + return f"line {line}, column {column}" + + return TOMLDecodeError(f"{msg} (at {coord_repr(src, pos)})") + + +def is_unicode_scalar_value(codepoint: int) -> bool: + return (0 <= codepoint <= 55295) or (57344 <= codepoint <= 1114111) + + +def make_safe_parse_float(parse_float: ParseFloat) -> ParseFloat: + """A decorator to make `parse_float` safe. + + `parse_float` must not return dicts or lists, because these types + would be mixed with parsed TOML tables and arrays, thus confusing + the parser. The returned decorated callable raises `ValueError` + instead of returning illegal types. + """ + # The default `float` callable never returns illegal types. Optimize it. + if parse_float is float: # type: ignore[comparison-overlap] + return float + + def safe_parse_float(float_str: str) -> Any: + float_value = parse_float(float_str) + if isinstance(float_value, (dict, list)): + raise ValueError("parse_float must not return dicts or lists") + return float_value + + return safe_parse_float diff --git a/Lib/tomllib/_re.py b/Lib/tomllib/_re.py new file mode 100644 index 0000000000000..994bb7493fd92 --- /dev/null +++ b/Lib/tomllib/_re.py @@ -0,0 +1,107 @@ +# SPDX-License-Identifier: MIT +# SPDX-FileCopyrightText: 2021 Taneli Hukkinen +# Licensed to PSF under a Contributor Agreement. + +from __future__ import annotations + +from datetime import date, datetime, time, timedelta, timezone, tzinfo +from functools import lru_cache +import re +from typing import Any + +from ._types import ParseFloat + +# E.g. +# - 00:32:00.999999 +# - 00:32:00 +_TIME_RE_STR = r"([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])(?:\.([0-9]{1,6})[0-9]*)?" + +RE_NUMBER = re.compile( + r""" +0 +(?: + x[0-9A-Fa-f](?:_?[0-9A-Fa-f])* # hex + | + b[01](?:_?[01])* # bin + | + o[0-7](?:_?[0-7])* # oct +) +| +[+-]?(?:0|[1-9](?:_?[0-9])*) # dec, integer part +(?P + (?:\.[0-9](?:_?[0-9])*)? # optional fractional part + (?:[eE][+-]?[0-9](?:_?[0-9])*)? # optional exponent part +) +""", + flags=re.VERBOSE, +) +RE_LOCALTIME = re.compile(_TIME_RE_STR) +RE_DATETIME = re.compile( + rf""" +([0-9]{{4}})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01]) # date, e.g. 1988-10-27 +(?: + [Tt ] + {_TIME_RE_STR} + (?:([Zz])|([+-])([01][0-9]|2[0-3]):([0-5][0-9]))? # optional time offset +)? +""", + flags=re.VERBOSE, +) + + +def match_to_datetime(match: re.Match) -> datetime | date: + """Convert a `RE_DATETIME` match to `datetime.datetime` or `datetime.date`. + + Raises ValueError if the match does not correspond to a valid date + or datetime. + """ + ( + year_str, + month_str, + day_str, + hour_str, + minute_str, + sec_str, + micros_str, + zulu_time, + offset_sign_str, + offset_hour_str, + offset_minute_str, + ) = match.groups() + year, month, day = int(year_str), int(month_str), int(day_str) + if hour_str is None: + return date(year, month, day) + hour, minute, sec = int(hour_str), int(minute_str), int(sec_str) + micros = int(micros_str.ljust(6, "0")) if micros_str else 0 + if offset_sign_str: + tz: tzinfo | None = cached_tz( + offset_hour_str, offset_minute_str, offset_sign_str + ) + elif zulu_time: + tz = timezone.utc + else: # local date-time + tz = None + return datetime(year, month, day, hour, minute, sec, micros, tzinfo=tz) + + + at lru_cache(maxsize=None) +def cached_tz(hour_str: str, minute_str: str, sign_str: str) -> timezone: + sign = 1 if sign_str == "+" else -1 + return timezone( + timedelta( + hours=sign * int(hour_str), + minutes=sign * int(minute_str), + ) + ) + + +def match_to_localtime(match: re.Match) -> time: + hour_str, minute_str, sec_str, micros_str = match.groups() + micros = int(micros_str.ljust(6, "0")) if micros_str else 0 + return time(int(hour_str), int(minute_str), int(sec_str), micros) + + +def match_to_number(match: re.Match, parse_float: ParseFloat) -> Any: + if match.group("floatpart"): + return parse_float(match.group()) + return int(match.group(), 0) diff --git a/Lib/tomllib/_types.py b/Lib/tomllib/_types.py new file mode 100644 index 0000000000000..d949412e03b29 --- /dev/null +++ b/Lib/tomllib/_types.py @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: MIT +# SPDX-FileCopyrightText: 2021 Taneli Hukkinen +# Licensed to PSF under a Contributor Agreement. + +from typing import Any, Callable, Tuple + +# Type annotations +ParseFloat = Callable[[str], Any] +Key = Tuple[str, ...] +Pos = int diff --git a/Misc/NEWS.d/next/Library/2022-02-23-01-11-08.bpo-40059.Iwc9UH.rst b/Misc/NEWS.d/next/Library/2022-02-23-01-11-08.bpo-40059.Iwc9UH.rst new file mode 100644 index 0000000000000..d41ff1304e83b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-02-23-01-11-08.bpo-40059.Iwc9UH.rst @@ -0,0 +1 @@ +:pep:`680`, the :mod:`tomllib` module. Adds support for parsing TOML. diff --git a/Python/stdlib_module_names.h b/Python/stdlib_module_names.h index 754fa94e35eba..553585a76a394 100644 --- a/Python/stdlib_module_names.h +++ b/Python/stdlib_module_names.h @@ -277,6 +277,7 @@ static const char* _Py_stdlib_module_names[] = { "tkinter", "token", "tokenize", +"tomllib", "trace", "traceback", "tracemalloc", From webhook-mailer at python.org Tue Mar 8 04:03:47 2022 From: webhook-mailer at python.org (ambv) Date: Tue, 08 Mar 2022 09:03:47 -0000 Subject: [Python-checkins] bpo-46932: Update bundled libexpat to 2.4.7 (GH-31736) (GH-31740) Message-ID: https://github.com/python/cpython/commit/c3ec5bc1b7a14b04621920f111aee01c31f6f1c1 commit: c3ec5bc1b7a14b04621920f111aee01c31f6f1c1 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv date: 2022-03-08T10:03:18+01:00 summary: bpo-46932: Update bundled libexpat to 2.4.7 (GH-31736) (GH-31740) (cherry picked from commit 176835c3d5c70f4c1b152cc2062b549144e37094) Co-authored-by: Steve Dower files: A Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst M Modules/expat/expat.h M Modules/expat/xmlparse.c diff --git a/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst b/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst new file mode 100644 index 0000000000000..8545c656eab89 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst @@ -0,0 +1 @@ +Update bundled libexpat to 2.4.7 diff --git a/Modules/expat/expat.h b/Modules/expat/expat.h index 46a0e1bcd22de..c9214f64070a8 100644 --- a/Modules/expat/expat.h +++ b/Modules/expat/expat.h @@ -15,6 +15,7 @@ Copyright (c) 2016 Cristian Rodr?guez Copyright (c) 2016 Thomas Beutlich Copyright (c) 2017 Rhodri James + Copyright (c) 2022 Thijs Schreijer Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -174,8 +175,10 @@ struct XML_cp { }; /* This is called for an element declaration. See above for - description of the model argument. It's the caller's responsibility - to free model when finished with it. + description of the model argument. It's the user code's responsibility + to free model when finished with it. See XML_FreeContentModel. + There is no need to free the model from the handler, it can be kept + around and freed at a later stage. */ typedef void(XMLCALL *XML_ElementDeclHandler)(void *userData, const XML_Char *name, @@ -237,6 +240,17 @@ XML_ParserCreate(const XML_Char *encoding); and the local part will be concatenated without any separator. It is a programming error to use the separator '\0' with namespace triplets (see XML_SetReturnNSTriplet). + If a namespace separator is chosen that can be part of a URI or + part of an XML name, splitting an expanded name back into its + 1, 2 or 3 original parts on application level in the element handler + may end up vulnerable, so these are advised against; sane choices for + a namespace separator are e.g. '\n' (line feed) and '|' (pipe). + + Note that Expat does not validate namespace URIs (beyond encoding) + against RFC 3986 today (and is not required to do so with regard to + the XML 1.0 namespaces specification) but it may start doing that + in future releases. Before that, an application using Expat must + be ready to receive namespace URIs containing non-URI characters. */ XMLPARSEAPI(XML_Parser) XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); @@ -317,7 +331,7 @@ typedef void(XMLCALL *XML_StartDoctypeDeclHandler)(void *userData, const XML_Char *pubid, int has_internal_subset); -/* This is called for the start of the DOCTYPE declaration when the +/* This is called for the end of the DOCTYPE declaration when the closing > is encountered, but after processing any external subset. */ @@ -1041,7 +1055,7 @@ XML_SetBillionLaughsAttackProtectionActivationThreshold( */ #define XML_MAJOR_VERSION 2 #define XML_MINOR_VERSION 4 -#define XML_MICRO_VERSION 6 +#define XML_MICRO_VERSION 7 #ifdef __cplusplus } diff --git a/Modules/expat/xmlparse.c b/Modules/expat/xmlparse.c index 7db28d07acbcd..05216d997b07f 100644 --- a/Modules/expat/xmlparse.c +++ b/Modules/expat/xmlparse.c @@ -1,4 +1,4 @@ -/* a30d2613dcfdef81475a9d1a349134d2d42722172fdaa7d5bb12ed2aa74b9596 (2.4.6+) +/* fcb1a62fefa945567301146eb98e3ad3413e823a41c4378e84e8b6b6f308d824 (2.4.7+) __ __ _ ___\ \/ /_ __ __ _| |_ / _ \\ /| '_ \ / _` | __| @@ -34,6 +34,7 @@ Copyright (c) 2019 Vadim Zeitlin Copyright (c) 2021 Dong-hee Na Copyright (c) 2022 Samanta Navarro + Copyright (c) 2022 Jeffrey Walton Licensed under the MIT license: Permission is hereby granted, free of charge, to any person obtaining @@ -133,7 +134,7 @@ * BSD / macOS (including <10.7) (arc4random): HAVE_ARC4RANDOM, \ * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \ * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \ - * Linux (including <3.17) / BSD / macOS (including <10.7) (/dev/urandom): XML_DEV_URANDOM, \ + * Linux (including <3.17) / BSD / macOS (including <10.7) / Solaris >=8 (/dev/urandom): XML_DEV_URANDOM, \ * Windows >=Vista (rand_s): _WIN32. \ \ If insist on not using any of these, bypass this error by defining \ @@ -722,6 +723,7 @@ XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) { return XML_ParserCreate_MM(encodingName, NULL, tmp); } +// "xml=http://www.w3.org/XML/1998/namespace" static const XML_Char implicitContext[] = {ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, @@ -3704,12 +3706,124 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, return XML_ERROR_NONE; } +static XML_Bool +is_rfc3986_uri_char(XML_Char candidate) { + // For the RFC 3986 ANBF grammar see + // https://datatracker.ietf.org/doc/html/rfc3986#appendix-A + + switch (candidate) { + // From rule "ALPHA" (uppercase half) + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + + // From rule "ALPHA" (lowercase half) + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': + + // From rule "DIGIT" + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + + // From rule "pct-encoded" + case '%': + + // From rule "unreserved" + case '-': + case '.': + case '_': + case '~': + + // From rule "gen-delims" + case ':': + case '/': + case '?': + case '#': + case '[': + case ']': + case '@': + + // From rule "sub-delims" + case '!': + case '$': + case '&': + case '\'': + case '(': + case ')': + case '*': + case '+': + case ',': + case ';': + case '=': + return XML_TRUE; + + default: + return XML_FALSE; + } +} + /* addBinding() overwrites the value of prefix->binding without checking. Therefore one must keep track of the old value outside of addBinding(). */ static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr) { + // "http://www.w3.org/XML/1998/namespace" static const XML_Char xmlNamespace[] = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, @@ -3720,6 +3834,7 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'}; static const int xmlLen = (int)sizeof(xmlNamespace) / sizeof(XML_Char) - 1; + // "http://www.w3.org/2000/xmlns/" static const XML_Char xmlnsNamespace[] = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, @@ -3760,14 +3875,26 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, && (len > xmlnsLen || uri[len] != xmlnsNamespace[len])) isXMLNS = XML_FALSE; - // NOTE: While Expat does not validate namespace URIs against RFC 3986, - // we have to at least make sure that the XML processor on top of - // Expat (that is splitting tag names by namespace separator into - // 2- or 3-tuples (uri-local or uri-local-prefix)) cannot be confused - // by an attacker putting additional namespace separator characters - // into namespace declarations. That would be ambiguous and not to - // be expected. - if (parser->m_ns && (uri[len] == parser->m_namespaceSeparator)) { + // NOTE: While Expat does not validate namespace URIs against RFC 3986 + // today (and is not REQUIRED to do so with regard to the XML 1.0 + // namespaces specification) we have to at least make sure, that + // the application on top of Expat (that is likely splitting expanded + // element names ("qualified names") of form + // "[uri sep] local [sep prefix] '\0'" back into 1, 2 or 3 pieces + // in its element handler code) cannot be confused by an attacker + // putting additional namespace separator characters into namespace + // declarations. That would be ambiguous and not to be expected. + // + // While the HTML API docs of function XML_ParserCreateNS have been + // advising against use of a namespace separator character that can + // appear in a URI for >20 years now, some widespread applications + // are using URI characters (':' (colon) in particular) for a + // namespace separator, in practice. To keep these applications + // functional, we only reject namespaces URIs containing the + // application-chosen namespace separator if the chosen separator + // is a non-URI character with regard to RFC 3986. + if (parser->m_ns && (uri[len] == parser->m_namespaceSeparator) + && ! is_rfc3986_uri_char(uri[len])) { return XML_ERROR_SYNTAX; } } From webhook-mailer at python.org Tue Mar 8 04:04:36 2022 From: webhook-mailer at python.org (ambv) Date: Tue, 08 Mar 2022 09:04:36 -0000 Subject: [Python-checkins] bpo-46948: Fix CVE-2022-26488 by ensuring the Windows Installer correctly uses the install path during repair (GH-31729) Message-ID: https://github.com/python/cpython/commit/cff1b78c1dfb2a62b1e16fabc5f43bc3634d9de7 commit: cff1b78c1dfb2a62b1e16fabc5f43bc3634d9de7 branch: 3.8 author: Steve Dower committer: ambv date: 2022-03-08T10:04:24+01:00 summary: bpo-46948: Fix CVE-2022-26488 by ensuring the Windows Installer correctly uses the install path during repair (GH-31729) files: A Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst M Tools/msi/bundle/bundle.wxs M Tools/msi/common.wxs M Tools/msi/dev/dev.wxs M Tools/msi/doc/doc.wxs M Tools/msi/lib/lib.wxs M Tools/msi/path/path.wxs M Tools/msi/tcltk/tcltk.wxs M Tools/msi/test/test.wxs M Tools/msi/tools/tools.wxs M Tools/msi/ucrt/ucrt.wxs diff --git a/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst b/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst new file mode 100644 index 0000000000000..cfc4827882ded --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst @@ -0,0 +1,2 @@ +Prevent CVE-2022-26488 by ensuring the Add to PATH option in the Windows +installer uses the correct path when being repaired. diff --git a/Tools/msi/bundle/bundle.wxs b/Tools/msi/bundle/bundle.wxs index ddd6870f62552..12f2a46c8c7e9 100644 --- a/Tools/msi/bundle/bundle.wxs +++ b/Tools/msi/bundle/bundle.wxs @@ -95,8 +95,8 @@ - + diff --git a/Tools/msi/common.wxs b/Tools/msi/common.wxs index 398d94a24d554..d8f3cde99ab52 100644 --- a/Tools/msi/common.wxs +++ b/Tools/msi/common.wxs @@ -53,11 +53,23 @@ - + + - + + + + + + + + + + + + diff --git a/Tools/msi/dev/dev.wxs b/Tools/msi/dev/dev.wxs index 23a710df87d55..2ddeb31afc770 100644 --- a/Tools/msi/dev/dev.wxs +++ b/Tools/msi/dev/dev.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/doc/doc.wxs b/Tools/msi/doc/doc.wxs index cd1a68cc2601a..cc5bdb493e5fe 100644 --- a/Tools/msi/doc/doc.wxs +++ b/Tools/msi/doc/doc.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/lib/lib.wxs b/Tools/msi/lib/lib.wxs index 2a3b9ecfeef8d..b38cd9114be74 100644 --- a/Tools/msi/lib/lib.wxs +++ b/Tools/msi/lib/lib.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/path/path.wxs b/Tools/msi/path/path.wxs index 8b37936cc938f..017b812270c5b 100644 --- a/Tools/msi/path/path.wxs +++ b/Tools/msi/path/path.wxs @@ -2,7 +2,8 @@ - + + diff --git a/Tools/msi/tcltk/tcltk.wxs b/Tools/msi/tcltk/tcltk.wxs index eeae8e8b0dfa5..bbf6ac70fadf6 100644 --- a/Tools/msi/tcltk/tcltk.wxs +++ b/Tools/msi/tcltk/tcltk.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/test/test.wxs b/Tools/msi/test/test.wxs index f2ed64f07bf28..e8f514a222366 100644 --- a/Tools/msi/test/test.wxs +++ b/Tools/msi/test/test.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/tools/tools.wxs b/Tools/msi/tools/tools.wxs index 7a805d0612e08..133a743efccae 100644 --- a/Tools/msi/tools/tools.wxs +++ b/Tools/msi/tools/tools.wxs @@ -4,6 +4,7 @@ + diff --git a/Tools/msi/ucrt/ucrt.wxs b/Tools/msi/ucrt/ucrt.wxs index 76e56820c53b2..94fd3f0e97488 100644 --- a/Tools/msi/ucrt/ucrt.wxs +++ b/Tools/msi/ucrt/ucrt.wxs @@ -4,6 +4,7 @@ + From webhook-mailer at python.org Tue Mar 8 04:05:06 2022 From: webhook-mailer at python.org (ambv) Date: Tue, 08 Mar 2022 09:05:06 -0000 Subject: [Python-checkins] bpo-44549: Update bzip2 to 1.0.8 in Windows builds to mitigate CVE-2016-3189 and CVE-2019-12900 (GH-31732) (GH-31734) Message-ID: https://github.com/python/cpython/commit/6649519e67841b1aa12672f1d9b5cb24494f6196 commit: 6649519e67841b1aa12672f1d9b5cb24494f6196 branch: 3.8 author: Steve Dower committer: ambv date: 2022-03-08T10:04:59+01:00 summary: bpo-44549: Update bzip2 to 1.0.8 in Windows builds to mitigate CVE-2016-3189 and CVE-2019-12900 (GH-31732) (GH-31734) files: A Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst M PCbuild/get_externals.bat M PCbuild/python.props M PCbuild/readme.txt diff --git a/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst b/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst new file mode 100644 index 0000000000000..0f1ef9af6c617 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst @@ -0,0 +1,2 @@ +Update bzip2 to 1.0.8 in Windows builds to mitigate CVE-2016-3189 and +CVE-2019-12900 diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index d975f05d8f3a9..2eff5e0bd0a00 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -51,7 +51,7 @@ if NOT DEFINED PYTHON ( echo.Fetching external libraries... set libraries= -set libraries=%libraries% bzip2-1.0.6 +set libraries=%libraries% bzip2-1.0.8 if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.3.0 if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1l set libraries=%libraries% sqlite-3.35.5.0 diff --git a/PCbuild/python.props b/PCbuild/python.props index 0d25e51126a71..7dfcf8f8a25d9 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -57,7 +57,7 @@ $([System.IO.Path]::GetFullPath(`$(PySourcePath)externals`)) $(ExternalsDir)\ $(ExternalsDir)sqlite-3.35.5.0\ - $(ExternalsDir)bzip2-1.0.6\ + $(ExternalsDir)bzip2-1.0.8\ $(ExternalsDir)xz-5.2.2\ $(ExternalsDir)libffi-3.3.0\ $(ExternalsDir)libffi-3.3.0\$(ArchName)\ diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index e6b9a78ea8286..6ad55ab922e1b 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -157,7 +157,7 @@ interpreter, but they do implement several major features. See the about getting the source for building these libraries. The sub-projects are: _bz2 - Python wrapper for version 1.0.6 of the libbzip2 compression library + Python wrapper for version 1.0.8 of the libbzip2 compression library Homepage: http://www.bzip.org/ _lzma From webhook-mailer at python.org Tue Mar 8 04:35:03 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Tue, 08 Mar 2022 09:35:03 -0000 Subject: [Python-checkins] bpo-44439: _ZipWriteFile.write() handle buffer protocol correctly (GH-29468) Message-ID: https://github.com/python/cpython/commit/36dd7396fcd26d8bf9919d536d05d7000becbe5b commit: 36dd7396fcd26d8bf9919d536d05d7000becbe5b branch: main author: Ma Lin committer: serhiy-storchaka date: 2022-03-08T11:33:56+02:00 summary: bpo-44439: _ZipWriteFile.write() handle buffer protocol correctly (GH-29468) Co-authored-by: Marco Ribeiro files: A Misc/NEWS.d/next/Library/2021-11-08-20-27-41.bpo-44439.I_8qro.rst M Lib/test/test_zipfile.py M Lib/zipfile.py diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index de2dd33f43660..759a4abb9d4d4 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -1,3 +1,4 @@ +import array import contextlib import importlib.util import io @@ -1121,6 +1122,14 @@ def test_write_after_close(self): self.assertRaises(ValueError, w.write, b'') self.assertEqual(zipf.read('test'), data) + def test_issue44439(self): + q = array.array('Q', [1, 2, 3, 4, 5]) + LENGTH = len(q) * q.itemsize + with zipfile.ZipFile(io.BytesIO(), 'w', self.compression) as zip: + with zip.open('data', 'w') as data: + self.assertEqual(data.write(q), LENGTH) + self.assertEqual(zip.getinfo('data').file_size, LENGTH) + class StoredWriterTests(AbstractWriterTests, unittest.TestCase): compression = zipfile.ZIP_STORED diff --git a/Lib/zipfile.py b/Lib/zipfile.py index 8e9325b934326..41bf49a8fe685 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -1147,8 +1147,15 @@ def writable(self): def write(self, data): if self.closed: raise ValueError('I/O operation on closed file.') - nbytes = len(data) + + # Accept any data that supports the buffer protocol + if isinstance(data, (bytes, bytearray)): + nbytes = len(data) + else: + data = memoryview(data) + nbytes = data.nbytes self._file_size += nbytes + self._crc = crc32(data, self._crc) if self._compressor: data = self._compressor.compress(data) diff --git a/Misc/NEWS.d/next/Library/2021-11-08-20-27-41.bpo-44439.I_8qro.rst b/Misc/NEWS.d/next/Library/2021-11-08-20-27-41.bpo-44439.I_8qro.rst new file mode 100644 index 0000000000000..f4e562c4236d2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-11-08-20-27-41.bpo-44439.I_8qro.rst @@ -0,0 +1,2 @@ +Fix ``.write()`` method of a member file in ``ZipFile``, when the input data is +an object that supports the buffer protocol, the file length may be wrong. From webhook-mailer at python.org Tue Mar 8 04:35:37 2022 From: webhook-mailer at python.org (ambv) Date: Tue, 08 Mar 2022 09:35:37 -0000 Subject: [Python-checkins] Update copyright year to 2022. (GH-30335) (GH-31478) Message-ID: https://github.com/python/cpython/commit/28ad79e732f8bba7b7cf02e006c1e36b88adeefd commit: 28ad79e732f8bba7b7cf02e006c1e36b88adeefd branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv date: 2022-03-08T10:35:32+01:00 summary: Update copyright year to 2022. (GH-30335) (GH-31478) Automerge-Triggered-By: GH:benjaminp (cherry picked from commit ba00f0d93a4aea85ae8089f139856a7c450584d7) Co-authored-by: Benjamin Peterson files: M Doc/copyright.rst M Doc/license.rst M LICENSE M Mac/IDLE/IDLE.app/Contents/Info.plist M Mac/PythonLauncher/Info.plist.in M Mac/Resources/app/Info.plist.in M PC/python_ver_rc.h M Python/getcopyright.c M README.rst diff --git a/Doc/copyright.rst b/Doc/copyright.rst index 4191c0bb63a2c..e64a49328b472 100644 --- a/Doc/copyright.rst +++ b/Doc/copyright.rst @@ -4,7 +4,7 @@ Copyright Python and this documentation is: -Copyright ? 2001-2021 Python Software Foundation. All rights reserved. +Copyright ? 2001-2022 Python Software Foundation. All rights reserved. Copyright ? 2000 BeOpen.com. All rights reserved. diff --git a/Doc/license.rst b/Doc/license.rst index ceb946e8bb11f..250e6cda35e7d 100644 --- a/Doc/license.rst +++ b/Doc/license.rst @@ -100,7 +100,7 @@ PSF LICENSE AGREEMENT FOR PYTHON |release| analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python |release| alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of - copyright, i.e., "Copyright ? 2001-2021 Python Software Foundation; All Rights + copyright, i.e., "Copyright ? 2001-2022 Python Software Foundation; All Rights Reserved" are retained in Python |release| alone or in any derivative version prepared by Licensee. diff --git a/LICENSE b/LICENSE index 473861da1be7c..739c90c284001 100644 --- a/LICENSE +++ b/LICENSE @@ -84,7 +84,7 @@ analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Python Software Foundation; +2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022 Python Software Foundation; All Rights Reserved" are retained in Python alone or in any derivative version prepared by Licensee. diff --git a/Mac/IDLE/IDLE.app/Contents/Info.plist b/Mac/IDLE/IDLE.app/Contents/Info.plist index f6b5cfe8d5451..d197c77ed4b1a 100644 --- a/Mac/IDLE/IDLE.app/Contents/Info.plist +++ b/Mac/IDLE/IDLE.app/Contents/Info.plist @@ -36,7 +36,7 @@ CFBundleExecutable IDLE CFBundleGetInfoString - %version%, ? 2001-2021 Python Software Foundation + %version%, ? 2001-2022 Python Software Foundation CFBundleIconFile IDLE.icns CFBundleIdentifier diff --git a/Mac/PythonLauncher/Info.plist.in b/Mac/PythonLauncher/Info.plist.in index 3d8bc3e4154ee..70f215d07249b 100644 --- a/Mac/PythonLauncher/Info.plist.in +++ b/Mac/PythonLauncher/Info.plist.in @@ -40,7 +40,7 @@ CFBundleExecutable Python Launcher CFBundleGetInfoString - %VERSION%, ? 2001-2021 Python Software Foundation + %VERSION%, ? 2001-2022 Python Software Foundation CFBundleIconFile PythonLauncher.icns CFBundleIdentifier diff --git a/Mac/Resources/app/Info.plist.in b/Mac/Resources/app/Info.plist.in index 2c801332332b3..84843b734e3d6 100644 --- a/Mac/Resources/app/Info.plist.in +++ b/Mac/Resources/app/Info.plist.in @@ -37,7 +37,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleLongVersionString - %version%, (c) 2001-2021 Python Software Foundation. + %version%, (c) 2001-2022 Python Software Foundation. CFBundleName Python CFBundlePackageType diff --git a/PC/python_ver_rc.h b/PC/python_ver_rc.h index 81b89fe9d7903..15a4d09d801e1 100644 --- a/PC/python_ver_rc.h +++ b/PC/python_ver_rc.h @@ -5,7 +5,7 @@ #include "winver.h" #define PYTHON_COMPANY "Python Software Foundation" -#define PYTHON_COPYRIGHT "Copyright \xA9 2001-2021 Python Software Foundation. Copyright \xA9 2000 BeOpen.com. Copyright \xA9 1995-2001 CNRI. Copyright \xA9 1991-1995 SMC." +#define PYTHON_COPYRIGHT "Copyright \xA9 2001-2022 Python Software Foundation. Copyright \xA9 2000 BeOpen.com. Copyright \xA9 1995-2001 CNRI. Copyright \xA9 1991-1995 SMC." #define MS_WINDOWS #include "modsupport.h" diff --git a/Python/getcopyright.c b/Python/getcopyright.c index 7fdeb314d5261..88d1d0536253a 100644 --- a/Python/getcopyright.c +++ b/Python/getcopyright.c @@ -4,7 +4,7 @@ static const char cprt[] = "\ -Copyright (c) 2001-2021 Python Software Foundation.\n\ +Copyright (c) 2001-2022 Python Software Foundation.\n\ All Rights Reserved.\n\ \n\ Copyright (c) 2000 BeOpen.com.\n\ diff --git a/README.rst b/README.rst index 7ef8ea53d0f3c..2797b59f79b8b 100644 --- a/README.rst +++ b/README.rst @@ -18,7 +18,7 @@ This is Python version 3.8.12 :target: https://discuss.python.org/ -Copyright (c) 2001-2021 Python Software Foundation. All rights reserved. +Copyright (c) 2001-2022 Python Software Foundation. All rights reserved. See the end of this file for further copyright and license information. @@ -246,7 +246,7 @@ See :pep:`569` for Python 3.8 release details. Copyright and License Information --------------------------------- -Copyright (c) 2001-2021 Python Software Foundation. All rights reserved. +Copyright (c) 2001-2022 Python Software Foundation. All rights reserved. Copyright (c) 2000 BeOpen.com. All rights reserved. From webhook-mailer at python.org Tue Mar 8 04:35:52 2022 From: webhook-mailer at python.org (ambv) Date: Tue, 08 Mar 2022 09:35:52 -0000 Subject: [Python-checkins] bpo-46784: Add newly exported expat symbols to the namespace. (GH-31397) (GH-31419) Message-ID: https://github.com/python/cpython/commit/ccbc31ecf3a08ef626be9bbb099f0ce801142fc8 commit: ccbc31ecf3a08ef626be9bbb099f0ce801142fc8 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv date: 2022-03-08T10:35:47+01:00 summary: bpo-46784: Add newly exported expat symbols to the namespace. (GH-31397) (GH-31419) The libexpat 2.4.1 upgrade from introduced the following new exported symbols: * `testingAccountingGetCountBytesDirect` * `testingAccountingGetCountBytesIndirect` * `unsignedCharToPrintable` * `XML_SetBillionLaughsAttackProtectionActivationThreshold` * `XML_SetBillionLaughsAttackProtectionMaximumAmplification` We need to adjust [Modules/expat/pyexpatns.h](https://github.com/python/cpython/blob/master/Modules/expat/pyexpatns.h) (The newer libexpat upgrade has no new symbols). Automerge-Triggered-By: GH:gpshead (cherry picked from commit 6312c1052c0186b4596fc45c42fd3ade9f8f5911) Co-authored-by: Yilei "Dolee" Yang files: A Misc/NEWS.d/next/Library/2022-02-18-22-10-30.bpo-46784.SVOQJx.rst M Modules/expat/pyexpatns.h diff --git a/Misc/NEWS.d/next/Library/2022-02-18-22-10-30.bpo-46784.SVOQJx.rst b/Misc/NEWS.d/next/Library/2022-02-18-22-10-30.bpo-46784.SVOQJx.rst new file mode 100644 index 0000000000000..d190816637ae8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-02-18-22-10-30.bpo-46784.SVOQJx.rst @@ -0,0 +1 @@ +Fix libexpat symbols collisions with user dynamically loaded or statically linked libexpat in embedded Python. diff --git a/Modules/expat/pyexpatns.h b/Modules/expat/pyexpatns.h index cfb742ee000b0..d45d9b6c45715 100644 --- a/Modules/expat/pyexpatns.h +++ b/Modules/expat/pyexpatns.h @@ -38,6 +38,9 @@ #ifndef PYEXPATNS_H #define PYEXPATNS_H +#define testingAccountingGetCountBytesDirect PyExpat_testingAccountingGetCountBytesDirect +#define testingAccountingGetCountBytesIndirect PyExpat_testingAccountingGetCountBytesIndirect +#define unsignedCharToPrintable PyExpat_unsignedCharToPrintable #define XML_DefaultCurrent PyExpat_XML_DefaultCurrent #define XML_ErrorString PyExpat_XML_ErrorString #define XML_ExpatVersion PyExpat_XML_ExpatVersion @@ -81,6 +84,8 @@ #define XML_ResumeParser PyExpat_XML_ResumeParser #define XML_SetAttlistDeclHandler PyExpat_XML_SetAttlistDeclHandler #define XML_SetBase PyExpat_XML_SetBase +#define XML_SetBillionLaughsAttackProtectionActivationThreshold PyExpat_XML_SetBillionLaughsAttackProtectionActivationThreshold +#define XML_SetBillionLaughsAttackProtectionMaximumAmplification PyExpat_XML_SetBillionLaughsAttackProtectionMaximumAmplification #define XML_SetCdataSectionHandler PyExpat_XML_SetCdataSectionHandler #define XML_SetCharacterDataHandler PyExpat_XML_SetCharacterDataHandler #define XML_SetCommentHandler PyExpat_XML_SetCommentHandler From webhook-mailer at python.org Tue Mar 8 05:03:57 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 08 Mar 2022 10:03:57 -0000 Subject: [Python-checkins] bpo-44439: _ZipWriteFile.write() handle buffer protocol correctly (GH-29468) Message-ID: https://github.com/python/cpython/commit/21c5b3f73fb11fb0d3239971f72e8f0574a07245 commit: 21c5b3f73fb11fb0d3239971f72e8f0574a07245 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-08T02:03:12-08:00 summary: bpo-44439: _ZipWriteFile.write() handle buffer protocol correctly (GH-29468) Co-authored-by: Marco Ribeiro (cherry picked from commit 36dd7396fcd26d8bf9919d536d05d7000becbe5b) Co-authored-by: Ma Lin files: A Misc/NEWS.d/next/Library/2021-11-08-20-27-41.bpo-44439.I_8qro.rst M Lib/test/test_zipfile.py M Lib/zipfile.py diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index bfc981c0d15d3..6e06ee6a60043 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -1,3 +1,4 @@ +import array import contextlib import importlib.util import io @@ -1119,6 +1120,14 @@ def test_write_after_close(self): self.assertRaises(ValueError, w.write, b'') self.assertEqual(zipf.read('test'), data) + def test_issue44439(self): + q = array.array('Q', [1, 2, 3, 4, 5]) + LENGTH = len(q) * q.itemsize + with zipfile.ZipFile(io.BytesIO(), 'w', self.compression) as zip: + with zip.open('data', 'w') as data: + self.assertEqual(data.write(q), LENGTH) + self.assertEqual(zip.getinfo('data').file_size, LENGTH) + class StoredWriterTests(AbstractWriterTests, unittest.TestCase): compression = zipfile.ZIP_STORED diff --git a/Lib/zipfile.py b/Lib/zipfile.py index d99c0d7697775..67cfdfb6aafc4 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -1121,8 +1121,15 @@ def writable(self): def write(self, data): if self.closed: raise ValueError('I/O operation on closed file.') - nbytes = len(data) + + # Accept any data that supports the buffer protocol + if isinstance(data, (bytes, bytearray)): + nbytes = len(data) + else: + data = memoryview(data) + nbytes = data.nbytes self._file_size += nbytes + self._crc = crc32(data, self._crc) if self._compressor: data = self._compressor.compress(data) diff --git a/Misc/NEWS.d/next/Library/2021-11-08-20-27-41.bpo-44439.I_8qro.rst b/Misc/NEWS.d/next/Library/2021-11-08-20-27-41.bpo-44439.I_8qro.rst new file mode 100644 index 0000000000000..f4e562c4236d2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-11-08-20-27-41.bpo-44439.I_8qro.rst @@ -0,0 +1,2 @@ +Fix ``.write()`` method of a member file in ``ZipFile``, when the input data is +an object that supports the buffer protocol, the file length may be wrong. From webhook-mailer at python.org Tue Mar 8 05:05:05 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 08 Mar 2022 10:05:05 -0000 Subject: [Python-checkins] bpo-44439: _ZipWriteFile.write() handle buffer protocol correctly (GH-29468) Message-ID: https://github.com/python/cpython/commit/0663ca17f5535178c083c6734fa52e40bd2db2de commit: 0663ca17f5535178c083c6734fa52e40bd2db2de branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-08T02:04:54-08:00 summary: bpo-44439: _ZipWriteFile.write() handle buffer protocol correctly (GH-29468) Co-authored-by: Marco Ribeiro (cherry picked from commit 36dd7396fcd26d8bf9919d536d05d7000becbe5b) Co-authored-by: Ma Lin files: A Misc/NEWS.d/next/Library/2021-11-08-20-27-41.bpo-44439.I_8qro.rst M Lib/test/test_zipfile.py M Lib/zipfile.py diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index 999197a0e32dc..bd383d3f68552 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -1,3 +1,4 @@ +import array import contextlib import importlib.util import io @@ -1117,6 +1118,14 @@ def test_write_after_close(self): self.assertRaises(ValueError, w.write, b'') self.assertEqual(zipf.read('test'), data) + def test_issue44439(self): + q = array.array('Q', [1, 2, 3, 4, 5]) + LENGTH = len(q) * q.itemsize + with zipfile.ZipFile(io.BytesIO(), 'w', self.compression) as zip: + with zip.open('data', 'w') as data: + self.assertEqual(data.write(q), LENGTH) + self.assertEqual(zip.getinfo('data').file_size, LENGTH) + class StoredWriterTests(AbstractWriterTests, unittest.TestCase): compression = zipfile.ZIP_STORED diff --git a/Lib/zipfile.py b/Lib/zipfile.py index 816f8582bbf6d..f72c6a4e0c253 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -1120,8 +1120,15 @@ def writable(self): def write(self, data): if self.closed: raise ValueError('I/O operation on closed file.') - nbytes = len(data) + + # Accept any data that supports the buffer protocol + if isinstance(data, (bytes, bytearray)): + nbytes = len(data) + else: + data = memoryview(data) + nbytes = data.nbytes self._file_size += nbytes + self._crc = crc32(data, self._crc) if self._compressor: data = self._compressor.compress(data) diff --git a/Misc/NEWS.d/next/Library/2021-11-08-20-27-41.bpo-44439.I_8qro.rst b/Misc/NEWS.d/next/Library/2021-11-08-20-27-41.bpo-44439.I_8qro.rst new file mode 100644 index 0000000000000..f4e562c4236d2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-11-08-20-27-41.bpo-44439.I_8qro.rst @@ -0,0 +1,2 @@ +Fix ``.write()`` method of a member file in ``ZipFile``, when the input data is +an object that supports the buffer protocol, the file length may be wrong. From webhook-mailer at python.org Tue Mar 8 06:18:22 2022 From: webhook-mailer at python.org (tiran) Date: Tue, 08 Mar 2022 11:18:22 -0000 Subject: [Python-checkins] bpo-40280: Block more non-working syscalls in Emscripten (GH-31757) Message-ID: https://github.com/python/cpython/commit/5081e78efde901556398615eb477c63c836686e5 commit: 5081e78efde901556398615eb477c63c836686e5 branch: main author: Christian Heimes committer: tiran date: 2022-03-08T12:17:30+01:00 summary: bpo-40280: Block more non-working syscalls in Emscripten (GH-31757) - getgroups always fails. - geteuid and getegid always return 0 (root), which confuse tarfile and tests. - hardlinks (link, linkat) always fails. - non-encodable file names are not supported by NODERAWFS layer. - mark more tests with dependency on subprocess and multiprocessing. Mocking does not work if the module fails to import. files: M Lib/distutils/tests/test_file_util.py M Lib/test/support/os_helper.py M Lib/test/test_compileall.py M Lib/test/test_genericpath.py M Lib/test/test_os.py M Lib/test/test_posix.py M Lib/test/test_script_helper.py M Tools/wasm/config.site-wasm32-emscripten diff --git a/Lib/distutils/tests/test_file_util.py b/Lib/distutils/tests/test_file_util.py index a614219a10b1d..551151b014366 100644 --- a/Lib/distutils/tests/test_file_util.py +++ b/Lib/distutils/tests/test_file_util.py @@ -79,6 +79,7 @@ def test_move_file_exception_unpacking_unlink(self): fobj.write('spam eggs') move_file(self.source, self.target, verbose=0) + @unittest.skipUnless(hasattr(os, 'link'), 'requires os.link') def test_copy_file_hard_link(self): with open(self.source, 'w') as f: f.write('some content') @@ -99,6 +100,7 @@ def test_copy_file_hard_link(self): with open(self.source, 'r') as f: self.assertEqual(f.read(), 'some content') + @unittest.skipUnless(hasattr(os, 'link'), 'requires os.link') def test_copy_file_hard_link_failure(self): # If hard linking fails, copy_file() falls back on copying file # (some special filesystems don't support hard linking even under diff --git a/Lib/test/support/os_helper.py b/Lib/test/support/os_helper.py index c761d7bd3d2b6..eee37ef0d5a71 100644 --- a/Lib/test/support/os_helper.py +++ b/Lib/test/support/os_helper.py @@ -49,8 +49,8 @@ 'encoding (%s). Unicode filename tests may not be effective' % (TESTFN_UNENCODABLE, sys.getfilesystemencoding())) TESTFN_UNENCODABLE = None -# Mac OS X denies unencodable filenames (invalid utf-8) -elif sys.platform != 'darwin': +# macOS and Emscripten deny unencodable filenames (invalid utf-8) +elif sys.platform not in {'darwin', 'emscripten'}: try: # ascii and utf-8 cannot encode the byte 0xff b'\xff'.decode(sys.getfilesystemencoding()) diff --git a/Lib/test/test_compileall.py b/Lib/test/test_compileall.py index e207cf8f1793b..98dab339caa1c 100644 --- a/Lib/test/test_compileall.py +++ b/Lib/test/test_compileall.py @@ -244,6 +244,7 @@ def test_compile_one_worker(self, compile_file_mock, pool_mock): self.assertFalse(pool_mock.called) self.assertTrue(compile_file_mock.called) + @skipUnless(_have_multiprocessing, "requires multiprocessing") @mock.patch('concurrent.futures.ProcessPoolExecutor', new=None) @mock.patch('compileall.compile_file') def test_compile_missing_multiprocessing(self, compile_file_mock): @@ -296,6 +297,7 @@ def test_ddir_only_one_worker(self): """Recursive compile_dir ddir= contains package paths; bpo39769.""" return self._test_ddir_only(ddir="", parallel=False) + @skipUnless(_have_multiprocessing, "requires multiprocessing") def test_ddir_multiple_workers(self): """Recursive compile_dir ddir= contains package paths; bpo39769.""" return self._test_ddir_only(ddir="", parallel=True) @@ -304,6 +306,7 @@ def test_ddir_empty_only_one_worker(self): """Recursive compile_dir ddir='' contains package paths; bpo39769.""" return self._test_ddir_only(ddir="", parallel=False) + @skipUnless(_have_multiprocessing, "requires multiprocessing") def test_ddir_empty_multiple_workers(self): """Recursive compile_dir ddir='' contains package paths; bpo39769.""" return self._test_ddir_only(ddir="", parallel=True) @@ -924,6 +927,7 @@ class CommandLineTestsNoSourceEpoch(CommandLineTestsBase, + at unittest.skipUnless(hasattr(os, 'link'), 'requires os.link') class HardlinkDedupTestsBase: # Test hardlink_dupes parameter of compileall.compile_dir() diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py index 1ff7f75ad3e61..2741adc139bcf 100644 --- a/Lib/test/test_genericpath.py +++ b/Lib/test/test_genericpath.py @@ -7,6 +7,7 @@ import sys import unittest import warnings +from test.support import is_emscripten from test.support import os_helper from test.support import warnings_helper from test.support.script_helper import assert_python_ok @@ -154,6 +155,7 @@ def test_exists(self): self.assertIs(self.pathmodule.lexists(bfilename + b'\x00'), False) @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") + @unittest.skipIf(is_emscripten, "Emscripten pipe fds have no stat") def test_exists_fd(self): r, w = os.pipe() try: @@ -246,6 +248,7 @@ def _test_samefile_on_link_func(self, func): def test_samefile_on_symlink(self): self._test_samefile_on_link_func(os.symlink) + @unittest.skipUnless(hasattr(os, 'link'), 'requires os.link') def test_samefile_on_link(self): try: self._test_samefile_on_link_func(os.link) @@ -288,6 +291,7 @@ def _test_samestat_on_link_func(self, func): def test_samestat_on_symlink(self): self._test_samestat_on_link_func(os.symlink) + @unittest.skipUnless(hasattr(os, 'link'), 'requires os.link') def test_samestat_on_link(self): try: self._test_samestat_on_link_func(os.link) @@ -476,11 +480,11 @@ def test_abspath_issue3426(self): def test_nonascii_abspath(self): if (os_helper.TESTFN_UNDECODABLE - # Mac OS X denies the creation of a directory with an invalid - # UTF-8 name. Windows allows creating a directory with an + # macOS and Emscripten deny the creation of a directory with an + # invalid UTF-8 name. Windows allows creating a directory with an # arbitrary bytes name, but fails to enter this directory # (when the bytes name is used). - and sys.platform not in ('win32', 'darwin')): + and sys.platform not in ('win32', 'darwin', 'emscripten')): name = os_helper.TESTFN_UNDECODABLE elif os_helper.TESTFN_NONASCII: name = os_helper.TESTFN_NONASCII diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 660691579c163..4800291023233 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -2203,6 +2203,7 @@ def test_blocking(self): self.check(os.set_blocking, True) + at unittest.skipUnless(hasattr(os, 'link'), 'requires os.link') class LinkTests(unittest.TestCase): def setUp(self): self.file1 = os_helper.TESTFN diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index eecddfed8c5c5..395f065234519 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -75,8 +75,9 @@ def testNoArgFunctions(self): for name in NO_ARG_FUNCTIONS: posix_func = getattr(posix, name, None) if posix_func is not None: - posix_func() - self.assertRaises(TypeError, posix_func, 1) + with self.subTest(name): + posix_func() + self.assertRaises(TypeError, posix_func, 1) @unittest.skipUnless(hasattr(posix, 'getresuid'), 'test needs posix.getresuid()') @@ -1399,7 +1400,10 @@ def test_utime_dir_fd(self): # whoops! using both together not supported on this platform. pass - @unittest.skipUnless(os.link in os.supports_dir_fd, "test needs dir_fd support in os.link()") + @unittest.skipUnless( + hasattr(os, "link") and os.link in os.supports_dir_fd, + "test needs dir_fd support in os.link()" + ) def test_link_dir_fd(self): with self.prepare_file() as (dir_fd, name, fullname), \ self.prepare() as (dir_fd2, linkname, fulllinkname): diff --git a/Lib/test/test_script_helper.py b/Lib/test/test_script_helper.py index 4ade2cbc0d4b1..f7871fd3b77c0 100644 --- a/Lib/test/test_script_helper.py +++ b/Lib/test/test_script_helper.py @@ -3,7 +3,7 @@ import subprocess import sys import os -from test.support import script_helper +from test.support import script_helper, requires_subprocess import unittest from unittest import mock @@ -69,6 +69,7 @@ def test_assert_python_not_isolated_when_env_is_required(self, mock_popen): self.assertNotIn('-E', popen_command) + at requires_subprocess() class TestScriptHelperEnvironment(unittest.TestCase): """Code coverage for interpreter_requires_environment().""" diff --git a/Tools/wasm/config.site-wasm32-emscripten b/Tools/wasm/config.site-wasm32-emscripten index 98991b462446f..f85024e21720f 100644 --- a/Tools/wasm/config.site-wasm32-emscripten +++ b/Tools/wasm/config.site-wasm32-emscripten @@ -86,11 +86,22 @@ ac_cv_func_mkfifoat=no ac_cv_func_mknod=no ac_cv_func_mknodat=no -# always fails with permission error +# always fails with permission or not implemented error +ac_cv_func_getgroups=no ac_cv_func_setgroups=no ac_cv_func_setresuid=no ac_cv_func_setresgid=no +# Emscripten geteuid() / getegid() always return 0 (root), which breaks +# assumption in tarfile module and some tests. +ac_cv_func_getegid=no +ac_cv_func_geteuid=no + +# Emscripten does not support hard links, always fails with errno 34 +# "Too many links". See emscripten_syscall_stubs.c +ac_cv_func_link=no +ac_cv_func_linkat=no + # alarm signal is not delivered, may need a callback into the event loop? ac_cv_func_alarm=no From webhook-mailer at python.org Tue Mar 8 10:30:26 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 08 Mar 2022 15:30:26 -0000 Subject: [Python-checkins] [3.10] bpo-46878: Purge 'non-standard' from sqlite3 docstrings (GH-31612) (GH-31753) Message-ID: https://github.com/python/cpython/commit/f3d3b2d5c5599272660f4bbd5103aa8abc7c48c4 commit: f3d3b2d5c5599272660f4bbd5103aa8abc7c48c4 branch: 3.10 author: Erlend Egeberg Aasland committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-08T07:30:14-08:00 summary: [3.10] bpo-46878: Purge 'non-standard' from sqlite3 docstrings (GH-31612) (GH-31753) (cherry picked from commit 4d95fa1ac5d31ff450fb2f31b55ce1eb99d6efcb) files: M Modules/_sqlite/clinic/connection.c.h M Modules/_sqlite/clinic/cursor.c.h M Modules/_sqlite/clinic/module.c.h M Modules/_sqlite/connection.c M Modules/_sqlite/cursor.c M Modules/_sqlite/module.c diff --git a/Modules/_sqlite/clinic/connection.c.h b/Modules/_sqlite/clinic/connection.c.h index 22aa8abf7c436..9ddce41e90df5 100644 --- a/Modules/_sqlite/clinic/connection.c.h +++ b/Modules/_sqlite/clinic/connection.c.h @@ -97,7 +97,7 @@ PyDoc_STRVAR(pysqlite_connection_create_function__doc__, "create_function($self, /, name, narg, func, *, deterministic=False)\n" "--\n" "\n" -"Creates a new function. Non-standard."); +"Creates a new function."); #define PYSQLITE_CONNECTION_CREATE_FUNCTION_METHODDEF \ {"create_function", (PyCFunction)(void(*)(void))pysqlite_connection_create_function, METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_create_function__doc__}, @@ -160,7 +160,7 @@ PyDoc_STRVAR(pysqlite_connection_create_aggregate__doc__, "create_aggregate($self, /, name, n_arg, aggregate_class)\n" "--\n" "\n" -"Creates a new aggregate. Non-standard."); +"Creates a new aggregate."); #define PYSQLITE_CONNECTION_CREATE_AGGREGATE_METHODDEF \ {"create_aggregate", (PyCFunction)(void(*)(void))pysqlite_connection_create_aggregate, METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_create_aggregate__doc__}, @@ -213,7 +213,7 @@ PyDoc_STRVAR(pysqlite_connection_set_authorizer__doc__, "set_authorizer($self, /, authorizer_callback)\n" "--\n" "\n" -"Sets authorizer callback. Non-standard."); +"Sets authorizer callback."); #define PYSQLITE_CONNECTION_SET_AUTHORIZER_METHODDEF \ {"set_authorizer", (PyCFunction)(void(*)(void))pysqlite_connection_set_authorizer, METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_set_authorizer__doc__}, @@ -246,7 +246,7 @@ PyDoc_STRVAR(pysqlite_connection_set_progress_handler__doc__, "set_progress_handler($self, /, progress_handler, n)\n" "--\n" "\n" -"Sets progress handler callback. Non-standard."); +"Sets progress handler callback."); #define PYSQLITE_CONNECTION_SET_PROGRESS_HANDLER_METHODDEF \ {"set_progress_handler", (PyCFunction)(void(*)(void))pysqlite_connection_set_progress_handler, METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_set_progress_handler__doc__}, @@ -285,9 +285,7 @@ PyDoc_STRVAR(pysqlite_connection_set_trace_callback__doc__, "set_trace_callback($self, /, trace_callback)\n" "--\n" "\n" -"Sets a trace callback called for each SQL statement (passed as unicode).\n" -"\n" -"Non-standard."); +"Sets a trace callback called for each SQL statement (passed as unicode)."); #define PYSQLITE_CONNECTION_SET_TRACE_CALLBACK_METHODDEF \ {"set_trace_callback", (PyCFunction)(void(*)(void))pysqlite_connection_set_trace_callback, METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_set_trace_callback__doc__}, @@ -322,7 +320,7 @@ PyDoc_STRVAR(pysqlite_connection_enable_load_extension__doc__, "enable_load_extension($self, enable, /)\n" "--\n" "\n" -"Enable dynamic loading of SQLite extension modules. Non-standard."); +"Enable dynamic loading of SQLite extension modules."); #define PYSQLITE_CONNECTION_ENABLE_LOAD_EXTENSION_METHODDEF \ {"enable_load_extension", (PyCFunction)pysqlite_connection_enable_load_extension, METH_O, pysqlite_connection_enable_load_extension__doc__}, @@ -355,7 +353,7 @@ PyDoc_STRVAR(pysqlite_connection_load_extension__doc__, "load_extension($self, name, /)\n" "--\n" "\n" -"Load SQLite extension module. Non-standard."); +"Load SQLite extension module."); #define PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF \ {"load_extension", (PyCFunction)pysqlite_connection_load_extension, METH_O, pysqlite_connection_load_extension__doc__}, @@ -395,7 +393,7 @@ PyDoc_STRVAR(pysqlite_connection_execute__doc__, "execute($self, sql, parameters=, /)\n" "--\n" "\n" -"Executes a SQL statement. Non-standard."); +"Executes an SQL statement."); #define PYSQLITE_CONNECTION_EXECUTE_METHODDEF \ {"execute", (PyCFunction)(void(*)(void))pysqlite_connection_execute, METH_FASTCALL, pysqlite_connection_execute__doc__}, @@ -437,7 +435,7 @@ PyDoc_STRVAR(pysqlite_connection_executemany__doc__, "executemany($self, sql, parameters, /)\n" "--\n" "\n" -"Repeatedly executes a SQL statement. Non-standard."); +"Repeatedly executes an SQL statement."); #define PYSQLITE_CONNECTION_EXECUTEMANY_METHODDEF \ {"executemany", (PyCFunction)(void(*)(void))pysqlite_connection_executemany, METH_FASTCALL, pysqlite_connection_executemany__doc__}, @@ -475,7 +473,7 @@ PyDoc_STRVAR(pysqlite_connection_executescript__doc__, "executescript($self, sql_script, /)\n" "--\n" "\n" -"Executes multiple SQL statements at once. Non-standard."); +"Executes multiple SQL statements at once."); #define PYSQLITE_CONNECTION_EXECUTESCRIPT_METHODDEF \ {"executescript", (PyCFunction)pysqlite_connection_executescript, METH_O, pysqlite_connection_executescript__doc__}, @@ -484,7 +482,7 @@ PyDoc_STRVAR(pysqlite_connection_interrupt__doc__, "interrupt($self, /)\n" "--\n" "\n" -"Abort any pending database operation. Non-standard."); +"Abort any pending database operation."); #define PYSQLITE_CONNECTION_INTERRUPT_METHODDEF \ {"interrupt", (PyCFunction)pysqlite_connection_interrupt, METH_NOARGS, pysqlite_connection_interrupt__doc__}, @@ -502,9 +500,7 @@ PyDoc_STRVAR(pysqlite_connection_iterdump__doc__, "iterdump($self, /)\n" "--\n" "\n" -"Returns iterator to the dump of the database in an SQL text format.\n" -"\n" -"Non-standard."); +"Returns iterator to the dump of the database in an SQL text format."); #define PYSQLITE_CONNECTION_ITERDUMP_METHODDEF \ {"iterdump", (PyCFunction)pysqlite_connection_iterdump, METH_NOARGS, pysqlite_connection_iterdump__doc__}, @@ -523,7 +519,7 @@ PyDoc_STRVAR(pysqlite_connection_backup__doc__, " sleep=0.25)\n" "--\n" "\n" -"Makes a backup of the database. Non-standard."); +"Makes a backup of the database."); #define PYSQLITE_CONNECTION_BACKUP_METHODDEF \ {"backup", (PyCFunction)(void(*)(void))pysqlite_connection_backup, METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_backup__doc__}, @@ -614,7 +610,7 @@ PyDoc_STRVAR(pysqlite_connection_create_collation__doc__, "create_collation($self, name, callback, /)\n" "--\n" "\n" -"Creates a collation function. Non-standard."); +"Creates a collation function."); #define PYSQLITE_CONNECTION_CREATE_COLLATION_METHODDEF \ {"create_collation", (PyCFunction)(void(*)(void))pysqlite_connection_create_collation, METH_FASTCALL, pysqlite_connection_create_collation__doc__}, @@ -710,4 +706,4 @@ pysqlite_connection_exit(pysqlite_Connection *self, PyObject *const *args, Py_ss #ifndef PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF #define PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF #endif /* !defined(PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF) */ -/*[clinic end generated code: output=6c40101de3ae46fc input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2f3f3406ba6b4d2e input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/cursor.c.h b/Modules/_sqlite/clinic/cursor.c.h index 7e0745f448f5f..cad0a9bf23b1c 100644 --- a/Modules/_sqlite/clinic/cursor.c.h +++ b/Modules/_sqlite/clinic/cursor.c.h @@ -114,7 +114,7 @@ PyDoc_STRVAR(pysqlite_cursor_executescript__doc__, "executescript($self, sql_script, /)\n" "--\n" "\n" -"Executes multiple SQL statements at once. Non-standard."); +"Executes multiple SQL statements at once."); #define PYSQLITE_CURSOR_EXECUTESCRIPT_METHODDEF \ {"executescript", (PyCFunction)pysqlite_cursor_executescript, METH_O, pysqlite_cursor_executescript__doc__}, @@ -259,4 +259,4 @@ pysqlite_cursor_close(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) { return pysqlite_cursor_close_impl(self); } -/*[clinic end generated code: output=c319842c7e7e4c51 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=cdd7e7a541ceb4d2 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/module.c.h b/Modules/_sqlite/clinic/module.c.h index fb1e1187b209f..2118cb7c42429 100644 --- a/Modules/_sqlite/clinic/module.c.h +++ b/Modules/_sqlite/clinic/module.c.h @@ -6,7 +6,7 @@ PyDoc_STRVAR(pysqlite_complete_statement__doc__, "complete_statement($module, /, statement)\n" "--\n" "\n" -"Checks if a string contains a complete SQL statement. Non-standard."); +"Checks if a string contains a complete SQL statement."); #define PYSQLITE_COMPLETE_STATEMENT_METHODDEF \ {"complete_statement", (PyCFunction)(void(*)(void))pysqlite_complete_statement, METH_FASTCALL|METH_KEYWORDS, pysqlite_complete_statement__doc__}, @@ -52,7 +52,10 @@ PyDoc_STRVAR(pysqlite_enable_shared_cache__doc__, "\n" "Enable or disable shared cache mode for the calling thread.\n" "\n" -"Experimental/Non-standard."); +"This method is deprecated and will be removed in Python 3.12.\n" +"Shared cache is strongly discouraged by the SQLite 3 documentation.\n" +"If shared cache must be used, open the database in URI mode using\n" +"the cache=shared query parameter."); #define PYSQLITE_ENABLE_SHARED_CACHE_METHODDEF \ {"enable_shared_cache", (PyCFunction)(void(*)(void))pysqlite_enable_shared_cache, METH_FASTCALL|METH_KEYWORDS, pysqlite_enable_shared_cache__doc__}, @@ -87,7 +90,7 @@ PyDoc_STRVAR(pysqlite_register_adapter__doc__, "register_adapter($module, type, caster, /)\n" "--\n" "\n" -"Registers an adapter with pysqlite\'s adapter registry. Non-standard."); +"Registers an adapter with sqlite3\'s adapter registry."); #define PYSQLITE_REGISTER_ADAPTER_METHODDEF \ {"register_adapter", (PyCFunction)(void(*)(void))pysqlite_register_adapter, METH_FASTCALL, pysqlite_register_adapter__doc__}, @@ -118,7 +121,7 @@ PyDoc_STRVAR(pysqlite_register_converter__doc__, "register_converter($module, name, converter, /)\n" "--\n" "\n" -"Registers a converter with pysqlite. Non-standard."); +"Registers a converter with sqlite3."); #define PYSQLITE_REGISTER_CONVERTER_METHODDEF \ {"register_converter", (PyCFunction)(void(*)(void))pysqlite_register_converter, METH_FASTCALL, pysqlite_register_converter__doc__}, @@ -184,7 +187,7 @@ PyDoc_STRVAR(pysqlite_adapt__doc__, "adapt($module, obj, proto=PrepareProtocolType, alt=, /)\n" "--\n" "\n" -"Adapt given object to given protocol. Non-standard."); +"Adapt given object to given protocol."); #define PYSQLITE_ADAPT_METHODDEF \ {"adapt", (PyCFunction)(void(*)(void))pysqlite_adapt, METH_FASTCALL, pysqlite_adapt__doc__}, @@ -219,4 +222,4 @@ pysqlite_adapt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=d87990f941c209fa input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6939849a4371122d input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index b669160128691..c9c10b41398e2 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -890,14 +890,14 @@ _sqlite3.Connection.create_function as pysqlite_connection_create_function * deterministic: bool = False -Creates a new function. Non-standard. +Creates a new function. [clinic start generated code]*/ static PyObject * pysqlite_connection_create_function_impl(pysqlite_Connection *self, const char *name, int narg, PyObject *func, int deterministic) -/*[clinic end generated code: output=07d1877dd98c0308 input=f2edcf073e815beb]*/ +/*[clinic end generated code: output=07d1877dd98c0308 input=17e16b285ee44819]*/ { int rc; int flags = SQLITE_UTF8; @@ -945,14 +945,14 @@ _sqlite3.Connection.create_aggregate as pysqlite_connection_create_aggregate n_arg: int aggregate_class: object -Creates a new aggregate. Non-standard. +Creates a new aggregate. [clinic start generated code]*/ static PyObject * pysqlite_connection_create_aggregate_impl(pysqlite_Connection *self, const char *name, int n_arg, PyObject *aggregate_class) -/*[clinic end generated code: output=fbb2f858cfa4d8db input=c2e13bbf234500a5]*/ +/*[clinic end generated code: output=fbb2f858cfa4d8db input=a17afd1fcc930ecf]*/ { int rc; @@ -1095,13 +1095,13 @@ _sqlite3.Connection.set_authorizer as pysqlite_connection_set_authorizer authorizer_callback as authorizer_cb: object -Sets authorizer callback. Non-standard. +Sets authorizer callback. [clinic start generated code]*/ static PyObject * pysqlite_connection_set_authorizer_impl(pysqlite_Connection *self, PyObject *authorizer_cb) -/*[clinic end generated code: output=f18ba575d788b35c input=df079724c020d2f2]*/ +/*[clinic end generated code: output=f18ba575d788b35c input=446676a87c949d68]*/ { int rc; @@ -1127,14 +1127,14 @@ _sqlite3.Connection.set_progress_handler as pysqlite_connection_set_progress_han progress_handler: object n: int -Sets progress handler callback. Non-standard. +Sets progress handler callback. [clinic start generated code]*/ static PyObject * pysqlite_connection_set_progress_handler_impl(pysqlite_Connection *self, PyObject *progress_handler, int n) -/*[clinic end generated code: output=35a7c10364cb1b04 input=857696c25f964c64]*/ +/*[clinic end generated code: output=35a7c10364cb1b04 input=d9379b629c7391c7]*/ { if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; @@ -1158,14 +1158,12 @@ _sqlite3.Connection.set_trace_callback as pysqlite_connection_set_trace_callback trace_callback: object Sets a trace callback called for each SQL statement (passed as unicode). - -Non-standard. [clinic start generated code]*/ static PyObject * pysqlite_connection_set_trace_callback_impl(pysqlite_Connection *self, PyObject *trace_callback) -/*[clinic end generated code: output=fb0e307b9924d454 input=56d60fd38d763679]*/ +/*[clinic end generated code: output=fb0e307b9924d454 input=885e460ebbf79f0c]*/ { if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; @@ -1205,13 +1203,13 @@ _sqlite3.Connection.enable_load_extension as pysqlite_connection_enable_load_ext enable as onoff: bool(accept={int}) / -Enable dynamic loading of SQLite extension modules. Non-standard. +Enable dynamic loading of SQLite extension modules. [clinic start generated code]*/ static PyObject * pysqlite_connection_enable_load_extension_impl(pysqlite_Connection *self, int onoff) -/*[clinic end generated code: output=9cac37190d388baf input=5c0da5b121121cbc]*/ +/*[clinic end generated code: output=9cac37190d388baf input=5f00e93f7a9d3540]*/ { int rc; @@ -1240,13 +1238,13 @@ _sqlite3.Connection.load_extension as pysqlite_connection_load_extension name as extension_name: str / -Load SQLite extension module. Non-standard. +Load SQLite extension module. [clinic start generated code]*/ static PyObject * pysqlite_connection_load_extension_impl(pysqlite_Connection *self, const char *extension_name) -/*[clinic end generated code: output=47eb1d7312bc97a7 input=0b711574560db9fc]*/ +/*[clinic end generated code: output=47eb1d7312bc97a7 input=edd507389d89d621]*/ { int rc; char* errmsg; @@ -1417,13 +1415,13 @@ _sqlite3.Connection.execute as pysqlite_connection_execute parameters: object = NULL / -Executes a SQL statement. Non-standard. +Executes an SQL statement. [clinic start generated code]*/ static PyObject * pysqlite_connection_execute_impl(pysqlite_Connection *self, PyObject *sql, PyObject *parameters) -/*[clinic end generated code: output=5be05ae01ee17ee4 input=fbd17c75c7140271]*/ +/*[clinic end generated code: output=5be05ae01ee17ee4 input=27aa7792681ddba2]*/ { _Py_IDENTIFIER(execute); PyObject* cursor = 0; @@ -1452,13 +1450,13 @@ _sqlite3.Connection.executemany as pysqlite_connection_executemany parameters: object / -Repeatedly executes a SQL statement. Non-standard. +Repeatedly executes an SQL statement. [clinic start generated code]*/ static PyObject * pysqlite_connection_executemany_impl(pysqlite_Connection *self, PyObject *sql, PyObject *parameters) -/*[clinic end generated code: output=776cd2fd20bfe71f input=4feab80659ffc82b]*/ +/*[clinic end generated code: output=776cd2fd20bfe71f input=495be76551d525db]*/ { _Py_IDENTIFIER(executemany); PyObject* cursor = 0; @@ -1487,13 +1485,13 @@ _sqlite3.Connection.executescript as pysqlite_connection_executescript sql_script as script_obj: object / -Executes multiple SQL statements at once. Non-standard. +Executes multiple SQL statements at once. [clinic start generated code]*/ static PyObject * pysqlite_connection_executescript(pysqlite_Connection *self, PyObject *script_obj) -/*[clinic end generated code: output=4c4f9d77aa0ae37d input=b27ae5c24ffb8b43]*/ +/*[clinic end generated code: output=4c4f9d77aa0ae37d input=f6e5f1ccfa313db4]*/ { _Py_IDENTIFIER(executescript); PyObject* cursor = 0; @@ -1574,12 +1572,12 @@ pysqlite_collation_callback( /*[clinic input] _sqlite3.Connection.interrupt as pysqlite_connection_interrupt -Abort any pending database operation. Non-standard. +Abort any pending database operation. [clinic start generated code]*/ static PyObject * pysqlite_connection_interrupt_impl(pysqlite_Connection *self) -/*[clinic end generated code: output=f193204bc9e70b47 input=4bd0ad083cf93aa7]*/ +/*[clinic end generated code: output=f193204bc9e70b47 input=75ad03ade7012859]*/ { PyObject* retval = NULL; @@ -1603,13 +1601,11 @@ pysqlite_connection_interrupt_impl(pysqlite_Connection *self) _sqlite3.Connection.iterdump as pysqlite_connection_iterdump Returns iterator to the dump of the database in an SQL text format. - -Non-standard. [clinic start generated code]*/ static PyObject * pysqlite_connection_iterdump_impl(pysqlite_Connection *self) -/*[clinic end generated code: output=586997aaf9808768 input=53bc907cb5eedb85]*/ +/*[clinic end generated code: output=586997aaf9808768 input=1911ca756066da89]*/ { _Py_IDENTIFIER(_iterdump); PyObject* retval = NULL; @@ -1657,7 +1653,7 @@ _sqlite3.Connection.backup as pysqlite_connection_backup name: str = "main" sleep: double = 0.250 -Makes a backup of the database. Non-standard. +Makes a backup of the database. [clinic start generated code]*/ static PyObject * @@ -1665,7 +1661,7 @@ pysqlite_connection_backup_impl(pysqlite_Connection *self, pysqlite_Connection *target, int pages, PyObject *progress, const char *name, double sleep) -/*[clinic end generated code: output=306a3e6a38c36334 input=30ae45fc420bfd3b]*/ +/*[clinic end generated code: output=306a3e6a38c36334 input=458a0b6997c4960b]*/ { int rc; int sleep_ms = (int)(sleep * 1000.0); @@ -1762,13 +1758,13 @@ _sqlite3.Connection.create_collation as pysqlite_connection_create_collation callback as callable: object / -Creates a collation function. Non-standard. +Creates a collation function. [clinic start generated code]*/ static PyObject * pysqlite_connection_create_collation_impl(pysqlite_Connection *self, PyObject *name, PyObject *callable) -/*[clinic end generated code: output=0f63b8995565ae22 input=5c3898813a776cf2]*/ +/*[clinic end generated code: output=0f63b8995565ae22 input=eb2c4328dc493ee8]*/ { PyObject* uppercase_name = 0; Py_ssize_t i, len; diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 36f63863cc1f8..d06392a7a47dc 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -685,12 +685,12 @@ _sqlite3.Cursor.executescript as pysqlite_cursor_executescript sql_script as script_obj: object / -Executes multiple SQL statements at once. Non-standard. +Executes multiple SQL statements at once. [clinic start generated code]*/ static PyObject * pysqlite_cursor_executescript(pysqlite_Cursor *self, PyObject *script_obj) -/*[clinic end generated code: output=115a8132b0f200fe input=ba3ec59df205e362]*/ +/*[clinic end generated code: output=115a8132b0f200fe input=75270e5bcdb4d6aa]*/ { _Py_IDENTIFIER(commit); const char* script_cstr; diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index ba70a6c51f440..8cff4e224d57c 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -105,12 +105,12 @@ _sqlite3.complete_statement as pysqlite_complete_statement statement: str -Checks if a string contains a complete SQL statement. Non-standard. +Checks if a string contains a complete SQL statement. [clinic start generated code]*/ static PyObject * pysqlite_complete_statement_impl(PyObject *module, const char *statement) -/*[clinic end generated code: output=e55f1ff1952df558 input=f6b24996b31c5c33]*/ +/*[clinic end generated code: output=e55f1ff1952df558 input=ac45d257375bb828]*/ { if (sqlite3_complete(statement)) { return Py_NewRef(Py_True); @@ -126,12 +126,15 @@ _sqlite3.enable_shared_cache as pysqlite_enable_shared_cache Enable or disable shared cache mode for the calling thread. -Experimental/Non-standard. +This method is deprecated and will be removed in Python 3.12. +Shared cache is strongly discouraged by the SQLite 3 documentation. +If shared cache must be used, open the database in URI mode using +the cache=shared query parameter. [clinic start generated code]*/ static PyObject * pysqlite_enable_shared_cache_impl(PyObject *module, int do_enable) -/*[clinic end generated code: output=259c74eedee1516b input=8400e41bc58b6b24]*/ +/*[clinic end generated code: output=259c74eedee1516b input=26e40d5971d3487d]*/ { int rc; @@ -152,13 +155,13 @@ _sqlite3.register_adapter as pysqlite_register_adapter caster: object / -Registers an adapter with pysqlite's adapter registry. Non-standard. +Registers an adapter with sqlite3's adapter registry. [clinic start generated code]*/ static PyObject * pysqlite_register_adapter_impl(PyObject *module, PyTypeObject *type, PyObject *caster) -/*[clinic end generated code: output=a287e8db18e8af23 input=839dad90e2492725]*/ +/*[clinic end generated code: output=a287e8db18e8af23 input=b4bd87afcadc535d]*/ { int rc; @@ -183,13 +186,13 @@ _sqlite3.register_converter as pysqlite_register_converter converter as callable: object / -Registers a converter with pysqlite. Non-standard. +Registers a converter with sqlite3. [clinic start generated code]*/ static PyObject * pysqlite_register_converter_impl(PyObject *module, PyObject *orig_name, PyObject *callable) -/*[clinic end generated code: output=a2f2bfeed7230062 input=e074cf7f4890544f]*/ +/*[clinic end generated code: output=a2f2bfeed7230062 input=90f645419425d6c4]*/ { PyObject* name = NULL; PyObject* retval = NULL; @@ -237,13 +240,13 @@ _sqlite3.adapt as pysqlite_adapt alt: object = NULL / -Adapt given object to given protocol. Non-standard. +Adapt given object to given protocol. [clinic start generated code]*/ static PyObject * pysqlite_adapt_impl(PyObject *module, PyObject *obj, PyObject *proto, PyObject *alt) -/*[clinic end generated code: output=0c3927c5fcd23dd9 input=a58ab77fb5ae22dd]*/ +/*[clinic end generated code: output=0c3927c5fcd23dd9 input=46ca9564710ba48a]*/ { return pysqlite_microprotocols_adapt(obj, proto, alt); } From webhook-mailer at python.org Tue Mar 8 10:31:13 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 08 Mar 2022 15:31:13 -0000 Subject: [Python-checkins] [3.9] bpo-46878: Purge 'non-standard' from sqlite3 docstrings (GH-31612) (GH-31754) Message-ID: https://github.com/python/cpython/commit/653ca6c62b0c3272310f7fa5ce9c6939e3c41d91 commit: 653ca6c62b0c3272310f7fa5ce9c6939e3c41d91 branch: 3.9 author: Erlend Egeberg Aasland committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-08T07:31:06-08:00 summary: [3.9] bpo-46878: Purge 'non-standard' from sqlite3 docstrings (GH-31612) (GH-31754) (cherry picked from commit 4d95fa1ac5d31ff450fb2f31b55ce1eb99d6efcb) files: M Modules/_sqlite/connection.c M Modules/_sqlite/cursor.c M Modules/_sqlite/microprotocols.h M Modules/_sqlite/module.c diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 90327376cc0d4..67688e8753790 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1837,41 +1837,41 @@ static PyMethodDef connection_methods[] = { {"rollback", (PyCFunction)pysqlite_connection_rollback, METH_NOARGS, PyDoc_STR("Roll back the current transaction.")}, {"create_function", (PyCFunction)(void(*)(void))pysqlite_connection_create_function, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("Creates a new function. Non-standard.")}, + PyDoc_STR("Creates a new function.")}, {"create_aggregate", (PyCFunction)(void(*)(void))pysqlite_connection_create_aggregate, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("Creates a new aggregate. Non-standard.")}, + PyDoc_STR("Creates a new aggregate.")}, {"set_authorizer", (PyCFunction)(void(*)(void))pysqlite_connection_set_authorizer, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("Sets authorizer callback. Non-standard.")}, + PyDoc_STR("Sets authorizer callback.")}, #ifdef HAVE_LOAD_EXTENSION {"enable_load_extension", (PyCFunction)pysqlite_enable_load_extension, METH_VARARGS, - PyDoc_STR("Enable dynamic loading of SQLite extension modules. Non-standard.")}, + PyDoc_STR("Enable dynamic loading of SQLite extension modules.")}, {"load_extension", (PyCFunction)pysqlite_load_extension, METH_VARARGS, - PyDoc_STR("Load SQLite extension module. Non-standard.")}, + PyDoc_STR("Load SQLite extension module.")}, #endif {"set_progress_handler", (PyCFunction)(void(*)(void))pysqlite_connection_set_progress_handler, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("Sets progress handler callback. Non-standard.")}, + PyDoc_STR("Sets progress handler callback.")}, {"set_trace_callback", (PyCFunction)(void(*)(void))pysqlite_connection_set_trace_callback, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("Sets a trace callback called for each SQL statement (passed as unicode). Non-standard.")}, + PyDoc_STR("Sets a trace callback called for each SQL statement (passed as unicode).")}, {"execute", (PyCFunction)pysqlite_connection_execute, METH_VARARGS, - PyDoc_STR("Executes a SQL statement. Non-standard.")}, + PyDoc_STR("Executes an SQL statement.")}, {"executemany", (PyCFunction)pysqlite_connection_executemany, METH_VARARGS, - PyDoc_STR("Repeatedly executes a SQL statement. Non-standard.")}, + PyDoc_STR("Repeatedly executes an SQL statement.")}, {"executescript", (PyCFunction)pysqlite_connection_executescript, METH_VARARGS, - PyDoc_STR("Executes a multiple SQL statements at once. Non-standard.")}, + PyDoc_STR("Executes a multiple SQL statements at once.")}, {"create_collation", (PyCFunction)pysqlite_connection_create_collation, METH_VARARGS, - PyDoc_STR("Creates a collation function. Non-standard.")}, + PyDoc_STR("Creates a collation function.")}, {"interrupt", (PyCFunction)pysqlite_connection_interrupt, METH_NOARGS, - PyDoc_STR("Abort any pending database operation. Non-standard.")}, + PyDoc_STR("Abort any pending database operation.")}, {"iterdump", (PyCFunction)pysqlite_connection_iterdump, METH_NOARGS, - PyDoc_STR("Returns iterator to the dump of the database in an SQL text format. Non-standard.")}, + PyDoc_STR("Returns iterator to the dump of the database in an SQL text format.")}, #ifdef HAVE_BACKUP_API {"backup", (PyCFunction)(void(*)(void))pysqlite_connection_backup, METH_VARARGS | METH_KEYWORDS, - PyDoc_STR("Makes a backup of the database. Non-standard.")}, + PyDoc_STR("Makes a backup of the database.")}, #endif {"__enter__", (PyCFunction)pysqlite_connection_enter, METH_NOARGS, - PyDoc_STR("For context manager. Non-standard.")}, + PyDoc_STR("For context manager.")}, {"__exit__", (PyCFunction)pysqlite_connection_exit, METH_VARARGS, - PyDoc_STR("For context manager. Non-standard.")}, + PyDoc_STR("For context manager.")}, {NULL, NULL} }; diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index dd0ce7e1ea6a3..c6d5a9a2af897 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -882,7 +882,7 @@ static PyMethodDef cursor_methods[] = { {"executemany", (PyCFunction)pysqlite_cursor_executemany, METH_VARARGS, PyDoc_STR("Repeatedly executes a SQL statement.")}, {"executescript", (PyCFunction)pysqlite_cursor_executescript, METH_VARARGS, - PyDoc_STR("Executes a multiple SQL statements at once. Non-standard.")}, + PyDoc_STR("Executes a multiple SQL statements at once.")}, {"fetchone", (PyCFunction)pysqlite_cursor_fetchone, METH_NOARGS, PyDoc_STR("Fetches one row from the resultset.")}, {"fetchmany", (PyCFunction)(void(*)(void))pysqlite_cursor_fetchmany, METH_VARARGS|METH_KEYWORDS, diff --git a/Modules/_sqlite/microprotocols.h b/Modules/_sqlite/microprotocols.h index 5418c2b98fd75..68c18d9355a6f 100644 --- a/Modules/_sqlite/microprotocols.h +++ b/Modules/_sqlite/microprotocols.h @@ -47,6 +47,6 @@ extern PyObject *pysqlite_microprotocols_adapt( extern PyObject * pysqlite_adapt(pysqlite_Cursor* self, PyObject *args); #define pysqlite_adapt_doc \ - "adapt(obj, protocol, alternate) -> adapt obj to given protocol. Non-standard." + "adapt(obj, protocol, alternate) -> adapt obj to given protocol." #endif /* !defined(PSYCOPG_MICROPROTOCOLS_H) */ diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index 44811835d42fc..98909369e755a 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -121,7 +121,7 @@ static PyObject* module_complete(PyObject* self, PyObject* args, PyObject* PyDoc_STRVAR(module_complete_doc, "complete_statement(sql)\n\ \n\ -Checks if a string contains a complete SQL statement. Non-standard."); +Checks if a string contains a complete SQL statement."); #ifdef HAVE_SHARED_CACHE static PyObject* module_enable_shared_cache(PyObject* self, PyObject* args, PyObject* @@ -149,8 +149,7 @@ static PyObject* module_enable_shared_cache(PyObject* self, PyObject* args, PyOb PyDoc_STRVAR(module_enable_shared_cache_doc, "enable_shared_cache(do_enable)\n\ \n\ -Enable or disable shared cache mode for the calling thread.\n\ -Experimental/Non-standard."); +Enable or disable shared cache mode for the calling thread."); #endif /* HAVE_SHARED_CACHE */ static PyObject* module_register_adapter(PyObject* self, PyObject* args) @@ -180,7 +179,7 @@ static PyObject* module_register_adapter(PyObject* self, PyObject* args) PyDoc_STRVAR(module_register_adapter_doc, "register_adapter(type, callable)\n\ \n\ -Registers an adapter with pysqlite's adapter registry. Non-standard."); +Registers an adapter with sqlite3's adapter registry."); static PyObject* module_register_converter(PyObject* self, PyObject* args) { @@ -214,7 +213,7 @@ static PyObject* module_register_converter(PyObject* self, PyObject* args) PyDoc_STRVAR(module_register_converter_doc, "register_converter(typename, callable)\n\ \n\ -Registers a converter with pysqlite. Non-standard."); +Registers a converter with sqlite3."); static PyObject* enable_callback_tracebacks(PyObject* self, PyObject* args) { From webhook-mailer at python.org Tue Mar 8 10:43:03 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Tue, 08 Mar 2022 15:43:03 -0000 Subject: [Python-checkins] [3.10] docs: Don't use code formatting for emphasis (GH-30519) (GH-31764) Message-ID: https://github.com/python/cpython/commit/5d2b9c9fe45643ba379277aea883276165499117 commit: 5d2b9c9fe45643ba379277aea883276165499117 branch: 3.10 author: Jelle Zijlstra committer: JelleZijlstra date: 2022-03-08T07:42:54-08:00 summary: [3.10] docs: Don't use code formatting for emphasis (GH-30519) (GH-31764) (cherry picked from commit badb637c8ce91625122d5f4d71276bfe1a8ed5e9) Co-authored-by: William Andrea files: M Doc/tutorial/controlflow.rst diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index 589263edd3571..f6e013b23e7e5 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -884,7 +884,7 @@ zero or more normal arguments may occur. :: file.write(separator.join(args)) -Normally, these ``variadic`` arguments will be last in the list of formal +Normally, these *variadic* arguments will be last in the list of formal parameters, because they scoop up all remaining input arguments that are passed to the function. Any formal parameters which occur after the ``*args`` parameter are 'keyword-only' arguments, meaning that they can only be used as From webhook-mailer at python.org Tue Mar 8 10:43:32 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Tue, 08 Mar 2022 15:43:32 -0000 Subject: [Python-checkins] Removed confusing reference to sys (GH-31638) Message-ID: https://github.com/python/cpython/commit/28f84c72b6cee145f9c00e9b999656e9a2517e49 commit: 28f84c72b6cee145f9c00e9b999656e9a2517e49 branch: main author: David Gilbertson committer: JelleZijlstra date: 2022-03-08T07:43:27-08:00 summary: Removed confusing reference to sys (GH-31638) files: M Doc/reference/import.rst diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst index 69e2a94727449..66737c698ae90 100644 --- a/Doc/reference/import.rst +++ b/Doc/reference/import.rst @@ -84,9 +84,9 @@ considered a package. All modules have a name. Subpackage names are separated from their parent package name by a dot, akin to Python's standard attribute access syntax. Thus -you might have a module called :mod:`sys` and a package called :mod:`email`, -which in turn has a subpackage called :mod:`email.mime` and a module within -that subpackage called :mod:`email.mime.text`. +you might have a package called :mod:`email`, which in turn has a subpackage +called :mod:`email.mime` and a module within that subpackage called +:mod:`email.mime.text`. Regular packages From webhook-mailer at python.org Tue Mar 8 10:53:52 2022 From: webhook-mailer at python.org (markshannon) Date: Tue, 08 Mar 2022 15:53:52 -0000 Subject: [Python-checkins] bpo-46841: Don't use an oparg counter for `STORE_SUBSCR` (GH-31742) Message-ID: https://github.com/python/cpython/commit/5498a61c7c25db6f9e76032aa9c5153d79e09889 commit: 5498a61c7c25db6f9e76032aa9c5153d79e09889 branch: main author: Brandt Bucher committer: markshannon date: 2022-03-08T15:53:22Z summary: bpo-46841: Don't use an oparg counter for `STORE_SUBSCR` (GH-31742) files: A Misc/NEWS.d/next/Core and Builtins/2022-03-07-15-54-39.bpo-46841.7wG92r.rst M Include/internal/pycore_code.h M Include/opcode.h M Lib/importlib/_bootstrap_external.py M Lib/opcode.py M Python/ceval.c M Python/specialize.c diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index 21c657afed6c8..0d324e9e4c0f5 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -86,6 +86,12 @@ typedef struct { #define INLINE_CACHE_ENTRIES_PRECALL CACHE_ENTRIES(_PyPrecallCache) +typedef struct { + _Py_CODEUNIT counter; +} _PyStoreSubscrCache; + +#define INLINE_CACHE_ENTRIES_STORE_SUBSCR CACHE_ENTRIES(_PyStoreSubscrCache) + /* Maximum size of code to quicken, in code units. */ #define MAX_SIZE_TO_QUICKEN 10000 diff --git a/Include/opcode.h b/Include/opcode.h index 930a975897e29..7bf0ba70fd7de 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -211,6 +211,7 @@ static const uint32_t _PyOpcode_Jump[8] = { const uint8_t _PyOpcode_InlineCacheEntries[256] = { [BINARY_SUBSCR] = 4, + [STORE_SUBSCR] = 1, [UNPACK_SEQUENCE] = 1, [STORE_ATTR] = 4, [LOAD_ATTR] = 4, diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 32a41f852e5d7..a6f0a1b3c4c7d 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -394,6 +394,7 @@ def _write_atomic(path, data, mode=0o666): # STORE_ATTR) # Python 3.11a5 3485 (Add an oparg to GET_AWAITABLE) # Python 3.11a6 3486 (Use inline caching for PRECALL and CALL) +# Python 3.11a6 3487 (Remove the adaptive "oparg counter" mechanism) # Python 3.12 will start with magic number 3500 @@ -408,7 +409,7 @@ def _write_atomic(path, data, mode=0o666): # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array # in PC/launcher.c must also be updated. -MAGIC_NUMBER = (3486).to_bytes(2, 'little') + b'\r\n' +MAGIC_NUMBER = (3487).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c _PYCACHE = '__pycache__' diff --git a/Lib/opcode.py b/Lib/opcode.py index a31a77a61c8af..eb9dd35fabf8d 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -84,7 +84,7 @@ def jabs_op(name, op, entries=0): def_op('BEFORE_WITH', 53) def_op('END_ASYNC_FOR', 54) -def_op('STORE_SUBSCR', 60) +def_op('STORE_SUBSCR', 60, 1) def_op('DELETE_SUBSCR', 61) def_op('GET_ITER', 68) diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-07-15-54-39.bpo-46841.7wG92r.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-07-15-54-39.bpo-46841.7wG92r.rst new file mode 100644 index 0000000000000..f863c75f715ee --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-07-15-54-39.bpo-46841.7wG92r.rst @@ -0,0 +1,2 @@ +Modify :opcode:`STORE_SUBSCR` to use an inline cache entry (rather than its +oparg) as an adaptive counter. diff --git a/Python/ceval.c b/Python/ceval.c index b15c1015cd242..83309e2c5219a 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2267,13 +2267,16 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int Py_DECREF(v); Py_DECREF(container); Py_DECREF(sub); - if (err != 0) + if (err != 0) { goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_STORE_SUBSCR); DISPATCH(); } TARGET(STORE_SUBSCR_ADAPTIVE) { - if (oparg == 0) { + _PyStoreSubscrCache *cache = (_PyStoreSubscrCache *)next_instr; + if (cache->counter == 0) { PyObject *sub = TOP(); PyObject *container = SECOND(); next_instr--; @@ -2284,8 +2287,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } else { STAT_INC(STORE_SUBSCR, deferred); - // oparg is the adaptive cache counter - UPDATE_PREV_INSTR_OPARG(next_instr, oparg - 1); + cache->counter--; JUMP_TO_INSTRUCTION(STORE_SUBSCR); } } @@ -2312,6 +2314,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int Py_DECREF(old_value); Py_DECREF(sub); Py_DECREF(list); + JUMPBY(INLINE_CACHE_ENTRIES_STORE_SUBSCR); NOTRACE_DISPATCH(); } @@ -2328,6 +2331,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int if (err != 0) { goto error; } + JUMPBY(INLINE_CACHE_ENTRIES_STORE_SUBSCR); DISPATCH(); } @@ -5520,21 +5524,6 @@ opname ## _miss: \ JUMP_TO_INSTRUCTION(opname); \ } -#define MISS_WITH_OPARG_COUNTER(opname) \ -opname ## _miss: \ - { \ - STAT_INC(opname, miss); \ - uint8_t oparg = _Py_OPARG(next_instr[-1])-1; \ - UPDATE_PREV_INSTR_OPARG(next_instr, oparg); \ - assert(_Py_OPARG(next_instr[-1]) == oparg); \ - if (oparg == 0) /* too many cache misses */ { \ - oparg = ADAPTIVE_CACHE_BACKOFF; \ - next_instr[-1] = _Py_MAKECODEUNIT(opname ## _ADAPTIVE, oparg); \ - STAT_INC(opname, deopt); \ - } \ - JUMP_TO_INSTRUCTION(opname); \ - } - MISS_WITH_INLINE_CACHE(LOAD_ATTR) MISS_WITH_INLINE_CACHE(STORE_ATTR) MISS_WITH_INLINE_CACHE(LOAD_GLOBAL) @@ -5545,7 +5534,7 @@ MISS_WITH_INLINE_CACHE(BINARY_OP) MISS_WITH_INLINE_CACHE(COMPARE_OP) MISS_WITH_INLINE_CACHE(BINARY_SUBSCR) MISS_WITH_INLINE_CACHE(UNPACK_SEQUENCE) -MISS_WITH_OPARG_COUNTER(STORE_SUBSCR) +MISS_WITH_INLINE_CACHE(STORE_SUBSCR) binary_subscr_dict_error: { diff --git a/Python/specialize.c b/Python/specialize.c index dae4e3fa188bd..a11a76c4ef118 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -301,12 +301,11 @@ optimize(_Py_CODEUNIT *instructions, int len) uint8_t adaptive_opcode = adaptive_opcodes[opcode]; if (adaptive_opcode) { instructions[i] = _Py_MAKECODEUNIT(adaptive_opcode, oparg); - int caches = _PyOpcode_InlineCacheEntries[opcode]; // Make sure the adaptive counter is zero: - assert((caches ? instructions[i + 1] : oparg) == 0); + assert(instructions[i + 1] == 0); previous_opcode = -1; previous_oparg = -1; - i += caches; + i += _PyOpcode_InlineCacheEntries[opcode]; } else { assert(!_PyOpcode_InlineCacheEntries[opcode]); @@ -1313,6 +1312,7 @@ _Py_Specialize_BinarySubscr( int _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *instr) { + _PyStoreSubscrCache *cache = (_PyStoreSubscrCache *)(instr + 1); PyTypeObject *container_type = Py_TYPE(container); if (container_type == &PyList_Type) { if (PyLong_CheckExact(sub)) { @@ -1320,7 +1320,7 @@ _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *ins && ((PyLongObject *)sub)->ob_digit[0] < (size_t)PyList_GET_SIZE(container)) { *instr = _Py_MAKECODEUNIT(STORE_SUBSCR_LIST_INT, - initial_counter_value()); + _Py_OPARG(*instr)); goto success; } else { @@ -1338,8 +1338,7 @@ _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *ins } } if (container_type == &PyDict_Type) { - *instr = _Py_MAKECODEUNIT(STORE_SUBSCR_DICT, - initial_counter_value()); + *instr = _Py_MAKECODEUNIT(STORE_SUBSCR_DICT, _Py_OPARG(*instr)); goto success; } #ifdef Py_STATS @@ -1406,11 +1405,12 @@ _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *ins fail: STAT_INC(STORE_SUBSCR, failure); assert(!PyErr_Occurred()); - *instr = _Py_MAKECODEUNIT(_Py_OPCODE(*instr), ADAPTIVE_CACHE_BACKOFF); + cache->counter = ADAPTIVE_CACHE_BACKOFF; return 0; success: STAT_INC(STORE_SUBSCR, success); assert(!PyErr_Occurred()); + cache->counter = initial_counter_value(); return 0; } From webhook-mailer at python.org Tue Mar 8 11:05:14 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 08 Mar 2022 16:05:14 -0000 Subject: [Python-checkins] Removed confusing reference to sys (GH-31638) Message-ID: https://github.com/python/cpython/commit/ef54c4df8283349603406a9274580556e7cc4bef commit: ef54c4df8283349603406a9274580556e7cc4bef branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-08T08:04:56-08:00 summary: Removed confusing reference to sys (GH-31638) (cherry picked from commit 28f84c72b6cee145f9c00e9b999656e9a2517e49) Co-authored-by: David Gilbertson files: M Doc/reference/import.rst diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst index 9834f957ea9f6..c01535d8049df 100644 --- a/Doc/reference/import.rst +++ b/Doc/reference/import.rst @@ -84,9 +84,9 @@ considered a package. All modules have a name. Subpackage names are separated from their parent package name by a dot, akin to Python's standard attribute access syntax. Thus -you might have a module called :mod:`sys` and a package called :mod:`email`, -which in turn has a subpackage called :mod:`email.mime` and a module within -that subpackage called :mod:`email.mime.text`. +you might have a package called :mod:`email`, which in turn has a subpackage +called :mod:`email.mime` and a module within that subpackage called +:mod:`email.mime.text`. Regular packages From webhook-mailer at python.org Tue Mar 8 11:08:35 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 08 Mar 2022 16:08:35 -0000 Subject: [Python-checkins] Removed confusing reference to sys (GH-31638) Message-ID: https://github.com/python/cpython/commit/f8c3697aca55b64dec4bd3012f40bc96dcf76a77 commit: f8c3697aca55b64dec4bd3012f40bc96dcf76a77 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-08T08:08:24-08:00 summary: Removed confusing reference to sys (GH-31638) (cherry picked from commit 28f84c72b6cee145f9c00e9b999656e9a2517e49) Co-authored-by: David Gilbertson files: M Doc/reference/import.rst diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst index c5952426fdcf8..2c84a97a26775 100644 --- a/Doc/reference/import.rst +++ b/Doc/reference/import.rst @@ -84,9 +84,9 @@ considered a package. All modules have a name. Subpackage names are separated from their parent package name by a dot, akin to Python's standard attribute access syntax. Thus -you might have a module called :mod:`sys` and a package called :mod:`email`, -which in turn has a subpackage called :mod:`email.mime` and a module within -that subpackage called :mod:`email.mime.text`. +you might have a package called :mod:`email`, which in turn has a subpackage +called :mod:`email.mime` and a module within that subpackage called +:mod:`email.mime.text`. Regular packages From webhook-mailer at python.org Tue Mar 8 13:22:49 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 08 Mar 2022 18:22:49 -0000 Subject: [Python-checkins] bpo-23325: Fix SIG_IGN and SIG_DFL int comparison in signal module (GH-31759) Message-ID: https://github.com/python/cpython/commit/c8a47e76a391c8818bf10a282cdcd3bb5c23ebf6 commit: c8a47e76a391c8818bf10a282cdcd3bb5c23ebf6 branch: main author: Christian Heimes committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-08T10:22:32-08:00 summary: bpo-23325: Fix SIG_IGN and SIG_DFL int comparison in signal module (GH-31759) files: A Misc/NEWS.d/next/Library/2022-03-08-11-34-06.bpo-23325.3VQnfo.rst M Modules/signalmodule.c diff --git a/Misc/NEWS.d/next/Library/2022-03-08-11-34-06.bpo-23325.3VQnfo.rst b/Misc/NEWS.d/next/Library/2022-03-08-11-34-06.bpo-23325.3VQnfo.rst new file mode 100644 index 0000000000000..0801cbb448225 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-08-11-34-06.bpo-23325.3VQnfo.rst @@ -0,0 +1,2 @@ +The :mod:`signal` module no longer assumes that :const:`~signal.SIG_IGN` and +:const:`~signal.SIG_DFL` are small int singletons. diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 26a1f48470ed2..9566263a0dd87 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -177,6 +177,17 @@ get_signal_state(PyObject *module) } +static inline int +compare_handler(PyObject *func, PyObject *dfl_ign_handler) +{ + assert(PyLong_CheckExact(dfl_ign_handler)); + if (!PyLong_CheckExact(func)) { + return 0; + } + // Assume that comparison of two PyLong objects will never fail. + return PyObject_RichCompareBool(func, dfl_ign_handler, Py_EQ) == 1; +} + #ifdef HAVE_GETITIMER /* auxiliary functions for setitimer */ static int @@ -528,21 +539,18 @@ signal_signal_impl(PyObject *module, int signalnum, PyObject *handler) "signal number out of range"); return NULL; } - if (handler == modstate->ignore_handler) { + if (PyCallable_Check(handler)) { + func = signal_handler; + } else if (compare_handler(handler, modstate->ignore_handler)) { func = SIG_IGN; - } - else if (handler == modstate->default_handler) { + } else if (compare_handler(handler, modstate->default_handler)) { func = SIG_DFL; - } - else if (!PyCallable_Check(handler)) { + } else { _PyErr_SetString(tstate, PyExc_TypeError, "signal handler must be signal.SIG_IGN, " "signal.SIG_DFL, or a callable object"); return NULL; } - else { - func = signal_handler; - } /* Check for pending signals before changing signal handler */ if (_PyErr_CheckSignalsTstate(tstate)) { @@ -1752,8 +1760,8 @@ _PySignal_Fini(void) set_handler(signum, NULL); if (func != NULL && func != Py_None - && func != state->default_handler - && func != state->ignore_handler) + && !compare_handler(func, state->default_handler) + && !compare_handler(func, state->ignore_handler)) { PyOS_setsig(signum, SIG_DFL); } @@ -1824,8 +1832,9 @@ _PyErr_CheckSignalsTstate(PyThreadState *tstate) * (see bpo-43406). */ PyObject *func = get_handler(i); - if (func == NULL || func == Py_None || func == state->ignore_handler || - func == state->default_handler) { + if (func == NULL || func == Py_None || + compare_handler(func, state->ignore_handler) || + compare_handler(func, state->default_handler)) { /* No Python signal handler due to aforementioned race condition. * We can't call raise() as it would break the assumption * that PyErr_SetInterrupt() only *simulates* an incoming @@ -1893,7 +1902,8 @@ PyErr_SetInterruptEx(int signum) signal_state_t *state = &signal_global_state; PyObject *func = get_handler(signum); - if (func != state->ignore_handler && func != state->default_handler) { + if (!compare_handler(func, state->ignore_handler) + && !compare_handler(func, state->default_handler)) { trip_signal(signum); } return 0; From webhook-mailer at python.org Tue Mar 8 13:53:33 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 08 Mar 2022 18:53:33 -0000 Subject: [Python-checkins] bpo-23325: Fix SIG_IGN and SIG_DFL int comparison in signal module (GH-31759) Message-ID: https://github.com/python/cpython/commit/95b001fe6766f491f4356f8bcf23d6895bab2342 commit: 95b001fe6766f491f4356f8bcf23d6895bab2342 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-08T10:53:24-08:00 summary: bpo-23325: Fix SIG_IGN and SIG_DFL int comparison in signal module (GH-31759) (cherry picked from commit c8a47e76a391c8818bf10a282cdcd3bb5c23ebf6) Co-authored-by: Christian Heimes files: A Misc/NEWS.d/next/Library/2022-03-08-11-34-06.bpo-23325.3VQnfo.rst M Modules/signalmodule.c diff --git a/Misc/NEWS.d/next/Library/2022-03-08-11-34-06.bpo-23325.3VQnfo.rst b/Misc/NEWS.d/next/Library/2022-03-08-11-34-06.bpo-23325.3VQnfo.rst new file mode 100644 index 0000000000000..0801cbb448225 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-08-11-34-06.bpo-23325.3VQnfo.rst @@ -0,0 +1,2 @@ +The :mod:`signal` module no longer assumes that :const:`~signal.SIG_IGN` and +:const:`~signal.SIG_DFL` are small int singletons. diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 96881d4a49f10..c3a5237bce434 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -174,6 +174,17 @@ get_signal_state(PyObject *module) } +static inline int +compare_handler(PyObject *func, PyObject *dfl_ign_handler) +{ + assert(PyLong_CheckExact(dfl_ign_handler)); + if (!PyLong_CheckExact(func)) { + return 0; + } + // Assume that comparison of two PyLong objects will never fail. + return PyObject_RichCompareBool(func, dfl_ign_handler, Py_EQ) == 1; +} + #ifdef HAVE_GETITIMER /* auxiliary functions for setitimer */ static int @@ -525,21 +536,18 @@ signal_signal_impl(PyObject *module, int signalnum, PyObject *handler) "signal number out of range"); return NULL; } - if (handler == modstate->ignore_handler) { + if (PyCallable_Check(handler)) { + func = signal_handler; + } else if (compare_handler(handler, modstate->ignore_handler)) { func = SIG_IGN; - } - else if (handler == modstate->default_handler) { + } else if (compare_handler(handler, modstate->default_handler)) { func = SIG_DFL; - } - else if (!PyCallable_Check(handler)) { + } else { _PyErr_SetString(tstate, PyExc_TypeError, "signal handler must be signal.SIG_IGN, " "signal.SIG_DFL, or a callable object"); return NULL; } - else { - func = signal_handler; - } /* Check for pending signals before changing signal handler */ if (_PyErr_CheckSignalsTstate(tstate)) { @@ -1736,8 +1744,8 @@ _PySignal_Fini(void) set_handler(signum, NULL); if (func != NULL && func != Py_None - && func != state->default_handler - && func != state->ignore_handler) + && !compare_handler(func, state->default_handler) + && !compare_handler(func, state->ignore_handler)) { PyOS_setsig(signum, SIG_DFL); } @@ -1812,8 +1820,9 @@ _PyErr_CheckSignalsTstate(PyThreadState *tstate) * (see bpo-43406). */ PyObject *func = get_handler(i); - if (func == NULL || func == Py_None || func == state->ignore_handler || - func == state->default_handler) { + if (func == NULL || func == Py_None || + compare_handler(func, state->ignore_handler) || + compare_handler(func, state->default_handler)) { /* No Python signal handler due to aforementioned race condition. * We can't call raise() as it would break the assumption * that PyErr_SetInterrupt() only *simulates* an incoming @@ -1873,7 +1882,8 @@ PyErr_SetInterruptEx(int signum) signal_state_t *state = &signal_global_state; PyObject *func = get_handler(signum); - if (func != state->ignore_handler && func != state->default_handler) { + if (!compare_handler(func, state->ignore_handler) + && !compare_handler(func, state->default_handler)) { trip_signal(signum); } return 0; From webhook-mailer at python.org Tue Mar 8 16:07:43 2022 From: webhook-mailer at python.org (asvetlov) Date: Tue, 08 Mar 2022 21:07:43 -0000 Subject: [Python-checkins] bpo-46955: Expose asyncio.base_events.Server as asyncio.Server (GH-31760) Message-ID: https://github.com/python/cpython/commit/da80d6b2f3beff519cb1457d5e055168c89f7224 commit: da80d6b2f3beff519cb1457d5e055168c89f7224 branch: main author: Stefan Zabka committer: asvetlov date: 2022-03-08T23:07:33+02:00 summary: bpo-46955: Expose asyncio.base_events.Server as asyncio.Server (GH-31760) This change aligns the documentation at https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.Server with the actual implementation Co-authored-by: Andrew Svetlov files: A Misc/NEWS.d/next/Library/2022-03-08-22-41-59.bpo-46955.IOoonN.rst M Lib/asyncio/base_events.py diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index f9215c5e0182a..51c4e664d74e9 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -49,7 +49,7 @@ from .log import logger -__all__ = 'BaseEventLoop', +__all__ = 'BaseEventLoop','Server', # Minimum number of _scheduled timer handles before cleanup of diff --git a/Misc/NEWS.d/next/Library/2022-03-08-22-41-59.bpo-46955.IOoonN.rst b/Misc/NEWS.d/next/Library/2022-03-08-22-41-59.bpo-46955.IOoonN.rst new file mode 100644 index 0000000000000..75fee1240d3cd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-08-22-41-59.bpo-46955.IOoonN.rst @@ -0,0 +1,2 @@ +Expose :class:`asyncio.base_events.Server` as :class:`asyncio.Server`. Patch +by Stefan Zabka. From webhook-mailer at python.org Tue Mar 8 16:33:18 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 08 Mar 2022 21:33:18 -0000 Subject: [Python-checkins] bpo-46955: Expose asyncio.base_events.Server as asyncio.Server (GH-31760) Message-ID: https://github.com/python/cpython/commit/20e88f78a39ff56235c1d42ba4b947f5fa8e67b7 commit: 20e88f78a39ff56235c1d42ba4b947f5fa8e67b7 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-08T13:32:46-08:00 summary: bpo-46955: Expose asyncio.base_events.Server as asyncio.Server (GH-31760) This change aligns the documentation at https://docs.python.org/3/library/asyncio-eventloop.htmlGH-asyncio.Server with the actual implementation Co-authored-by: Andrew Svetlov (cherry picked from commit da80d6b2f3beff519cb1457d5e055168c89f7224) Co-authored-by: Stefan Zabka files: A Misc/NEWS.d/next/Library/2022-03-08-22-41-59.bpo-46955.IOoonN.rst M Lib/asyncio/base_events.py diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 8a380bb80ea06..7a14e5e139f02 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -49,7 +49,7 @@ from .log import logger -__all__ = 'BaseEventLoop', +__all__ = 'BaseEventLoop','Server', # Minimum number of _scheduled timer handles before cleanup of diff --git a/Misc/NEWS.d/next/Library/2022-03-08-22-41-59.bpo-46955.IOoonN.rst b/Misc/NEWS.d/next/Library/2022-03-08-22-41-59.bpo-46955.IOoonN.rst new file mode 100644 index 0000000000000..75fee1240d3cd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-08-22-41-59.bpo-46955.IOoonN.rst @@ -0,0 +1,2 @@ +Expose :class:`asyncio.base_events.Server` as :class:`asyncio.Server`. Patch +by Stefan Zabka. From webhook-mailer at python.org Tue Mar 8 16:36:54 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 08 Mar 2022 21:36:54 -0000 Subject: [Python-checkins] bpo-46955: Expose asyncio.base_events.Server as asyncio.Server (GH-31760) Message-ID: https://github.com/python/cpython/commit/8de434b332ed92ba2db90de6ed0969aee23735c2 commit: 8de434b332ed92ba2db90de6ed0969aee23735c2 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-08T13:36:35-08:00 summary: bpo-46955: Expose asyncio.base_events.Server as asyncio.Server (GH-31760) This change aligns the documentation at https://docs.python.org/3/library/asyncio-eventloop.htmlGH-asyncio.Server with the actual implementation Co-authored-by: Andrew Svetlov (cherry picked from commit da80d6b2f3beff519cb1457d5e055168c89f7224) Co-authored-by: Stefan Zabka files: A Misc/NEWS.d/next/Library/2022-03-08-22-41-59.bpo-46955.IOoonN.rst M Lib/asyncio/base_events.py diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index f51613d3b7dfa..952da11064fef 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -49,7 +49,7 @@ from .log import logger -__all__ = 'BaseEventLoop', +__all__ = 'BaseEventLoop','Server', # Minimum number of _scheduled timer handles before cleanup of diff --git a/Misc/NEWS.d/next/Library/2022-03-08-22-41-59.bpo-46955.IOoonN.rst b/Misc/NEWS.d/next/Library/2022-03-08-22-41-59.bpo-46955.IOoonN.rst new file mode 100644 index 0000000000000..75fee1240d3cd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-08-22-41-59.bpo-46955.IOoonN.rst @@ -0,0 +1,2 @@ +Expose :class:`asyncio.base_events.Server` as :class:`asyncio.Server`. Patch +by Stefan Zabka. From webhook-mailer at python.org Tue Mar 8 16:44:04 2022 From: webhook-mailer at python.org (iritkatriel) Date: Tue, 08 Mar 2022 21:44:04 -0000 Subject: [Python-checkins] bpo-24959: fix unittest.assertRaises bug where traceback entries are dropped from chained exceptions (GH-23688) Message-ID: https://github.com/python/cpython/commit/88b7d86a73da9388aa65c96401c2984c8c16f8db commit: 88b7d86a73da9388aa65c96401c2984c8c16f8db branch: main author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-03-08T21:43:49Z summary: bpo-24959: fix unittest.assertRaises bug where traceback entries are dropped from chained exceptions (GH-23688) files: A Misc/NEWS.d/next/Library/2021-09-06-15-46-53.bpo-24959.UVFgiO.rst M Lib/unittest/result.py M Lib/unittest/test/test_result.py diff --git a/Lib/unittest/result.py b/Lib/unittest/result.py index ce7468e31481f..3da7005e603f4 100644 --- a/Lib/unittest/result.py +++ b/Lib/unittest/result.py @@ -173,18 +173,10 @@ def stop(self): def _exc_info_to_string(self, err, test): """Converts a sys.exc_info()-style tuple of values into a string.""" exctype, value, tb = err - # Skip test runner traceback levels - while tb and self._is_relevant_tb_level(tb): - tb = tb.tb_next - - if exctype is test.failureException: - # Skip assert*() traceback levels - length = self._count_relevant_tb_levels(tb) - else: - length = None + tb = self._clean_tracebacks(exctype, value, tb, test) tb_e = traceback.TracebackException( exctype, value, tb, - limit=length, capture_locals=self.tb_locals, compact=True) + capture_locals=self.tb_locals, compact=True) msgLines = list(tb_e.format()) if self.buffer: @@ -200,16 +192,49 @@ def _exc_info_to_string(self, err, test): msgLines.append(STDERR_LINE % error) return ''.join(msgLines) + def _clean_tracebacks(self, exctype, value, tb, test): + ret = None + first = True + excs = [(exctype, value, tb)] + while excs: + (exctype, value, tb) = excs.pop() + # Skip test runner traceback levels + while tb and self._is_relevant_tb_level(tb): + tb = tb.tb_next + + # Skip assert*() traceback levels + if exctype is test.failureException: + self._remove_unittest_tb_frames(tb) + + if first: + ret = tb + first = False + else: + value.__traceback__ = tb + + if value is not None: + for c in (value.__cause__, value.__context__): + if c is not None: + excs.append((type(c), c, c.__traceback__)) + return ret def _is_relevant_tb_level(self, tb): return '__unittest' in tb.tb_frame.f_globals - def _count_relevant_tb_levels(self, tb): - length = 0 + def _remove_unittest_tb_frames(self, tb): + '''Truncates usercode tb at the first unittest frame. + + If the first frame of the traceback is in user code, + the prefix up to the first unittest frame is returned. + If the first frame is already in the unittest module, + the traceback is not modified. + ''' + prev = None while tb and not self._is_relevant_tb_level(tb): - length += 1 + prev = tb tb = tb.tb_next - return length + if prev is not None: + prev.tb_next = None def __repr__(self): return ("<%s run=%i errors=%i failures=%i>" % diff --git a/Lib/unittest/test/test_result.py b/Lib/unittest/test/test_result.py index 224a78463edc9..c616f28dfee92 100644 --- a/Lib/unittest/test/test_result.py +++ b/Lib/unittest/test/test_result.py @@ -220,6 +220,61 @@ def test_1(self): self.assertIs(test_case, test) self.assertIsInstance(formatted_exc, str) + def test_addFailure_filter_traceback_frames(self): + class Foo(unittest.TestCase): + def test_1(self): + pass + + test = Foo('test_1') + def get_exc_info(): + try: + test.fail("foo") + except: + return sys.exc_info() + + exc_info_tuple = get_exc_info() + + full_exc = traceback.format_exception(*exc_info_tuple) + + result = unittest.TestResult() + result.startTest(test) + result.addFailure(test, exc_info_tuple) + result.stopTest(test) + + formatted_exc = result.failures[0][1] + dropped = [l for l in full_exc if l not in formatted_exc] + self.assertEqual(len(dropped), 1) + self.assertIn("raise self.failureException(msg)", dropped[0]) + + def test_addFailure_filter_traceback_frames_context(self): + class Foo(unittest.TestCase): + def test_1(self): + pass + + test = Foo('test_1') + def get_exc_info(): + try: + try: + test.fail("foo") + except: + raise ValueError(42) + except: + return sys.exc_info() + + exc_info_tuple = get_exc_info() + + full_exc = traceback.format_exception(*exc_info_tuple) + + result = unittest.TestResult() + result.startTest(test) + result.addFailure(test, exc_info_tuple) + result.stopTest(test) + + formatted_exc = result.failures[0][1] + dropped = [l for l in full_exc if l not in formatted_exc] + self.assertEqual(len(dropped), 1) + self.assertIn("raise self.failureException(msg)", dropped[0]) + # "addError(test, err)" # ... # "Called when the test case test raises an unexpected exception err diff --git a/Misc/NEWS.d/next/Library/2021-09-06-15-46-53.bpo-24959.UVFgiO.rst b/Misc/NEWS.d/next/Library/2021-09-06-15-46-53.bpo-24959.UVFgiO.rst new file mode 100644 index 0000000000000..b702986f9468a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-09-06-15-46-53.bpo-24959.UVFgiO.rst @@ -0,0 +1 @@ +Fix bug where :mod:`unittest` sometimes drops frames from tracebacks of exceptions raised in tests. From webhook-mailer at python.org Tue Mar 8 17:09:33 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 08 Mar 2022 22:09:33 -0000 Subject: [Python-checkins] bpo-24959: fix unittest.assertRaises bug where traceback entries are dropped from chained exceptions (GH-23688) Message-ID: https://github.com/python/cpython/commit/26fa25a9a73f0e31bf0f0d94103fa4de38c0a3cc commit: 26fa25a9a73f0e31bf0f0d94103fa4de38c0a3cc branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-08T14:09:28-08:00 summary: bpo-24959: fix unittest.assertRaises bug where traceback entries are dropped from chained exceptions (GH-23688) (cherry picked from commit 88b7d86a73da9388aa65c96401c2984c8c16f8db) Co-authored-by: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> files: A Misc/NEWS.d/next/Library/2021-09-06-15-46-53.bpo-24959.UVFgiO.rst M Lib/unittest/result.py M Lib/unittest/test/test_result.py diff --git a/Lib/unittest/result.py b/Lib/unittest/result.py index ce7468e31481f..3da7005e603f4 100644 --- a/Lib/unittest/result.py +++ b/Lib/unittest/result.py @@ -173,18 +173,10 @@ def stop(self): def _exc_info_to_string(self, err, test): """Converts a sys.exc_info()-style tuple of values into a string.""" exctype, value, tb = err - # Skip test runner traceback levels - while tb and self._is_relevant_tb_level(tb): - tb = tb.tb_next - - if exctype is test.failureException: - # Skip assert*() traceback levels - length = self._count_relevant_tb_levels(tb) - else: - length = None + tb = self._clean_tracebacks(exctype, value, tb, test) tb_e = traceback.TracebackException( exctype, value, tb, - limit=length, capture_locals=self.tb_locals, compact=True) + capture_locals=self.tb_locals, compact=True) msgLines = list(tb_e.format()) if self.buffer: @@ -200,16 +192,49 @@ def _exc_info_to_string(self, err, test): msgLines.append(STDERR_LINE % error) return ''.join(msgLines) + def _clean_tracebacks(self, exctype, value, tb, test): + ret = None + first = True + excs = [(exctype, value, tb)] + while excs: + (exctype, value, tb) = excs.pop() + # Skip test runner traceback levels + while tb and self._is_relevant_tb_level(tb): + tb = tb.tb_next + + # Skip assert*() traceback levels + if exctype is test.failureException: + self._remove_unittest_tb_frames(tb) + + if first: + ret = tb + first = False + else: + value.__traceback__ = tb + + if value is not None: + for c in (value.__cause__, value.__context__): + if c is not None: + excs.append((type(c), c, c.__traceback__)) + return ret def _is_relevant_tb_level(self, tb): return '__unittest' in tb.tb_frame.f_globals - def _count_relevant_tb_levels(self, tb): - length = 0 + def _remove_unittest_tb_frames(self, tb): + '''Truncates usercode tb at the first unittest frame. + + If the first frame of the traceback is in user code, + the prefix up to the first unittest frame is returned. + If the first frame is already in the unittest module, + the traceback is not modified. + ''' + prev = None while tb and not self._is_relevant_tb_level(tb): - length += 1 + prev = tb tb = tb.tb_next - return length + if prev is not None: + prev.tb_next = None def __repr__(self): return ("<%s run=%i errors=%i failures=%i>" % diff --git a/Lib/unittest/test/test_result.py b/Lib/unittest/test/test_result.py index 5416735f2923c..c5aaba0ff5253 100644 --- a/Lib/unittest/test/test_result.py +++ b/Lib/unittest/test/test_result.py @@ -220,6 +220,61 @@ def test_1(self): self.assertIs(test_case, test) self.assertIsInstance(formatted_exc, str) + def test_addFailure_filter_traceback_frames(self): + class Foo(unittest.TestCase): + def test_1(self): + pass + + test = Foo('test_1') + def get_exc_info(): + try: + test.fail("foo") + except: + return sys.exc_info() + + exc_info_tuple = get_exc_info() + + full_exc = traceback.format_exception(*exc_info_tuple) + + result = unittest.TestResult() + result.startTest(test) + result.addFailure(test, exc_info_tuple) + result.stopTest(test) + + formatted_exc = result.failures[0][1] + dropped = [l for l in full_exc if l not in formatted_exc] + self.assertEqual(len(dropped), 1) + self.assertIn("raise self.failureException(msg)", dropped[0]) + + def test_addFailure_filter_traceback_frames_context(self): + class Foo(unittest.TestCase): + def test_1(self): + pass + + test = Foo('test_1') + def get_exc_info(): + try: + try: + test.fail("foo") + except: + raise ValueError(42) + except: + return sys.exc_info() + + exc_info_tuple = get_exc_info() + + full_exc = traceback.format_exception(*exc_info_tuple) + + result = unittest.TestResult() + result.startTest(test) + result.addFailure(test, exc_info_tuple) + result.stopTest(test) + + formatted_exc = result.failures[0][1] + dropped = [l for l in full_exc if l not in formatted_exc] + self.assertEqual(len(dropped), 1) + self.assertIn("raise self.failureException(msg)", dropped[0]) + # "addError(test, err)" # ... # "Called when the test case test raises an unexpected exception err diff --git a/Misc/NEWS.d/next/Library/2021-09-06-15-46-53.bpo-24959.UVFgiO.rst b/Misc/NEWS.d/next/Library/2021-09-06-15-46-53.bpo-24959.UVFgiO.rst new file mode 100644 index 0000000000000..b702986f9468a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-09-06-15-46-53.bpo-24959.UVFgiO.rst @@ -0,0 +1 @@ +Fix bug where :mod:`unittest` sometimes drops frames from tracebacks of exceptions raised in tests. From webhook-mailer at python.org Tue Mar 8 17:15:30 2022 From: webhook-mailer at python.org (tiran) Date: Tue, 08 Mar 2022 22:15:30 -0000 Subject: [Python-checkins] bpo-40280: Skip dysfunctional pipe tests on Emscripten (GH-31770) Message-ID: https://github.com/python/cpython/commit/95ba723c54ab52487bc9f986b651536cfae15b29 commit: 95ba723c54ab52487bc9f986b651536cfae15b29 branch: main author: Christian Heimes committer: tiran date: 2022-03-08T23:15:26+01:00 summary: bpo-40280: Skip dysfunctional pipe tests on Emscripten (GH-31770) files: M Lib/test/test_io.py diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index e9abd153a3e8c..2d0ca878788f2 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -426,6 +426,9 @@ def test_invalid_operations(self): self.assertRaises(exc, fp.seek, 1, self.SEEK_CUR) self.assertRaises(exc, fp.seek, -1, self.SEEK_END) + @unittest.skipIf( + support.is_emscripten, "fstat() of a pipe fd is not supported" + ) def test_optional_abilities(self): # Test for OSError when optional APIs are not supported # The purpose of this test is to try fileno(), reading, writing and @@ -3971,6 +3974,9 @@ def test_removed_u_mode(self): self.open(os_helper.TESTFN, mode) self.assertIn('invalid mode', str(cm.exception)) + @unittest.skipIf( + support.is_emscripten, "fstat() of a pipe fd is not supported" + ) def test_open_pipe_with_append(self): # bpo-27805: Ignore ESPIPE from lseek() in open(). r, w = os.pipe() @@ -4134,9 +4140,15 @@ def test_pickling(self): with self.open(os_helper.TESTFN, **kwargs) as f: self.assertRaises(TypeError, pickle.dumps, f, protocol) + @unittest.skipIf( + support.is_emscripten, "fstat() of a pipe fd is not supported" + ) def test_nonblock_pipe_write_bigbuf(self): self._test_nonblock_pipe_write(16*1024) + @unittest.skipIf( + support.is_emscripten, "fstat() of a pipe fd is not supported" + ) def test_nonblock_pipe_write_smallbuf(self): self._test_nonblock_pipe_write(1024) From webhook-mailer at python.org Tue Mar 8 18:01:04 2022 From: webhook-mailer at python.org (iritkatriel) Date: Tue, 08 Mar 2022 23:01:04 -0000 Subject: [Python-checkins] bpo-24959: fix unittest.assertRaises bug where traceback entries are dropped from chained exceptions (GH-23688) (GH-31776) Message-ID: https://github.com/python/cpython/commit/f3ea249569bbce8417c55d421521bb672c202552 commit: f3ea249569bbce8417c55d421521bb672c202552 branch: 3.9 author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-03-08T23:00:45Z summary: bpo-24959: fix unittest.assertRaises bug where traceback entries are dropped from chained exceptions (GH-23688) (GH-31776) (cherry picked from commit 88b7d86a73da9388aa65c96401c2984c8c16f8db) files: A Misc/NEWS.d/next/Library/2021-09-06-15-46-53.bpo-24959.UVFgiO.rst M Lib/unittest/result.py M Lib/unittest/test/test_result.py diff --git a/Lib/unittest/result.py b/Lib/unittest/result.py index 111317b329a85..528d223850e90 100644 --- a/Lib/unittest/result.py +++ b/Lib/unittest/result.py @@ -173,17 +173,9 @@ def stop(self): def _exc_info_to_string(self, err, test): """Converts a sys.exc_info()-style tuple of values into a string.""" exctype, value, tb = err - # Skip test runner traceback levels - while tb and self._is_relevant_tb_level(tb): - tb = tb.tb_next - - if exctype is test.failureException: - # Skip assert*() traceback levels - length = self._count_relevant_tb_levels(tb) - else: - length = None + tb = self._clean_tracebacks(exctype, value, tb, test) tb_e = traceback.TracebackException( - exctype, value, tb, limit=length, capture_locals=self.tb_locals) + exctype, value, tb, capture_locals=self.tb_locals) msgLines = list(tb_e.format()) if self.buffer: @@ -199,16 +191,49 @@ def _exc_info_to_string(self, err, test): msgLines.append(STDERR_LINE % error) return ''.join(msgLines) + def _clean_tracebacks(self, exctype, value, tb, test): + ret = None + first = True + excs = [(exctype, value, tb)] + while excs: + (exctype, value, tb) = excs.pop() + # Skip test runner traceback levels + while tb and self._is_relevant_tb_level(tb): + tb = tb.tb_next + + # Skip assert*() traceback levels + if exctype is test.failureException: + self._remove_unittest_tb_frames(tb) + + if first: + ret = tb + first = False + else: + value.__traceback__ = tb + + if value is not None: + for c in (value.__cause__, value.__context__): + if c is not None: + excs.append((type(c), c, c.__traceback__)) + return ret def _is_relevant_tb_level(self, tb): return '__unittest' in tb.tb_frame.f_globals - def _count_relevant_tb_levels(self, tb): - length = 0 + def _remove_unittest_tb_frames(self, tb): + '''Truncates usercode tb at the first unittest frame. + + If the first frame of the traceback is in user code, + the prefix up to the first unittest frame is returned. + If the first frame is already in the unittest module, + the traceback is not modified. + ''' + prev = None while tb and not self._is_relevant_tb_level(tb): - length += 1 + prev = tb tb = tb.tb_next - return length + if prev is not None: + prev.tb_next = None def __repr__(self): return ("<%s run=%i errors=%i failures=%i>" % diff --git a/Lib/unittest/test/test_result.py b/Lib/unittest/test/test_result.py index 2d29f79809d60..9f33d3bfe95e5 100644 --- a/Lib/unittest/test/test_result.py +++ b/Lib/unittest/test/test_result.py @@ -221,6 +221,61 @@ def test_1(self): self.assertIs(test_case, test) self.assertIsInstance(formatted_exc, str) + def test_addFailure_filter_traceback_frames(self): + class Foo(unittest.TestCase): + def test_1(self): + pass + + test = Foo('test_1') + def get_exc_info(): + try: + test.fail("foo") + except: + return sys.exc_info() + + exc_info_tuple = get_exc_info() + + full_exc = traceback.format_exception(*exc_info_tuple) + + result = unittest.TestResult() + result.startTest(test) + result.addFailure(test, exc_info_tuple) + result.stopTest(test) + + formatted_exc = result.failures[0][1] + dropped = [l for l in full_exc if l not in formatted_exc] + self.assertEqual(len(dropped), 1) + self.assertIn("raise self.failureException(msg)", dropped[0]) + + def test_addFailure_filter_traceback_frames_context(self): + class Foo(unittest.TestCase): + def test_1(self): + pass + + test = Foo('test_1') + def get_exc_info(): + try: + try: + test.fail("foo") + except: + raise ValueError(42) + except: + return sys.exc_info() + + exc_info_tuple = get_exc_info() + + full_exc = traceback.format_exception(*exc_info_tuple) + + result = unittest.TestResult() + result.startTest(test) + result.addFailure(test, exc_info_tuple) + result.stopTest(test) + + formatted_exc = result.failures[0][1] + dropped = [l for l in full_exc if l not in formatted_exc] + self.assertEqual(len(dropped), 1) + self.assertIn("raise self.failureException(msg)", dropped[0]) + # "addError(test, err)" # ... # "Called when the test case test raises an unexpected exception err diff --git a/Misc/NEWS.d/next/Library/2021-09-06-15-46-53.bpo-24959.UVFgiO.rst b/Misc/NEWS.d/next/Library/2021-09-06-15-46-53.bpo-24959.UVFgiO.rst new file mode 100644 index 0000000000000..b702986f9468a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-09-06-15-46-53.bpo-24959.UVFgiO.rst @@ -0,0 +1 @@ +Fix bug where :mod:`unittest` sometimes drops frames from tracebacks of exceptions raised in tests. From webhook-mailer at python.org Tue Mar 8 21:45:59 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Wed, 09 Mar 2022 02:45:59 -0000 Subject: [Python-checkins] Docstring: replace pysqlite with sqlite3 (GH-31758) Message-ID: https://github.com/python/cpython/commit/b33a1ae703338e09dc0af5fbfd8ffa01d3ff75da commit: b33a1ae703338e09dc0af5fbfd8ffa01d3ff75da branch: main author: Erlend Egeberg Aasland committer: JelleZijlstra date: 2022-03-08T18:45:48-08:00 summary: Docstring: replace pysqlite with sqlite3 (GH-31758) Replace two instances of "pysqlite" with "sqlite3" in sqlite3 docstrings. Also reword "is a no-op" to "does nothing" for clarity. files: M Doc/library/sqlite3.rst M Modules/_sqlite/clinic/cursor.c.h M Modules/_sqlite/cursor.c diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index d213933ba5827..c456905bc956c 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -836,11 +836,11 @@ Cursor Objects .. method:: setinputsizes(sizes) - Required by the DB-API. Is a no-op in :mod:`sqlite3`. + Required by the DB-API. Does nothing in :mod:`sqlite3`. .. method:: setoutputsize(size [, column]) - Required by the DB-API. Is a no-op in :mod:`sqlite3`. + Required by the DB-API. Does nothing in :mod:`sqlite3`. .. attribute:: rowcount diff --git a/Modules/_sqlite/clinic/cursor.c.h b/Modules/_sqlite/clinic/cursor.c.h index a8de7f216b2bb..03bdbb766e965 100644 --- a/Modules/_sqlite/clinic/cursor.c.h +++ b/Modules/_sqlite/clinic/cursor.c.h @@ -232,7 +232,7 @@ PyDoc_STRVAR(pysqlite_cursor_setinputsizes__doc__, "setinputsizes($self, sizes, /)\n" "--\n" "\n" -"Required by DB-API. Does nothing in pysqlite."); +"Required by DB-API. Does nothing in sqlite3."); #define PYSQLITE_CURSOR_SETINPUTSIZES_METHODDEF \ {"setinputsizes", (PyCFunction)pysqlite_cursor_setinputsizes, METH_O, pysqlite_cursor_setinputsizes__doc__}, @@ -241,7 +241,7 @@ PyDoc_STRVAR(pysqlite_cursor_setoutputsize__doc__, "setoutputsize($self, size, column=None, /)\n" "--\n" "\n" -"Required by DB-API. Does nothing in pysqlite."); +"Required by DB-API. Does nothing in sqlite3."); #define PYSQLITE_CURSOR_SETOUTPUTSIZE_METHODDEF \ {"setoutputsize", (PyCFunction)(void(*)(void))pysqlite_cursor_setoutputsize, METH_FASTCALL, pysqlite_cursor_setoutputsize__doc__}, @@ -289,4 +289,4 @@ pysqlite_cursor_close(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) { return pysqlite_cursor_close_impl(self); } -/*[clinic end generated code: output=ab1375c060ff7021 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1bee279bc861f6d3 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index c8e68218642e8..69beccd0f09dc 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -921,12 +921,12 @@ _sqlite3.Cursor.setinputsizes as pysqlite_cursor_setinputsizes sizes: object / -Required by DB-API. Does nothing in pysqlite. +Required by DB-API. Does nothing in sqlite3. [clinic start generated code]*/ static PyObject * pysqlite_cursor_setinputsizes(pysqlite_Cursor *self, PyObject *sizes) -/*[clinic end generated code: output=893c817afe9d08ad input=7cffbb168663bc69]*/ +/*[clinic end generated code: output=893c817afe9d08ad input=de7950a3aec79bdf]*/ { Py_RETURN_NONE; } @@ -938,13 +938,13 @@ _sqlite3.Cursor.setoutputsize as pysqlite_cursor_setoutputsize column: object = None / -Required by DB-API. Does nothing in pysqlite. +Required by DB-API. Does nothing in sqlite3. [clinic start generated code]*/ static PyObject * pysqlite_cursor_setoutputsize_impl(pysqlite_Cursor *self, PyObject *size, PyObject *column) -/*[clinic end generated code: output=018d7e9129d45efe input=077b017da58b9389]*/ +/*[clinic end generated code: output=018d7e9129d45efe input=607a6bece8bbb273]*/ { Py_RETURN_NONE; } From webhook-mailer at python.org Tue Mar 8 21:46:45 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Wed, 09 Mar 2022 02:46:45 -0000 Subject: [Python-checkins] bpo-45138: Expand traced SQL statements in `sqlite3` trace callback (GH-28240) Message-ID: https://github.com/python/cpython/commit/d1777515f9f53b452a4231d68196a7c0e5deb879 commit: d1777515f9f53b452a4231d68196a7c0e5deb879 branch: main author: Erlend Egeberg Aasland committer: JelleZijlstra date: 2022-03-08T18:46:40-08:00 summary: bpo-45138: Expand traced SQL statements in `sqlite3` trace callback (GH-28240) files: A Misc/NEWS.d/next/Library/2021-09-08-16-21-03.bpo-45138.yghUrK.rst M Doc/library/sqlite3.rst M Doc/whatsnew/3.11.rst M Lib/test/test_sqlite3/test_hooks.py M Modules/_sqlite/connection.c diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index c456905bc956c..296b188221a76 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -560,6 +560,9 @@ Connection Objects Passing :const:`None` as *trace_callback* will disable the trace callback. + For SQLite 3.14.0 and newer, bound parameters are expanded in the passed + statement string. + .. note:: Exceptions raised in the trace callback are not propagated. As a development and debugging aid, use @@ -568,6 +571,9 @@ Connection Objects .. versionadded:: 3.3 + .. versionchanged:: 3.11 + Added support for expanded SQL statements. + .. method:: enable_load_extension(enabled) diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 9b82de7f4a1a2..262c1eb2c9dab 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -322,6 +322,10 @@ sqlite3 Instead we leave it to the SQLite library to handle these cases. (Contributed by Erlend E. Aasland in :issue:`44092`.) +* For SQLite 3.14.0 and newer, bound parameters are expanded in the statement + string passed to the trace callback. See :meth:`~sqlite3.Connection.set_trace_callback`. + (Contributed by Erlend E. Aasland in :issue:`45138`.) + sys --- diff --git a/Lib/test/test_sqlite3/test_hooks.py b/Lib/test/test_sqlite3/test_hooks.py index d4790cfe77b7b..38126b605469a 100644 --- a/Lib/test/test_sqlite3/test_hooks.py +++ b/Lib/test/test_sqlite3/test_hooks.py @@ -20,12 +20,16 @@ # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. -import unittest +import contextlib import sqlite3 as sqlite +import unittest from test.support.os_helper import TESTFN, unlink + +from test.test_sqlite3.test_dbapi import memory_database, cx_limit from test.test_sqlite3.test_userfunctions import with_tracebacks + class CollationTests(unittest.TestCase): def test_create_collation_not_string(self): con = sqlite.connect(":memory:") @@ -224,6 +228,16 @@ def bad_progress(): class TraceCallbackTests(unittest.TestCase): + @contextlib.contextmanager + def check_stmt_trace(self, cx, expected): + try: + traced = [] + cx.set_trace_callback(lambda stmt: traced.append(stmt)) + yield + finally: + self.assertEqual(traced, expected) + cx.set_trace_callback(None) + def test_trace_callback_used(self): """ Test that the trace callback is invoked once it is set. @@ -289,6 +303,51 @@ def trace(statement): con2.close() self.assertEqual(traced_statements, queries) + @unittest.skipIf(sqlite.sqlite_version_info < (3, 14, 0), + "Requires SQLite 3.14.0 or newer") + def test_trace_expanded_sql(self): + expected = [ + "create table t(t)", + "BEGIN ", + "insert into t values(0)", + "insert into t values(1)", + "insert into t values(2)", + "COMMIT", + ] + with memory_database() as cx, self.check_stmt_trace(cx, expected): + with cx: + cx.execute("create table t(t)") + cx.executemany("insert into t values(?)", ((v,) for v in range(3))) + + @with_tracebacks( + sqlite.DataError, + regex="Expanded SQL string exceeds the maximum string length" + ) + def test_trace_too_much_expanded_sql(self): + # If the expanded string is too large, we'll fall back to the + # unexpanded SQL statement. The resulting string length is limited by + # SQLITE_LIMIT_LENGTH. + template = "select 'b' as \"a\" from sqlite_master where \"a\"=" + category = sqlite.SQLITE_LIMIT_LENGTH + with memory_database() as cx, cx_limit(cx, category=category) as lim: + nextra = lim - (len(template) + 2) - 1 + ok_param = "a" * nextra + bad_param = "a" * (nextra + 1) + + unexpanded_query = template + "?" + with self.check_stmt_trace(cx, [unexpanded_query]): + cx.execute(unexpanded_query, (bad_param,)) + + expanded_query = f"{template}'{ok_param}'" + with self.check_stmt_trace(cx, [expanded_query]): + cx.execute(unexpanded_query, (ok_param,)) + + @with_tracebacks(ZeroDivisionError, regex="division by zero") + def test_trace_bad_handler(self): + with memory_database() as cx: + cx.set_trace_callback(lambda stmt: 5/0) + cx.execute("select 1") + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2021-09-08-16-21-03.bpo-45138.yghUrK.rst b/Misc/NEWS.d/next/Library/2021-09-08-16-21-03.bpo-45138.yghUrK.rst new file mode 100644 index 0000000000000..7b0b4402aeace --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-09-08-16-21-03.bpo-45138.yghUrK.rst @@ -0,0 +1,3 @@ +For SQLite 3.14.0 and newer, bound parameters are expanded in the statement +string passed to the :mod:`sqlite3` trace callback. Patch by Erlend E. +Aasland. diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index e4b8ecb5e2d7f..511e8a2077b41 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1079,11 +1079,10 @@ progress_callback(void *ctx) * to ensure future compatibility. */ static int -trace_callback(unsigned int type, void *ctx, void *prepared_statement, - void *statement_string) +trace_callback(unsigned int type, void *ctx, void *stmt, void *sql) #else static void -trace_callback(void *ctx, const char *statement_string) +trace_callback(void *ctx, const char *sql) #endif { #ifdef HAVE_TRACE_V2 @@ -1094,24 +1093,46 @@ trace_callback(void *ctx, const char *statement_string) PyGILState_STATE gilstate = PyGILState_Ensure(); - PyObject *py_statement = NULL; - PyObject *ret = NULL; - py_statement = PyUnicode_DecodeUTF8(statement_string, - strlen(statement_string), "replace"); assert(ctx != NULL); + PyObject *py_statement = NULL; +#ifdef HAVE_TRACE_V2 + assert(stmt != NULL); + const char *expanded_sql = sqlite3_expanded_sql((sqlite3_stmt *)stmt); + if (expanded_sql == NULL) { + sqlite3 *db = sqlite3_db_handle((sqlite3_stmt *)stmt); + if (sqlite3_errcode(db) == SQLITE_NOMEM) { + (void)PyErr_NoMemory(); + goto exit; + } + + pysqlite_state *state = ((callback_context *)ctx)->state; + assert(state != NULL); + PyErr_SetString(state->DataError, + "Expanded SQL string exceeds the maximum string " + "length"); + print_or_clear_traceback((callback_context *)ctx); + + // Fall back to unexpanded sql + py_statement = PyUnicode_FromString((const char *)sql); + } + else { + py_statement = PyUnicode_FromString(expanded_sql); + sqlite3_free((void *)expanded_sql); + } +#else + py_statement = PyUnicode_FromString(sql); +#endif if (py_statement) { PyObject *callable = ((callback_context *)ctx)->callable; - ret = PyObject_CallOneArg(callable, py_statement); + PyObject *ret = PyObject_CallOneArg(callable, py_statement); Py_DECREF(py_statement); + Py_XDECREF(ret); } - if (ret) { - Py_DECREF(ret); - } - else { - print_or_clear_traceback(ctx); +exit: + if (PyErr_Occurred()) { + print_or_clear_traceback((callback_context *)ctx); } - PyGILState_Release(gilstate); #ifdef HAVE_TRACE_V2 return 0; From webhook-mailer at python.org Wed Mar 9 06:32:15 2022 From: webhook-mailer at python.org (Fidget-Spinner) Date: Wed, 09 Mar 2022 11:32:15 -0000 Subject: [Python-checkins] Fix 3.11 what's new formatting (GH-31763) Message-ID: https://github.com/python/cpython/commit/5eb03b1b5124659ee63eac7bc03f76cf2c7f9439 commit: 5eb03b1b5124659ee63eac7bc03f76cf2c7f9439 branch: main author: Ken Jin committer: Fidget-Spinner date: 2022-03-09T19:31:56+08:00 summary: Fix 3.11 what's new formatting (GH-31763) files: M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 262c1eb2c9dab..d9e5d0646836f 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -65,10 +65,15 @@ Summary -- Release highlights .. PEP-sized items next. -PEP-654: Exception Groups and ``except*``. -(Contributed by Irit Katriel in :issue:`45292`.) -PEP-673: ``Self`` Type. -(Contributed by James Hilton-Balfe and Pradeep Kumar in :issue:`30924`.) +New syntax features: + +* :pep:`654`: Exception Groups and ``except*``. + (Contributed by Irit Katriel in :issue:`45292`.) + +New typing features: + +* :pep:`673`: ``Self`` Type. + (Contributed by James Hilton-Balfe and Pradeep Kumar in :issue:`30924`.) New Features ============ From webhook-mailer at python.org Wed Mar 9 07:29:39 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Wed, 09 Mar 2022 12:29:39 -0000 Subject: [Python-checkins] bpo-46245: Add optional parameter dir_fd in shutil.rmtree() (GH-30365) Message-ID: https://github.com/python/cpython/commit/02fbaf4887deaf0207a5805d3736e0124a694c14 commit: 02fbaf4887deaf0207a5805d3736e0124a694c14 branch: main author: Serhiy Storchaka committer: serhiy-storchaka date: 2022-03-09T14:29:33+02:00 summary: bpo-46245: Add optional parameter dir_fd in shutil.rmtree() (GH-30365) files: A Misc/NEWS.d/next/Library/2022-01-03-20-12-14.bpo-46245.3w4RlA.rst M Doc/library/shutil.rst M Doc/whatsnew/3.11.rst M Lib/shutil.py M Lib/test/test_shutil.py diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 22d6dba9e1a9c..16b8d3cdeebc8 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -286,7 +286,7 @@ Directory and files operations .. versionadded:: 3.8 The *dirs_exist_ok* parameter. -.. function:: rmtree(path, ignore_errors=False, onerror=None) +.. function:: rmtree(path, ignore_errors=False, onerror=None, *, dir_fd=None) .. index:: single: directory; deleting @@ -296,6 +296,9 @@ Directory and files operations handled by calling a handler specified by *onerror* or, if that is omitted, they raise an exception. + This function can support :ref:`paths relative to directory descriptors + `. + .. note:: On platforms that support the necessary fd-based functions a symlink @@ -315,7 +318,7 @@ Directory and files operations *excinfo*, will be the exception information returned by :func:`sys.exc_info`. Exceptions raised by *onerror* will not be caught. - .. audit-event:: shutil.rmtree path shutil.rmtree + .. audit-event:: shutil.rmtree path,dir_fd shutil.rmtree .. versionchanged:: 3.3 Added a symlink attack resistant version that is used automatically @@ -325,6 +328,9 @@ Directory and files operations On Windows, will no longer delete the contents of a directory junction before removing the junction. + .. versionchanged:: 3.11 + The *dir_fd* parameter. + .. attribute:: rmtree.avoids_symlink_attacks Indicates whether the current platform and implementation provides a diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index d9e5d0646836f..628d4c0aaa1e6 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -283,6 +283,13 @@ os (Contributed by Dong-hee Na in :issue:`44611`.) +shutil +------ + +* Add optional parameter *dir_fd* in :func:`shutil.rmtree`. + (Contributed by Serhiy Storchaka in :issue:`46245`.) + + socket ------ diff --git a/Lib/shutil.py b/Lib/shutil.py index eb768f9e03b7d..22bd86d569e7e 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -684,9 +684,14 @@ def _rmtree_safe_fd(topfd, path, onerror): os.scandir in os.supports_fd and os.stat in os.supports_follow_symlinks) -def rmtree(path, ignore_errors=False, onerror=None): +def rmtree(path, ignore_errors=False, onerror=None, *, dir_fd=None): """Recursively delete a directory tree. + If dir_fd is not None, it should be a file descriptor open to a directory; + path will then be relative to that directory. + dir_fd may not be implemented on your platform. + If it is unavailable, using it will raise a NotImplementedError. + If ignore_errors is set, errors are ignored; otherwise, if onerror is set, it is called to handle the error with arguments (func, path, exc_info) where func is platform and implementation dependent; @@ -695,7 +700,7 @@ def rmtree(path, ignore_errors=False, onerror=None): is false and onerror is None, an exception is raised. """ - sys.audit("shutil.rmtree", path) + sys.audit("shutil.rmtree", path, dir_fd) if ignore_errors: def onerror(*args): pass @@ -709,12 +714,12 @@ def onerror(*args): # Note: To guard against symlink races, we use the standard # lstat()/open()/fstat() trick. try: - orig_st = os.lstat(path) + orig_st = os.lstat(path, dir_fd=dir_fd) except Exception: onerror(os.lstat, path, sys.exc_info()) return try: - fd = os.open(path, os.O_RDONLY) + fd = os.open(path, os.O_RDONLY, dir_fd=dir_fd) fd_closed = False except Exception: onerror(os.open, path, sys.exc_info()) @@ -725,7 +730,7 @@ def onerror(*args): try: os.close(fd) fd_closed = True - os.rmdir(path) + os.rmdir(path, dir_fd=dir_fd) except OSError: onerror(os.rmdir, path, sys.exc_info()) else: @@ -738,6 +743,8 @@ def onerror(*args): if not fd_closed: os.close(fd) else: + if dir_fd is not None: + raise NotImplementedError("dir_fd unavailable on this platform") try: if _rmtree_islink(path): # symlinks to directories are forbidden, see bug #1669 diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index 7669b94ac35a6..7003386345280 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -405,6 +405,27 @@ def _raiser(*args, **kwargs): self.assertFalse(shutil._use_fd_functions) self.assertFalse(shutil.rmtree.avoids_symlink_attacks) + @unittest.skipUnless(shutil._use_fd_functions, "dir_fd is not supported") + def test_rmtree_with_dir_fd(self): + tmp_dir = self.mkdtemp() + victim = 'killme' + fullname = os.path.join(tmp_dir, victim) + dir_fd = os.open(tmp_dir, os.O_RDONLY) + self.addCleanup(os.close, dir_fd) + os.mkdir(fullname) + os.mkdir(os.path.join(fullname, 'subdir')) + write_file(os.path.join(fullname, 'subdir', 'somefile'), 'foo') + self.assertTrue(os.path.exists(fullname)) + shutil.rmtree(victim, dir_fd=dir_fd) + self.assertFalse(os.path.exists(fullname)) + + @unittest.skipIf(shutil._use_fd_functions, "dir_fd is supported") + def test_rmtree_with_dir_fd_unsupported(self): + tmp_dir = self.mkdtemp() + with self.assertRaises(NotImplementedError): + shutil.rmtree(tmp_dir, dir_fd=0) + self.assertTrue(os.path.exists(tmp_dir)) + def test_rmtree_dont_delete_file(self): # When called on a file instead of a directory, don't delete it. handle, path = tempfile.mkstemp(dir=self.mkdtemp()) diff --git a/Misc/NEWS.d/next/Library/2022-01-03-20-12-14.bpo-46245.3w4RlA.rst b/Misc/NEWS.d/next/Library/2022-01-03-20-12-14.bpo-46245.3w4RlA.rst new file mode 100644 index 0000000000000..43e8660b2a3d3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-01-03-20-12-14.bpo-46245.3w4RlA.rst @@ -0,0 +1 @@ +Add optional parameter *dir_fd* in :func:`shutil.rmtree`. From webhook-mailer at python.org Wed Mar 9 08:38:16 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 09 Mar 2022 13:38:16 -0000 Subject: [Python-checkins] bpo-40059: Fix installation of tomllib (GH-31784) Message-ID: https://github.com/python/cpython/commit/23dcea5de736b367c0244042aaca10971538b2b4 commit: 23dcea5de736b367c0244042aaca10971538b2b4 branch: main author: Dominic Davis-Foster committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-09T05:38:00-08:00 summary: bpo-40059: Fix installation of tomllib (GH-31784) files: M Makefile.pre.in diff --git a/Makefile.pre.in b/Makefile.pre.in index 1b40764b2ef95..9deffadb8881d 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1869,6 +1869,7 @@ LIBSUBDIRS= asyncio \ site-packages \ sqlite3 \ tkinter \ + tomllib \ turtledemo \ unittest \ urllib \ From webhook-mailer at python.org Wed Mar 9 12:40:08 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 09 Mar 2022 17:40:08 -0000 Subject: [Python-checkins] bpo-45138: Revert GH-28240: Expand traced SQL statements (GH-31788) Message-ID: https://github.com/python/cpython/commit/e801e88744f34508aa338f9f7f3f3baee012f813 commit: e801e88744f34508aa338f9f7f3f3baee012f813 branch: main author: Erlend Egeberg Aasland committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-09T09:39:49-08:00 summary: bpo-45138: Revert GH-28240: Expand traced SQL statements (GH-31788) This reverts commit d1777515f9f53b452a4231d68196a7c0e5deb879. Automerge-Triggered-By: GH:JelleZijlstra files: D Misc/NEWS.d/next/Library/2021-09-08-16-21-03.bpo-45138.yghUrK.rst M Doc/library/sqlite3.rst M Doc/whatsnew/3.11.rst M Lib/test/test_sqlite3/test_hooks.py M Modules/_sqlite/connection.c diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 296b188221a76..c456905bc956c 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -560,9 +560,6 @@ Connection Objects Passing :const:`None` as *trace_callback* will disable the trace callback. - For SQLite 3.14.0 and newer, bound parameters are expanded in the passed - statement string. - .. note:: Exceptions raised in the trace callback are not propagated. As a development and debugging aid, use @@ -571,9 +568,6 @@ Connection Objects .. versionadded:: 3.3 - .. versionchanged:: 3.11 - Added support for expanded SQL statements. - .. method:: enable_load_extension(enabled) diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 628d4c0aaa1e6..4514de9c07c9e 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -334,10 +334,6 @@ sqlite3 Instead we leave it to the SQLite library to handle these cases. (Contributed by Erlend E. Aasland in :issue:`44092`.) -* For SQLite 3.14.0 and newer, bound parameters are expanded in the statement - string passed to the trace callback. See :meth:`~sqlite3.Connection.set_trace_callback`. - (Contributed by Erlend E. Aasland in :issue:`45138`.) - sys --- diff --git a/Lib/test/test_sqlite3/test_hooks.py b/Lib/test/test_sqlite3/test_hooks.py index 38126b605469a..d4790cfe77b7b 100644 --- a/Lib/test/test_sqlite3/test_hooks.py +++ b/Lib/test/test_sqlite3/test_hooks.py @@ -20,16 +20,12 @@ # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. -import contextlib -import sqlite3 as sqlite import unittest +import sqlite3 as sqlite from test.support.os_helper import TESTFN, unlink - -from test.test_sqlite3.test_dbapi import memory_database, cx_limit from test.test_sqlite3.test_userfunctions import with_tracebacks - class CollationTests(unittest.TestCase): def test_create_collation_not_string(self): con = sqlite.connect(":memory:") @@ -228,16 +224,6 @@ def bad_progress(): class TraceCallbackTests(unittest.TestCase): - @contextlib.contextmanager - def check_stmt_trace(self, cx, expected): - try: - traced = [] - cx.set_trace_callback(lambda stmt: traced.append(stmt)) - yield - finally: - self.assertEqual(traced, expected) - cx.set_trace_callback(None) - def test_trace_callback_used(self): """ Test that the trace callback is invoked once it is set. @@ -303,51 +289,6 @@ def trace(statement): con2.close() self.assertEqual(traced_statements, queries) - @unittest.skipIf(sqlite.sqlite_version_info < (3, 14, 0), - "Requires SQLite 3.14.0 or newer") - def test_trace_expanded_sql(self): - expected = [ - "create table t(t)", - "BEGIN ", - "insert into t values(0)", - "insert into t values(1)", - "insert into t values(2)", - "COMMIT", - ] - with memory_database() as cx, self.check_stmt_trace(cx, expected): - with cx: - cx.execute("create table t(t)") - cx.executemany("insert into t values(?)", ((v,) for v in range(3))) - - @with_tracebacks( - sqlite.DataError, - regex="Expanded SQL string exceeds the maximum string length" - ) - def test_trace_too_much_expanded_sql(self): - # If the expanded string is too large, we'll fall back to the - # unexpanded SQL statement. The resulting string length is limited by - # SQLITE_LIMIT_LENGTH. - template = "select 'b' as \"a\" from sqlite_master where \"a\"=" - category = sqlite.SQLITE_LIMIT_LENGTH - with memory_database() as cx, cx_limit(cx, category=category) as lim: - nextra = lim - (len(template) + 2) - 1 - ok_param = "a" * nextra - bad_param = "a" * (nextra + 1) - - unexpanded_query = template + "?" - with self.check_stmt_trace(cx, [unexpanded_query]): - cx.execute(unexpanded_query, (bad_param,)) - - expanded_query = f"{template}'{ok_param}'" - with self.check_stmt_trace(cx, [expanded_query]): - cx.execute(unexpanded_query, (ok_param,)) - - @with_tracebacks(ZeroDivisionError, regex="division by zero") - def test_trace_bad_handler(self): - with memory_database() as cx: - cx.set_trace_callback(lambda stmt: 5/0) - cx.execute("select 1") - if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2021-09-08-16-21-03.bpo-45138.yghUrK.rst b/Misc/NEWS.d/next/Library/2021-09-08-16-21-03.bpo-45138.yghUrK.rst deleted file mode 100644 index 7b0b4402aeace..0000000000000 --- a/Misc/NEWS.d/next/Library/2021-09-08-16-21-03.bpo-45138.yghUrK.rst +++ /dev/null @@ -1,3 +0,0 @@ -For SQLite 3.14.0 and newer, bound parameters are expanded in the statement -string passed to the :mod:`sqlite3` trace callback. Patch by Erlend E. -Aasland. diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 511e8a2077b41..e4b8ecb5e2d7f 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1079,10 +1079,11 @@ progress_callback(void *ctx) * to ensure future compatibility. */ static int -trace_callback(unsigned int type, void *ctx, void *stmt, void *sql) +trace_callback(unsigned int type, void *ctx, void *prepared_statement, + void *statement_string) #else static void -trace_callback(void *ctx, const char *sql) +trace_callback(void *ctx, const char *statement_string) #endif { #ifdef HAVE_TRACE_V2 @@ -1093,46 +1094,24 @@ trace_callback(void *ctx, const char *sql) PyGILState_STATE gilstate = PyGILState_Ensure(); - assert(ctx != NULL); PyObject *py_statement = NULL; -#ifdef HAVE_TRACE_V2 - assert(stmt != NULL); - const char *expanded_sql = sqlite3_expanded_sql((sqlite3_stmt *)stmt); - if (expanded_sql == NULL) { - sqlite3 *db = sqlite3_db_handle((sqlite3_stmt *)stmt); - if (sqlite3_errcode(db) == SQLITE_NOMEM) { - (void)PyErr_NoMemory(); - goto exit; - } - - pysqlite_state *state = ((callback_context *)ctx)->state; - assert(state != NULL); - PyErr_SetString(state->DataError, - "Expanded SQL string exceeds the maximum string " - "length"); - print_or_clear_traceback((callback_context *)ctx); - - // Fall back to unexpanded sql - py_statement = PyUnicode_FromString((const char *)sql); - } - else { - py_statement = PyUnicode_FromString(expanded_sql); - sqlite3_free((void *)expanded_sql); - } -#else - py_statement = PyUnicode_FromString(sql); -#endif + PyObject *ret = NULL; + py_statement = PyUnicode_DecodeUTF8(statement_string, + strlen(statement_string), "replace"); + assert(ctx != NULL); if (py_statement) { PyObject *callable = ((callback_context *)ctx)->callable; - PyObject *ret = PyObject_CallOneArg(callable, py_statement); + ret = PyObject_CallOneArg(callable, py_statement); Py_DECREF(py_statement); - Py_XDECREF(ret); } -exit: - if (PyErr_Occurred()) { - print_or_clear_traceback((callback_context *)ctx); + if (ret) { + Py_DECREF(ret); } + else { + print_or_clear_traceback(ctx); + } + PyGILState_Release(gilstate); #ifdef HAVE_TRACE_V2 return 0; From webhook-mailer at python.org Wed Mar 9 13:19:57 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Wed, 09 Mar 2022 18:19:57 -0000 Subject: [Python-checkins] [3.10] Docstring: replace pysqlite with sqlite3 (GH-31758) (GH-31777) Message-ID: https://github.com/python/cpython/commit/5dfe9817912cd020389f3e15e6d5ea98b08a543f commit: 5dfe9817912cd020389f3e15e6d5ea98b08a543f branch: 3.10 author: Jelle Zijlstra committer: JelleZijlstra date: 2022-03-09T10:19:27-08:00 summary: [3.10] Docstring: replace pysqlite with sqlite3 (GH-31758) (GH-31777) Replace two instances of "pysqlite" with "sqlite3" in sqlite3 docstrings. Also reword "is a no-op" to "does nothing" for clarity.. (cherry picked from commit b33a1ae703338e09dc0af5fbfd8ffa01d3ff75da) Co-authored-by: Erlend Egeberg Aasland files: M Doc/library/sqlite3.rst M Modules/_sqlite/clinic/cursor.c.h M Modules/_sqlite/cursor.c diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 492dadb2746ac..1c5d6ac2b1bc8 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -757,11 +757,11 @@ Cursor Objects .. method:: setinputsizes(sizes) - Required by the DB-API. Is a no-op in :mod:`sqlite3`. + Required by the DB-API. Does nothing in :mod:`sqlite3`. .. method:: setoutputsize(size [, column]) - Required by the DB-API. Is a no-op in :mod:`sqlite3`. + Required by the DB-API. Does nothing in :mod:`sqlite3`. .. attribute:: rowcount diff --git a/Modules/_sqlite/clinic/cursor.c.h b/Modules/_sqlite/clinic/cursor.c.h index cad0a9bf23b1c..fc7d92b466947 100644 --- a/Modules/_sqlite/clinic/cursor.c.h +++ b/Modules/_sqlite/clinic/cursor.c.h @@ -202,7 +202,7 @@ PyDoc_STRVAR(pysqlite_cursor_setinputsizes__doc__, "setinputsizes($self, sizes, /)\n" "--\n" "\n" -"Required by DB-API. Does nothing in pysqlite."); +"Required by DB-API. Does nothing in sqlite3."); #define PYSQLITE_CURSOR_SETINPUTSIZES_METHODDEF \ {"setinputsizes", (PyCFunction)pysqlite_cursor_setinputsizes, METH_O, pysqlite_cursor_setinputsizes__doc__}, @@ -211,7 +211,7 @@ PyDoc_STRVAR(pysqlite_cursor_setoutputsize__doc__, "setoutputsize($self, size, column=None, /)\n" "--\n" "\n" -"Required by DB-API. Does nothing in pysqlite."); +"Required by DB-API. Does nothing in sqlite3."); #define PYSQLITE_CURSOR_SETOUTPUTSIZE_METHODDEF \ {"setoutputsize", (PyCFunction)(void(*)(void))pysqlite_cursor_setoutputsize, METH_FASTCALL, pysqlite_cursor_setoutputsize__doc__}, @@ -259,4 +259,4 @@ pysqlite_cursor_close(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) { return pysqlite_cursor_close_impl(self); } -/*[clinic end generated code: output=cdd7e7a541ceb4d2 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=98aa7b44c6834d0c input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index d06392a7a47dc..390830f68a9b6 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -935,12 +935,12 @@ _sqlite3.Cursor.setinputsizes as pysqlite_cursor_setinputsizes sizes: object / -Required by DB-API. Does nothing in pysqlite. +Required by DB-API. Does nothing in sqlite3. [clinic start generated code]*/ static PyObject * pysqlite_cursor_setinputsizes(pysqlite_Cursor *self, PyObject *sizes) -/*[clinic end generated code: output=893c817afe9d08ad input=7cffbb168663bc69]*/ +/*[clinic end generated code: output=893c817afe9d08ad input=de7950a3aec79bdf]*/ { Py_RETURN_NONE; } @@ -952,13 +952,13 @@ _sqlite3.Cursor.setoutputsize as pysqlite_cursor_setoutputsize column: object = None / -Required by DB-API. Does nothing in pysqlite. +Required by DB-API. Does nothing in sqlite3. [clinic start generated code]*/ static PyObject * pysqlite_cursor_setoutputsize_impl(pysqlite_Cursor *self, PyObject *size, PyObject *column) -/*[clinic end generated code: output=018d7e9129d45efe input=077b017da58b9389]*/ +/*[clinic end generated code: output=018d7e9129d45efe input=607a6bece8bbb273]*/ { Py_RETURN_NONE; } From webhook-mailer at python.org Wed Mar 9 13:19:57 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Wed, 09 Mar 2022 18:19:57 -0000 Subject: [Python-checkins] [3.9] Docstring: replace pysqlite with sqlite3 (GH-31758) (GH-31778) Message-ID: https://github.com/python/cpython/commit/0c47008f8ba64b42834681053e0fbd019630b0e7 commit: 0c47008f8ba64b42834681053e0fbd019630b0e7 branch: 3.9 author: Jelle Zijlstra committer: JelleZijlstra date: 2022-03-09T10:19:53-08:00 summary: [3.9] Docstring: replace pysqlite with sqlite3 (GH-31758) (GH-31778) Replace two instances of "pysqlite" with "sqlite3" in sqlite3 docstrings. Also reword "is a no-op" to "does nothing" for clarity.. (cherry picked from commit b33a1ae703338e09dc0af5fbfd8ffa01d3ff75da) Co-authored-by: Erlend Egeberg Aasland files: M Doc/library/sqlite3.rst M Modules/_sqlite/cursor.c diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index e50928a3845c4..c68386ff0cd3f 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -744,11 +744,11 @@ Cursor Objects .. method:: setinputsizes(sizes) - Required by the DB-API. Is a no-op in :mod:`sqlite3`. + Required by the DB-API. Does nothing in :mod:`sqlite3`. .. method:: setoutputsize(size [, column]) - Required by the DB-API. Is a no-op in :mod:`sqlite3`. + Required by the DB-API. Does nothing in :mod:`sqlite3`. .. attribute:: rowcount diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index c6d5a9a2af897..ad7e702c88c32 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -882,7 +882,7 @@ static PyMethodDef cursor_methods[] = { {"executemany", (PyCFunction)pysqlite_cursor_executemany, METH_VARARGS, PyDoc_STR("Repeatedly executes a SQL statement.")}, {"executescript", (PyCFunction)pysqlite_cursor_executescript, METH_VARARGS, - PyDoc_STR("Executes a multiple SQL statements at once.")}, + PyDoc_STR("Executes multiple SQL statements at once.")}, {"fetchone", (PyCFunction)pysqlite_cursor_fetchone, METH_NOARGS, PyDoc_STR("Fetches one row from the resultset.")}, {"fetchmany", (PyCFunction)(void(*)(void))pysqlite_cursor_fetchmany, METH_VARARGS|METH_KEYWORDS, @@ -892,9 +892,9 @@ static PyMethodDef cursor_methods[] = { {"close", (PyCFunction)pysqlite_cursor_close, METH_NOARGS, PyDoc_STR("Closes the cursor.")}, {"setinputsizes", (PyCFunction)pysqlite_noop, METH_VARARGS, - PyDoc_STR("Required by DB-API. Does nothing in pysqlite.")}, + PyDoc_STR("Required by DB-API. Does nothing in sqlite3.")}, {"setoutputsize", (PyCFunction)pysqlite_noop, METH_VARARGS, - PyDoc_STR("Required by DB-API. Does nothing in pysqlite.")}, + PyDoc_STR("Required by DB-API. Does nothing in sqlite3.")}, {NULL, NULL} }; From webhook-mailer at python.org Wed Mar 9 18:02:10 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 09 Mar 2022 23:02:10 -0000 Subject: [Python-checkins] bpo-46881: Statically allocate and initialize the latin1 characters. (GH-31616) Message-ID: https://github.com/python/cpython/commit/8714b6fa27271035dd6dd3514e283f92d669321d commit: 8714b6fa27271035dd6dd3514e283f92d669321d branch: main author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-09T15:02:00-08:00 summary: bpo-46881: Statically allocate and initialize the latin1 characters. (GH-31616) files: A Misc/NEWS.d/next/Core and Builtins/2022-03-03-09-08-17.bpo-46881.ckD4tT.rst M Include/internal/pycore_global_strings.h M Include/internal/pycore_runtime_init.h M Include/internal/pycore_unicodeobject.h M Objects/unicodeobject.c M Tools/scripts/generate_global_objects.py diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h index 74ebc144ab548..755d69a873cdc 100644 --- a/Include/internal/pycore_global_strings.h +++ b/Include/internal/pycore_global_strings.h @@ -350,6 +350,14 @@ struct _Py_global_strings { STRUCT_FOR_ID(write) STRUCT_FOR_ID(zipimporter) } identifiers; + struct { + PyASCIIObject _ascii; + uint8_t _data[2]; + } ascii[128]; + struct { + PyCompactUnicodeObject _latin1; + uint8_t _data[2]; + } latin1[128]; }; /* End auto-generated code */ diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h index 8b1abcde11f72..5ba18267aeb34 100644 --- a/Include/internal/pycore_runtime_init.h +++ b/Include/internal/pycore_runtime_init.h @@ -93,26 +93,34 @@ extern "C" { _PyBytes_SIMPLE_INIT(CH, 1) \ } -#define _PyASCIIObject_INIT(LITERAL) \ +#define _PyUnicode_ASCII_BASE_INIT(LITERAL, ASCII) \ { \ - ._ascii = { \ - .ob_base = _PyObject_IMMORTAL_INIT(&PyUnicode_Type), \ - .length = sizeof(LITERAL) - 1, \ - .hash = -1, \ - .state = { \ - .kind = 1, \ - .compact = 1, \ - .ascii = 1, \ - .ready = 1, \ - }, \ + .ob_base = _PyObject_IMMORTAL_INIT(&PyUnicode_Type), \ + .length = sizeof(LITERAL) - 1, \ + .hash = -1, \ + .state = { \ + .kind = 1, \ + .compact = 1, \ + .ascii = ASCII, \ + .ready = 1, \ }, \ - ._data = LITERAL, \ + } +#define _PyASCIIObject_INIT(LITERAL) \ + { \ + ._ascii = _PyUnicode_ASCII_BASE_INIT(LITERAL, 1), \ + ._data = LITERAL \ } #define INIT_STR(NAME, LITERAL) \ ._ ## NAME = _PyASCIIObject_INIT(LITERAL) #define INIT_ID(NAME) \ ._ ## NAME = _PyASCIIObject_INIT(#NAME) - +#define _PyUnicode_LATIN1_INIT(LITERAL) \ + { \ + ._latin1 = { \ + ._base = _PyUnicode_ASCII_BASE_INIT(LITERAL, 0), \ + }, \ + ._data = LITERAL, \ + } /* The following is auto-generated by Tools/scripts/generate_global_objects.py. */ #define _Py_global_objects_INIT { \ @@ -965,6 +973,266 @@ extern "C" { INIT_ID(write), \ INIT_ID(zipimporter), \ }, \ + .ascii = { \ + _PyASCIIObject_INIT("\x00"), \ + _PyASCIIObject_INIT("\x01"), \ + _PyASCIIObject_INIT("\x02"), \ + _PyASCIIObject_INIT("\x03"), \ + _PyASCIIObject_INIT("\x04"), \ + _PyASCIIObject_INIT("\x05"), \ + _PyASCIIObject_INIT("\x06"), \ + _PyASCIIObject_INIT("\x07"), \ + _PyASCIIObject_INIT("\x08"), \ + _PyASCIIObject_INIT("\x09"), \ + _PyASCIIObject_INIT("\x0a"), \ + _PyASCIIObject_INIT("\x0b"), \ + _PyASCIIObject_INIT("\x0c"), \ + _PyASCIIObject_INIT("\x0d"), \ + _PyASCIIObject_INIT("\x0e"), \ + _PyASCIIObject_INIT("\x0f"), \ + _PyASCIIObject_INIT("\x10"), \ + _PyASCIIObject_INIT("\x11"), \ + _PyASCIIObject_INIT("\x12"), \ + _PyASCIIObject_INIT("\x13"), \ + _PyASCIIObject_INIT("\x14"), \ + _PyASCIIObject_INIT("\x15"), \ + _PyASCIIObject_INIT("\x16"), \ + _PyASCIIObject_INIT("\x17"), \ + _PyASCIIObject_INIT("\x18"), \ + _PyASCIIObject_INIT("\x19"), \ + _PyASCIIObject_INIT("\x1a"), \ + _PyASCIIObject_INIT("\x1b"), \ + _PyASCIIObject_INIT("\x1c"), \ + _PyASCIIObject_INIT("\x1d"), \ + _PyASCIIObject_INIT("\x1e"), \ + _PyASCIIObject_INIT("\x1f"), \ + _PyASCIIObject_INIT("\x20"), \ + _PyASCIIObject_INIT("\x21"), \ + _PyASCIIObject_INIT("\x22"), \ + _PyASCIIObject_INIT("\x23"), \ + _PyASCIIObject_INIT("\x24"), \ + _PyASCIIObject_INIT("\x25"), \ + _PyASCIIObject_INIT("\x26"), \ + _PyASCIIObject_INIT("\x27"), \ + _PyASCIIObject_INIT("\x28"), \ + _PyASCIIObject_INIT("\x29"), \ + _PyASCIIObject_INIT("\x2a"), \ + _PyASCIIObject_INIT("\x2b"), \ + _PyASCIIObject_INIT("\x2c"), \ + _PyASCIIObject_INIT("\x2d"), \ + _PyASCIIObject_INIT("\x2e"), \ + _PyASCIIObject_INIT("\x2f"), \ + _PyASCIIObject_INIT("\x30"), \ + _PyASCIIObject_INIT("\x31"), \ + _PyASCIIObject_INIT("\x32"), \ + _PyASCIIObject_INIT("\x33"), \ + _PyASCIIObject_INIT("\x34"), \ + _PyASCIIObject_INIT("\x35"), \ + _PyASCIIObject_INIT("\x36"), \ + _PyASCIIObject_INIT("\x37"), \ + _PyASCIIObject_INIT("\x38"), \ + _PyASCIIObject_INIT("\x39"), \ + _PyASCIIObject_INIT("\x3a"), \ + _PyASCIIObject_INIT("\x3b"), \ + _PyASCIIObject_INIT("\x3c"), \ + _PyASCIIObject_INIT("\x3d"), \ + _PyASCIIObject_INIT("\x3e"), \ + _PyASCIIObject_INIT("\x3f"), \ + _PyASCIIObject_INIT("\x40"), \ + _PyASCIIObject_INIT("\x41"), \ + _PyASCIIObject_INIT("\x42"), \ + _PyASCIIObject_INIT("\x43"), \ + _PyASCIIObject_INIT("\x44"), \ + _PyASCIIObject_INIT("\x45"), \ + _PyASCIIObject_INIT("\x46"), \ + _PyASCIIObject_INIT("\x47"), \ + _PyASCIIObject_INIT("\x48"), \ + _PyASCIIObject_INIT("\x49"), \ + _PyASCIIObject_INIT("\x4a"), \ + _PyASCIIObject_INIT("\x4b"), \ + _PyASCIIObject_INIT("\x4c"), \ + _PyASCIIObject_INIT("\x4d"), \ + _PyASCIIObject_INIT("\x4e"), \ + _PyASCIIObject_INIT("\x4f"), \ + _PyASCIIObject_INIT("\x50"), \ + _PyASCIIObject_INIT("\x51"), \ + _PyASCIIObject_INIT("\x52"), \ + _PyASCIIObject_INIT("\x53"), \ + _PyASCIIObject_INIT("\x54"), \ + _PyASCIIObject_INIT("\x55"), \ + _PyASCIIObject_INIT("\x56"), \ + _PyASCIIObject_INIT("\x57"), \ + _PyASCIIObject_INIT("\x58"), \ + _PyASCIIObject_INIT("\x59"), \ + _PyASCIIObject_INIT("\x5a"), \ + _PyASCIIObject_INIT("\x5b"), \ + _PyASCIIObject_INIT("\x5c"), \ + _PyASCIIObject_INIT("\x5d"), \ + _PyASCIIObject_INIT("\x5e"), \ + _PyASCIIObject_INIT("\x5f"), \ + _PyASCIIObject_INIT("\x60"), \ + _PyASCIIObject_INIT("\x61"), \ + _PyASCIIObject_INIT("\x62"), \ + _PyASCIIObject_INIT("\x63"), \ + _PyASCIIObject_INIT("\x64"), \ + _PyASCIIObject_INIT("\x65"), \ + _PyASCIIObject_INIT("\x66"), \ + _PyASCIIObject_INIT("\x67"), \ + _PyASCIIObject_INIT("\x68"), \ + _PyASCIIObject_INIT("\x69"), \ + _PyASCIIObject_INIT("\x6a"), \ + _PyASCIIObject_INIT("\x6b"), \ + _PyASCIIObject_INIT("\x6c"), \ + _PyASCIIObject_INIT("\x6d"), \ + _PyASCIIObject_INIT("\x6e"), \ + _PyASCIIObject_INIT("\x6f"), \ + _PyASCIIObject_INIT("\x70"), \ + _PyASCIIObject_INIT("\x71"), \ + _PyASCIIObject_INIT("\x72"), \ + _PyASCIIObject_INIT("\x73"), \ + _PyASCIIObject_INIT("\x74"), \ + _PyASCIIObject_INIT("\x75"), \ + _PyASCIIObject_INIT("\x76"), \ + _PyASCIIObject_INIT("\x77"), \ + _PyASCIIObject_INIT("\x78"), \ + _PyASCIIObject_INIT("\x79"), \ + _PyASCIIObject_INIT("\x7a"), \ + _PyASCIIObject_INIT("\x7b"), \ + _PyASCIIObject_INIT("\x7c"), \ + _PyASCIIObject_INIT("\x7d"), \ + _PyASCIIObject_INIT("\x7e"), \ + _PyASCIIObject_INIT("\x7f"), \ + }, \ + .latin1 = { \ + _PyUnicode_LATIN1_INIT("\x80"), \ + _PyUnicode_LATIN1_INIT("\x81"), \ + _PyUnicode_LATIN1_INIT("\x82"), \ + _PyUnicode_LATIN1_INIT("\x83"), \ + _PyUnicode_LATIN1_INIT("\x84"), \ + _PyUnicode_LATIN1_INIT("\x85"), \ + _PyUnicode_LATIN1_INIT("\x86"), \ + _PyUnicode_LATIN1_INIT("\x87"), \ + _PyUnicode_LATIN1_INIT("\x88"), \ + _PyUnicode_LATIN1_INIT("\x89"), \ + _PyUnicode_LATIN1_INIT("\x8a"), \ + _PyUnicode_LATIN1_INIT("\x8b"), \ + _PyUnicode_LATIN1_INIT("\x8c"), \ + _PyUnicode_LATIN1_INIT("\x8d"), \ + _PyUnicode_LATIN1_INIT("\x8e"), \ + _PyUnicode_LATIN1_INIT("\x8f"), \ + _PyUnicode_LATIN1_INIT("\x90"), \ + _PyUnicode_LATIN1_INIT("\x91"), \ + _PyUnicode_LATIN1_INIT("\x92"), \ + _PyUnicode_LATIN1_INIT("\x93"), \ + _PyUnicode_LATIN1_INIT("\x94"), \ + _PyUnicode_LATIN1_INIT("\x95"), \ + _PyUnicode_LATIN1_INIT("\x96"), \ + _PyUnicode_LATIN1_INIT("\x97"), \ + _PyUnicode_LATIN1_INIT("\x98"), \ + _PyUnicode_LATIN1_INIT("\x99"), \ + _PyUnicode_LATIN1_INIT("\x9a"), \ + _PyUnicode_LATIN1_INIT("\x9b"), \ + _PyUnicode_LATIN1_INIT("\x9c"), \ + _PyUnicode_LATIN1_INIT("\x9d"), \ + _PyUnicode_LATIN1_INIT("\x9e"), \ + _PyUnicode_LATIN1_INIT("\x9f"), \ + _PyUnicode_LATIN1_INIT("\xa0"), \ + _PyUnicode_LATIN1_INIT("\xa1"), \ + _PyUnicode_LATIN1_INIT("\xa2"), \ + _PyUnicode_LATIN1_INIT("\xa3"), \ + _PyUnicode_LATIN1_INIT("\xa4"), \ + _PyUnicode_LATIN1_INIT("\xa5"), \ + _PyUnicode_LATIN1_INIT("\xa6"), \ + _PyUnicode_LATIN1_INIT("\xa7"), \ + _PyUnicode_LATIN1_INIT("\xa8"), \ + _PyUnicode_LATIN1_INIT("\xa9"), \ + _PyUnicode_LATIN1_INIT("\xaa"), \ + _PyUnicode_LATIN1_INIT("\xab"), \ + _PyUnicode_LATIN1_INIT("\xac"), \ + _PyUnicode_LATIN1_INIT("\xad"), \ + _PyUnicode_LATIN1_INIT("\xae"), \ + _PyUnicode_LATIN1_INIT("\xaf"), \ + _PyUnicode_LATIN1_INIT("\xb0"), \ + _PyUnicode_LATIN1_INIT("\xb1"), \ + _PyUnicode_LATIN1_INIT("\xb2"), \ + _PyUnicode_LATIN1_INIT("\xb3"), \ + _PyUnicode_LATIN1_INIT("\xb4"), \ + _PyUnicode_LATIN1_INIT("\xb5"), \ + _PyUnicode_LATIN1_INIT("\xb6"), \ + _PyUnicode_LATIN1_INIT("\xb7"), \ + _PyUnicode_LATIN1_INIT("\xb8"), \ + _PyUnicode_LATIN1_INIT("\xb9"), \ + _PyUnicode_LATIN1_INIT("\xba"), \ + _PyUnicode_LATIN1_INIT("\xbb"), \ + _PyUnicode_LATIN1_INIT("\xbc"), \ + _PyUnicode_LATIN1_INIT("\xbd"), \ + _PyUnicode_LATIN1_INIT("\xbe"), \ + _PyUnicode_LATIN1_INIT("\xbf"), \ + _PyUnicode_LATIN1_INIT("\xc0"), \ + _PyUnicode_LATIN1_INIT("\xc1"), \ + _PyUnicode_LATIN1_INIT("\xc2"), \ + _PyUnicode_LATIN1_INIT("\xc3"), \ + _PyUnicode_LATIN1_INIT("\xc4"), \ + _PyUnicode_LATIN1_INIT("\xc5"), \ + _PyUnicode_LATIN1_INIT("\xc6"), \ + _PyUnicode_LATIN1_INIT("\xc7"), \ + _PyUnicode_LATIN1_INIT("\xc8"), \ + _PyUnicode_LATIN1_INIT("\xc9"), \ + _PyUnicode_LATIN1_INIT("\xca"), \ + _PyUnicode_LATIN1_INIT("\xcb"), \ + _PyUnicode_LATIN1_INIT("\xcc"), \ + _PyUnicode_LATIN1_INIT("\xcd"), \ + _PyUnicode_LATIN1_INIT("\xce"), \ + _PyUnicode_LATIN1_INIT("\xcf"), \ + _PyUnicode_LATIN1_INIT("\xd0"), \ + _PyUnicode_LATIN1_INIT("\xd1"), \ + _PyUnicode_LATIN1_INIT("\xd2"), \ + _PyUnicode_LATIN1_INIT("\xd3"), \ + _PyUnicode_LATIN1_INIT("\xd4"), \ + _PyUnicode_LATIN1_INIT("\xd5"), \ + _PyUnicode_LATIN1_INIT("\xd6"), \ + _PyUnicode_LATIN1_INIT("\xd7"), \ + _PyUnicode_LATIN1_INIT("\xd8"), \ + _PyUnicode_LATIN1_INIT("\xd9"), \ + _PyUnicode_LATIN1_INIT("\xda"), \ + _PyUnicode_LATIN1_INIT("\xdb"), \ + _PyUnicode_LATIN1_INIT("\xdc"), \ + _PyUnicode_LATIN1_INIT("\xdd"), \ + _PyUnicode_LATIN1_INIT("\xde"), \ + _PyUnicode_LATIN1_INIT("\xdf"), \ + _PyUnicode_LATIN1_INIT("\xe0"), \ + _PyUnicode_LATIN1_INIT("\xe1"), \ + _PyUnicode_LATIN1_INIT("\xe2"), \ + _PyUnicode_LATIN1_INIT("\xe3"), \ + _PyUnicode_LATIN1_INIT("\xe4"), \ + _PyUnicode_LATIN1_INIT("\xe5"), \ + _PyUnicode_LATIN1_INIT("\xe6"), \ + _PyUnicode_LATIN1_INIT("\xe7"), \ + _PyUnicode_LATIN1_INIT("\xe8"), \ + _PyUnicode_LATIN1_INIT("\xe9"), \ + _PyUnicode_LATIN1_INIT("\xea"), \ + _PyUnicode_LATIN1_INIT("\xeb"), \ + _PyUnicode_LATIN1_INIT("\xec"), \ + _PyUnicode_LATIN1_INIT("\xed"), \ + _PyUnicode_LATIN1_INIT("\xee"), \ + _PyUnicode_LATIN1_INIT("\xef"), \ + _PyUnicode_LATIN1_INIT("\xf0"), \ + _PyUnicode_LATIN1_INIT("\xf1"), \ + _PyUnicode_LATIN1_INIT("\xf2"), \ + _PyUnicode_LATIN1_INIT("\xf3"), \ + _PyUnicode_LATIN1_INIT("\xf4"), \ + _PyUnicode_LATIN1_INIT("\xf5"), \ + _PyUnicode_LATIN1_INIT("\xf6"), \ + _PyUnicode_LATIN1_INIT("\xf7"), \ + _PyUnicode_LATIN1_INIT("\xf8"), \ + _PyUnicode_LATIN1_INIT("\xf9"), \ + _PyUnicode_LATIN1_INIT("\xfa"), \ + _PyUnicode_LATIN1_INIT("\xfb"), \ + _PyUnicode_LATIN1_INIT("\xfc"), \ + _PyUnicode_LATIN1_INIT("\xfd"), \ + _PyUnicode_LATIN1_INIT("\xfe"), \ + _PyUnicode_LATIN1_INIT("\xff"), \ + }, \ }, \ \ .tuple_empty = { \ diff --git a/Include/internal/pycore_unicodeobject.h b/Include/internal/pycore_unicodeobject.h index 977bbeb191712..4394ce939b567 100644 --- a/Include/internal/pycore_unicodeobject.h +++ b/Include/internal/pycore_unicodeobject.h @@ -44,9 +44,6 @@ struct _Py_unicode_ids { }; struct _Py_unicode_state { - /* Single character Unicode strings in the Latin-1 range are being - shared as well. */ - PyObject *latin1[256]; struct _Py_unicode_fs_codec fs_codec; // Unicode identifiers (_Py_Identifier): see _PyUnicode_FromId() diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-03-09-08-17.bpo-46881.ckD4tT.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-03-09-08-17.bpo-46881.ckD4tT.rst new file mode 100644 index 0000000000000..88434dd1dba97 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-03-09-08-17.bpo-46881.ckD4tT.rst @@ -0,0 +1 @@ +Statically allocate and initialize the latin1 characters. diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 908ad51492599..9052c53f11b8e 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -206,6 +206,11 @@ extern "C" { *_to++ = (to_type) *_iter++; \ } while (0) +#define LATIN1(ch) \ + (ch < 128 \ + ? (PyObject*)&_Py_SINGLETON(strings).ascii[ch] \ + : (PyObject*)&_Py_SINGLETON(strings).latin1[ch - 128]) + #ifdef MS_WINDOWS /* On Windows, overallocate by 50% is the best factor */ # define OVERALLOCATE_FACTOR 2 @@ -249,14 +254,6 @@ static int unicode_is_singleton(PyObject *unicode); #endif -static struct _Py_unicode_state* -get_unicode_state(void) -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - return &interp->unicode; -} - - // Return a borrowed reference to the empty string singleton. static inline PyObject* unicode_get_empty(void) { @@ -680,24 +677,10 @@ unicode_result_ready(PyObject *unicode) if (kind == PyUnicode_1BYTE_KIND) { const Py_UCS1 *data = PyUnicode_1BYTE_DATA(unicode); Py_UCS1 ch = data[0]; - struct _Py_unicode_state *state = get_unicode_state(); - PyObject *latin1_char = state->latin1[ch]; - if (latin1_char != NULL) { - if (unicode != latin1_char) { - Py_INCREF(latin1_char); - Py_DECREF(unicode); - } - return latin1_char; + if (unicode != LATIN1(ch)) { + Py_DECREF(unicode); } - else { - assert(_PyUnicode_CheckConsistency(unicode, 1)); - Py_INCREF(unicode); - state->latin1[ch] = unicode; - return unicode; - } - } - else { - assert(PyUnicode_READ_CHAR(unicode, 0) >= 256); + return get_latin1_char(ch); } } @@ -1990,11 +1973,10 @@ unicode_is_singleton(PyObject *unicode) return 1; } - struct _Py_unicode_state *state = get_unicode_state(); PyASCIIObject *ascii = (PyASCIIObject *)unicode; if (ascii->state.kind != PyUnicode_WCHAR_KIND && ascii->length == 1) { Py_UCS4 ch = PyUnicode_READ_CHAR(unicode, 0); - if (ch < 256 && state->latin1[ch] == unicode) { + if (ch < 256 && LATIN1(ch) == unicode) { return 1; } } @@ -2137,25 +2119,7 @@ unicode_write_cstr(PyObject *unicode, Py_ssize_t index, static PyObject* get_latin1_char(Py_UCS1 ch) { - struct _Py_unicode_state *state = get_unicode_state(); - - PyObject *unicode = state->latin1[ch]; - if (unicode) { - Py_INCREF(unicode); - return unicode; - } - - unicode = PyUnicode_New(1, ch); - if (!unicode) { - return NULL; - } - - PyUnicode_1BYTE_DATA(unicode)[0] = ch; - assert(_PyUnicode_CheckConsistency(unicode, 1)); - - Py_INCREF(unicode); - state->latin1[ch] = unicode; - return unicode; + return Py_NewRef(LATIN1(ch)); } static PyObject* @@ -15535,6 +15499,10 @@ _PyUnicode_InitGlobalObjects(PyInterpreterState *interp) #ifdef Py_DEBUG assert(_PyUnicode_CheckConsistency(&_Py_STR(empty), 1)); + + for (int i = 0; i < 256; i++) { + assert(_PyUnicode_CheckConsistency(LATIN1(i), 1)); + } #endif return _PyStatus_OK(); @@ -16113,10 +16081,6 @@ _PyUnicode_Fini(PyInterpreterState *interp) _PyUnicode_FiniEncodings(&state->fs_codec); unicode_clear_identifiers(state); - - for (Py_ssize_t i = 0; i < 256; i++) { - Py_CLEAR(state->latin1[i]); - } } diff --git a/Tools/scripts/generate_global_objects.py b/Tools/scripts/generate_global_objects.py index 867358cda8919..17ddb8b324a0b 100644 --- a/Tools/scripts/generate_global_objects.py +++ b/Tools/scripts/generate_global_objects.py @@ -196,6 +196,13 @@ def generate_global_strings(identifiers, strings): for name in sorted(identifiers): assert name.isidentifier(), name printer.write(f'STRUCT_FOR_ID({name})') + with printer.block('struct', ' ascii[128];'): + printer.write("PyASCIIObject _ascii;") + printer.write("uint8_t _data[2];") + with printer.block('struct', ' latin1[128];'): + printer.write("PyCompactUnicodeObject _latin1;") + printer.write("uint8_t _data[2];") + printer.write(END) printer.write(after) @@ -252,6 +259,12 @@ def generate_runtime_init(identifiers, strings): for name in sorted(identifiers): assert name.isidentifier(), name printer.write(f'INIT_ID({name}),') + with printer.block('.ascii =', ','): + for i in range(128): + printer.write(f'_PyASCIIObject_INIT("\\x{i:02x}"),') + with printer.block('.latin1 =', ','): + for i in range(128, 256): + printer.write(f'_PyUnicode_LATIN1_INIT("\\x{i:02x}"),') printer.write('') with printer.block('.tuple_empty =', ','): printer.write('.ob_base = _PyVarObject_IMMORTAL_INIT(&PyTuple_Type, 0)') From webhook-mailer at python.org Thu Mar 10 07:44:05 2022 From: webhook-mailer at python.org (tiran) Date: Thu, 10 Mar 2022 12:44:05 -0000 Subject: [Python-checkins] bpo-40280: Skip more tests/features that don't apply to Emscripten (GH-31791) Message-ID: https://github.com/python/cpython/commit/de554d6e02228b840eb6bffaf7d406c0ef368d5f commit: de554d6e02228b840eb6bffaf7d406c0ef368d5f branch: main author: Christian Heimes committer: tiran date: 2022-03-10T13:43:40+01:00 summary: bpo-40280: Skip more tests/features that don't apply to Emscripten (GH-31791) - fd inheritance can't be modified because Emscripten doesn't support subprocesses anyway. - setpriority always fails - geteuid no longer causes problems with latest emsdk - umask is a stub - geteuid / getuid always return 0, but process cannot chown to random uid. files: M Lib/test/support/__init__.py M Lib/test/test_os.py M Lib/test/test_pathlib.py M Lib/test/test_posix.py M Lib/test/test_tarfile.py M Tools/wasm/config.site-wasm32-emscripten diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index d80472d8776f6..865fb976f532e 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -517,7 +517,7 @@ def requires_fork(): has_subprocess_support = not is_emscripten and not is_wasi def requires_subprocess(): - """Used for subprocess, os.spawn calls""" + """Used for subprocess, os.spawn calls, fd inheritance""" return unittest.skipUnless(has_subprocess_support, "requires subprocess support") diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 4800291023233..ae8d930a95253 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -2192,6 +2192,7 @@ def test_write(self): def test_writev(self): self.check(os.writev, [b'abc']) + @support.requires_subprocess() def test_inheritable(self): self.check(os.get_inheritable) self.check(os.set_inheritable, True) @@ -3866,6 +3867,8 @@ def test_cpu_count(self): self.skipTest("Could not determine the number of CPUs") +# FD inheritance check is only useful for systems with process support. + at support.requires_subprocess() class FDInheritanceTests(unittest.TestCase): def test_get_set_inheritable(self): fd = os.open(__file__, os.O_RDONLY) diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 713d27908e756..66e44479239cf 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -13,6 +13,7 @@ from unittest import mock from test.support import import_helper +from test.support import is_emscripten from test.support import os_helper from test.support.os_helper import TESTFN, FakePath @@ -2158,6 +2159,7 @@ def test_mkdir_exist_ok_with_parent(self): self.assertTrue(p.exists()) self.assertEqual(p.stat().st_ctime, st_ctime_first) + @unittest.skipIf(is_emscripten, "FS root cannot be modified on Emscripten.") def test_mkdir_exist_ok_root(self): # Issue #25803: A drive root could raise PermissionError on Windows. self.cls('/').resolve().mkdir(exist_ok=True) @@ -2342,6 +2344,9 @@ def test_is_socket_false(self): self.assertIs((P / 'fileA\x00').is_socket(), False) @unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required") + @unittest.skipIf( + is_emscripten, "Unix sockets are not implemented on Emscripten." + ) def test_is_socket_true(self): P = self.cls(BASE, 'mysock') sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) @@ -2497,6 +2502,9 @@ def _check_symlink_loop(self, *args, strict=True): with self.assertRaises(RuntimeError): print(path.resolve(strict)) + @unittest.skipIf( + is_emscripten, "umask is not implemented on Emscripten." + ) def test_open_mode(self): old_mask = os.umask(0) self.addCleanup(os.umask, old_mask) @@ -2520,6 +2528,9 @@ def test_resolve_root(self): finally: os.chdir(current_directory) + @unittest.skipIf( + is_emscripten, "umask is not implemented on Emscripten." + ) def test_touch_mode(self): old_mask = os.umask(0) self.addCleanup(os.umask, old_mask) diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 395f065234519..c10039b17f7f8 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -30,8 +30,11 @@ _DUMMY_SYMLINK = os.path.join(tempfile.gettempdir(), os_helper.TESTFN + '-dummy-symlink') -requires_32b = unittest.skipUnless(sys.maxsize < 2**32, - 'test is only meaningful on 32-bit builds') +requires_32b = unittest.skipUnless( + # Emscripten has 32 bits pointers, but support 64 bits syscall args. + sys.maxsize < 2**32 and not support.is_emscripten, + 'test is only meaningful on 32-bit builds' +) def _supports_sched(): if not hasattr(posix, 'sched_getscheduler'): @@ -578,6 +581,7 @@ def test_dup2(self): @unittest.skipUnless(hasattr(os, 'O_CLOEXEC'), "needs os.O_CLOEXEC") @support.requires_linux_version(2, 6, 23) + @support.requires_subprocess() def test_oscloexec(self): fd = os.open(os_helper.TESTFN, os.O_RDONLY|os.O_CLOEXEC) self.addCleanup(os.close, fd) @@ -737,7 +741,11 @@ def check_stat(uid, gid): is_root = (uid in (0, 1)) else: is_root = (uid == 0) - if is_root: + if support.is_emscripten: + # Emscripten getuid() / geteuid() always return 0 (root), but + # cannot chown uid/gid to random value. + pass + elif is_root: # Try an amusingly large uid/gid to make sure we handle # large unsigned values. (chown lets you use any # uid/gid you like, even if they aren't defined.) diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index 0a67bcb0b09d7..12850cd635e99 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -1498,6 +1498,7 @@ def test_stream_padding(self): @unittest.skipUnless(sys.platform != "win32" and hasattr(os, "umask"), "Missing umask implementation") + @unittest.skipIf(support.is_emscripten, "Emscripten's umask is a stub.") def test_file_mode(self): # Test for issue #8464: Create files with correct # permissions. diff --git a/Tools/wasm/config.site-wasm32-emscripten b/Tools/wasm/config.site-wasm32-emscripten index f85024e21720f..5eaa7933776a8 100644 --- a/Tools/wasm/config.site-wasm32-emscripten +++ b/Tools/wasm/config.site-wasm32-emscripten @@ -62,6 +62,7 @@ ac_cv_func_pwritev2=no ac_cv_func_pwritev=no ac_cv_func_pipe2=no ac_cv_func_nice=no +ac_cv_func_setpriority=no ac_cv_func_setitimer=no # unsupported syscall: __syscall_prlimit64 ac_cv_func_prlimit=no @@ -92,11 +93,6 @@ ac_cv_func_setgroups=no ac_cv_func_setresuid=no ac_cv_func_setresgid=no -# Emscripten geteuid() / getegid() always return 0 (root), which breaks -# assumption in tarfile module and some tests. -ac_cv_func_getegid=no -ac_cv_func_geteuid=no - # Emscripten does not support hard links, always fails with errno 34 # "Too many links". See emscripten_syscall_stubs.c ac_cv_func_link=no From webhook-mailer at python.org Thu Mar 10 08:37:48 2022 From: webhook-mailer at python.org (vstinner) Date: Thu, 10 Mar 2022 13:37:48 -0000 Subject: [Python-checkins] bpo-46917: Require IEEE 754 to build Python (GH-31790) Message-ID: https://github.com/python/cpython/commit/9b51fd5d137b662c940f072297b30815f37f105b commit: 9b51fd5d137b662c940f072297b30815f37f105b branch: main author: Victor Stinner committer: vstinner date: 2022-03-10T14:37:19+01:00 summary: bpo-46917: Require IEEE 754 to build Python (GH-31790) Building Python now requires support of IEEE 754 floating point numbers. files: A Misc/NEWS.d/next/Build/2022-03-10-09-37-05.bpo-46917.fry4aK.rst M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 4514de9c07c9e..0e3ccb62cbf39 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -645,6 +645,9 @@ Build Changes * Building Python now requires a C11 compiler without optional C11 features. (Contributed by Victor Stinner in :issue:`46656`.) +* Building Python now requires support of IEEE 754 floating point numbers. + (Contributed by Victor Stinner in :issue:`46917`.) + * CPython can now be built with the ThinLTO option via ``--with-lto=thin``. (Contributed by Dong-hee Na and Brett Holman in :issue:`44340`.) diff --git a/Misc/NEWS.d/next/Build/2022-03-10-09-37-05.bpo-46917.fry4aK.rst b/Misc/NEWS.d/next/Build/2022-03-10-09-37-05.bpo-46917.fry4aK.rst new file mode 100644 index 0000000000000..fbb7891cae1a5 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2022-03-10-09-37-05.bpo-46917.fry4aK.rst @@ -0,0 +1,2 @@ +Building Python now requires support of IEEE 754 floating point numbers. +Patch by Victor Stinner. From webhook-mailer at python.org Thu Mar 10 09:42:43 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Thu, 10 Mar 2022 14:42:43 -0000 Subject: [Python-checkins] bpo-46581: Propagate private vars via _GenericAlias.copy_with (GH-31061) Message-ID: https://github.com/python/cpython/commit/32bf3597922ac3f613989582afa2bff43bea8a2f commit: 32bf3597922ac3f613989582afa2bff43bea8a2f branch: main author: Matt Bogosian committer: serhiy-storchaka date: 2022-03-10T16:42:15+02:00 summary: bpo-46581: Propagate private vars via _GenericAlias.copy_with (GH-31061) GH-26091 added the _typevar_types and _paramspec_tvars instance variables to _GenericAlias. However, they were not propagated consistently. This commit addresses the most prominent deficiency identified in bpo-46581 (namely their absence from _GenericAlias.copy_with), but there could be others. Co-authored-by: Ken Jin <28750310+Fidget-Spinner at users.noreply.github.com> Co-authored-by: Serhiy Storchaka files: A Misc/NEWS.d/next/Library/2022-02-01-11-32-47.bpo-46581.t7Zw65.rst M Lib/test/test_typing.py M Lib/typing.py M Misc/ACKS diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 5c1e907070ee4..fc596e4d90b21 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -5793,6 +5793,27 @@ def test_paramspec_in_nested_generics(self): self.assertEqual(G2[[int, str], float], list[C]) self.assertEqual(G3[[int, str], float], list[C] | int) + def test_paramspec_gets_copied(self): + # bpo-46581 + P = ParamSpec('P') + P2 = ParamSpec('P2') + C1 = Callable[P, int] + self.assertEqual(C1.__parameters__, (P,)) + self.assertEqual(C1[P2].__parameters__, (P2,)) + self.assertEqual(C1[str].__parameters__, ()) + self.assertEqual(C1[str, T].__parameters__, (T,)) + self.assertEqual(C1[Concatenate[str, P2]].__parameters__, (P2,)) + self.assertEqual(C1[Concatenate[T, P2]].__parameters__, (T, P2)) + self.assertEqual(C1[...].__parameters__, ()) + + C2 = Callable[Concatenate[str, P], int] + self.assertEqual(C2.__parameters__, (P,)) + self.assertEqual(C2[P2].__parameters__, (P2,)) + self.assertEqual(C2[str].__parameters__, ()) + self.assertEqual(C2[str, T].__parameters__, (T,)) + self.assertEqual(C2[Concatenate[str, P2]].__parameters__, (P2,)) + self.assertEqual(C2[Concatenate[T, P2]].__parameters__, (T, P2)) + class ConcatenateTests(BaseTestCase): def test_basics(self): diff --git a/Lib/typing.py b/Lib/typing.py index abb8bcefc5c04..e3015563b3e8c 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -670,7 +670,9 @@ def Concatenate(self, parameters): "ParamSpec variable.") msg = "Concatenate[arg, ...]: each arg must be a type." parameters = (*(_type_check(p, msg) for p in parameters[:-1]), parameters[-1]) - return _ConcatenateGenericAlias(self, parameters) + return _ConcatenateGenericAlias(self, parameters, + _typevar_types=(TypeVar, ParamSpec), + _paramspec_tvars=True) @_SpecialForm @@ -1339,7 +1341,9 @@ def _determine_new_args(self, args): return tuple(new_args) def copy_with(self, args): - return self.__class__(self.__origin__, args, name=self._name, inst=self._inst) + return self.__class__(self.__origin__, args, name=self._name, inst=self._inst, + _typevar_types=self._typevar_types, + _paramspec_tvars=self._paramspec_tvars) def __repr__(self): if self._name: @@ -1548,11 +1552,6 @@ def __hash__(self): class _ConcatenateGenericAlias(_GenericAlias, _root=True): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs, - _typevar_types=(TypeVar, ParamSpec), - _paramspec_tvars=True) - def copy_with(self, params): if isinstance(params[-1], (list, tuple)): return (*params[:-1], *params[-1]) diff --git a/Misc/ACKS b/Misc/ACKS index df851bb834cd4..84fcb322d4086 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -190,6 +190,7 @@ Paul Boddie Matthew Boedicker Robin Boerdijk Andra Bogildea +Matt Bogosian Nikolay Bogoychev David Bolen Wouter Bolsterlee diff --git a/Misc/NEWS.d/next/Library/2022-02-01-11-32-47.bpo-46581.t7Zw65.rst b/Misc/NEWS.d/next/Library/2022-02-01-11-32-47.bpo-46581.t7Zw65.rst new file mode 100644 index 0000000000000..1982c1d70093f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-02-01-11-32-47.bpo-46581.t7Zw65.rst @@ -0,0 +1,2 @@ +Brings :class:`ParamSpec` propagation for :class:`GenericAlias` in line with +:class:`Concatenate` (and others). From webhook-mailer at python.org Thu Mar 10 11:05:38 2022 From: webhook-mailer at python.org (gvanrossum) Date: Thu, 10 Mar 2022 16:05:38 -0000 Subject: [Python-checkins] bpo-46771: Implement asyncio context managers for handling timeouts (GH-31394) Message-ID: https://github.com/python/cpython/commit/f537b2a4fb86445ee3bd6ca7f10bc9d3a9f37da5 commit: f537b2a4fb86445ee3bd6ca7f10bc9d3a9f37da5 branch: main author: Andrew Svetlov committer: gvanrossum date: 2022-03-10T08:05:20-08:00 summary: bpo-46771: Implement asyncio context managers for handling timeouts (GH-31394) Example: async with asyncio.timeout(5): await some_task() Will interrupt the await and raise TimeoutError if some_task() takes longer than 5 seconds. Co-authored-by: Guido van Rossum files: A Lib/asyncio/timeouts.py A Lib/test/test_asyncio/test_timeouts.py A Misc/NEWS.d/next/Library/2022-02-21-11-41-23.bpo-464471.fL06TV.rst M Lib/asyncio/__init__.py diff --git a/Lib/asyncio/__init__.py b/Lib/asyncio/__init__.py index db1124cc9bd1e..fed16ec7c67fa 100644 --- a/Lib/asyncio/__init__.py +++ b/Lib/asyncio/__init__.py @@ -18,6 +18,7 @@ from .subprocess import * from .tasks import * from .taskgroups import * +from .timeouts import * from .threads import * from .transports import * @@ -34,6 +35,7 @@ subprocess.__all__ + tasks.__all__ + threads.__all__ + + timeouts.__all__ + transports.__all__) if sys.platform == 'win32': # pragma: no cover diff --git a/Lib/asyncio/timeouts.py b/Lib/asyncio/timeouts.py new file mode 100644 index 0000000000000..a89205348ff24 --- /dev/null +++ b/Lib/asyncio/timeouts.py @@ -0,0 +1,151 @@ +import enum + +from types import TracebackType +from typing import final, Optional, Type + +from . import events +from . import exceptions +from . import tasks + + +__all__ = ( + "Timeout", + "timeout", + "timeout_at", +) + + +class _State(enum.Enum): + CREATED = "created" + ENTERED = "active" + EXPIRING = "expiring" + EXPIRED = "expired" + EXITED = "finished" + + + at final +class Timeout: + + def __init__(self, when: Optional[float]) -> None: + self._state = _State.CREATED + + self._timeout_handler: Optional[events.TimerHandle] = None + self._task: Optional[tasks.Task] = None + self._when = when + + def when(self) -> Optional[float]: + return self._when + + def reschedule(self, when: Optional[float]) -> None: + assert self._state is not _State.CREATED + if self._state is not _State.ENTERED: + raise RuntimeError( + f"Cannot change state of {self._state.value} Timeout", + ) + + self._when = when + + if self._timeout_handler is not None: + self._timeout_handler.cancel() + + if when is None: + self._timeout_handler = None + else: + loop = events.get_running_loop() + self._timeout_handler = loop.call_at( + when, + self._on_timeout, + ) + + def expired(self) -> bool: + """Is timeout expired during execution?""" + return self._state in (_State.EXPIRING, _State.EXPIRED) + + def __repr__(self) -> str: + info = [''] + if self._state is _State.ENTERED: + when = round(self._when, 3) if self._when is not None else None + info.append(f"when={when}") + info_str = ' '.join(info) + return f"" + + async def __aenter__(self) -> "Timeout": + self._state = _State.ENTERED + self._task = tasks.current_task() + if self._task is None: + raise RuntimeError("Timeout should be used inside a task") + self.reschedule(self._when) + return self + + async def __aexit__( + self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType], + ) -> Optional[bool]: + assert self._state in (_State.ENTERED, _State.EXPIRING) + + if self._timeout_handler is not None: + self._timeout_handler.cancel() + self._timeout_handler = None + + if self._state is _State.EXPIRING: + self._state = _State.EXPIRED + + if self._task.uncancel() == 0 and exc_type is exceptions.CancelledError: + # Since there are no outstanding cancel requests, we're + # handling this. + raise TimeoutError + elif self._state is _State.ENTERED: + self._state = _State.EXITED + + return None + + def _on_timeout(self) -> None: + assert self._state is _State.ENTERED + self._task.cancel() + self._state = _State.EXPIRING + # drop the reference early + self._timeout_handler = None + + +def timeout(delay: Optional[float]) -> Timeout: + """Timeout async context manager. + + Useful in cases when you want to apply timeout logic around block + of code or in cases when asyncio.wait_for is not suitable. For example: + + >>> async with asyncio.timeout(10): # 10 seconds timeout + ... await long_running_task() + + + delay - value in seconds or None to disable timeout logic + + long_running_task() is interrupted by raising asyncio.CancelledError, + the top-most affected timeout() context manager converts CancelledError + into TimeoutError. + """ + loop = events.get_running_loop() + return Timeout(loop.time() + delay if delay is not None else None) + + +def timeout_at(when: Optional[float]) -> Timeout: + """Schedule the timeout at absolute time. + + Like timeout() but argument gives absolute time in the same clock system + as loop.time(). + + Please note: it is not POSIX time but a time with + undefined starting base, e.g. the time of the system power on. + + >>> async with asyncio.timeout_at(loop.time() + 10): + ... await long_running_task() + + + when - a deadline when timeout occurs or None to disable timeout logic + + long_running_task() is interrupted by raising asyncio.CancelledError, + the top-most affected timeout() context manager converts CancelledError + into TimeoutError. + """ + return Timeout(when) diff --git a/Lib/test/test_asyncio/test_timeouts.py b/Lib/test/test_asyncio/test_timeouts.py new file mode 100644 index 0000000000000..ef1ab0acb390d --- /dev/null +++ b/Lib/test/test_asyncio/test_timeouts.py @@ -0,0 +1,229 @@ +"""Tests for asyncio/timeouts.py""" + +import unittest +import time + +import asyncio +from asyncio import tasks + + +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + +class TimeoutTests(unittest.IsolatedAsyncioTestCase): + + async def test_timeout_basic(self): + with self.assertRaises(TimeoutError): + async with asyncio.timeout(0.01) as cm: + await asyncio.sleep(10) + self.assertTrue(cm.expired()) + + async def test_timeout_at_basic(self): + loop = asyncio.get_running_loop() + + with self.assertRaises(TimeoutError): + deadline = loop.time() + 0.01 + async with asyncio.timeout_at(deadline) as cm: + await asyncio.sleep(10) + self.assertTrue(cm.expired()) + self.assertEqual(deadline, cm.when()) + + async def test_nested_timeouts(self): + loop = asyncio.get_running_loop() + cancelled = False + with self.assertRaises(TimeoutError): + deadline = loop.time() + 0.01 + async with asyncio.timeout_at(deadline) as cm1: + # Only the topmost context manager should raise TimeoutError + try: + async with asyncio.timeout_at(deadline) as cm2: + await asyncio.sleep(10) + except asyncio.CancelledError: + cancelled = True + raise + self.assertTrue(cancelled) + self.assertTrue(cm1.expired()) + 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): + try: + await asyncio.sleep(10) + except asyncio.CancelledError: + cancelled = True + raise + self.assertTrue(cancelled) + + 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() + t0 = loop.time() + with self.assertRaises(TimeoutError): + async with asyncio.timeout(0) as cm: + 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_foreign_exception_passed(self): + with self.assertRaises(KeyError): + async with asyncio.timeout(0.01) as cm: + raise KeyError + self.assertFalse(cm.expired()) + + async def test_foreign_exception_on_timeout(self): + async def crash(): + try: + await asyncio.sleep(1) + finally: + 1/0 + with self.assertRaises(ZeroDivisionError): + async with asyncio.timeout(0.01): + await crash() + + async def test_foreign_cancel_doesnt_timeout_if_not_expired(self): + with self.assertRaises(asyncio.CancelledError): + async with asyncio.timeout(10) as cm: + asyncio.current_task().cancel() + await asyncio.sleep(10) + self.assertFalse(cm.expired()) + + async def test_outer_task_is_not_cancelled(self): + async def outer() -> None: + with self.assertRaises(TimeoutError): + async with asyncio.timeout(0.001): + await asyncio.sleep(10) + + task = asyncio.create_task(outer()) + await task + self.assertFalse(task.cancelled()) + self.assertTrue(task.done()) + + async def test_nested_timeouts_concurrent(self): + with self.assertRaises(TimeoutError): + async with asyncio.timeout(0.002): + with self.assertRaises(TimeoutError): + async with asyncio.timeout(0.1): + # Pretend we crunch some numbers. + time.sleep(0.01) + await asyncio.sleep(1) + + async def test_nested_timeouts_loop_busy(self): + # After the inner timeout is an expensive operation which should + # be stopped by the outer timeout. + loop = asyncio.get_running_loop() + # Disable a message about long running task + loop.slow_callback_duration = 10 + t0 = loop.time() + with self.assertRaises(TimeoutError): + async with asyncio.timeout(0.1): # (1) + with self.assertRaises(TimeoutError): + async with asyncio.timeout(0.01): # (2) + # Pretend the loop is busy for a while. + time.sleep(0.1) + await asyncio.sleep(1) + # TimeoutError was cought by (2) + await asyncio.sleep(10) # This sleep should be interrupted by (1) + t1 = loop.time() + self.assertTrue(t0 <= t1 <= t0 + 1) + + async def test_reschedule(self): + loop = asyncio.get_running_loop() + fut = loop.create_future() + deadline1 = loop.time() + 10 + deadline2 = deadline1 + 20 + + async def f(): + async with asyncio.timeout_at(deadline1) as cm: + fut.set_result(cm) + await asyncio.sleep(50) + + task = asyncio.create_task(f()) + cm = await fut + + self.assertEqual(cm.when(), deadline1) + cm.reschedule(deadline2) + self.assertEqual(cm.when(), deadline2) + cm.reschedule(None) + self.assertIsNone(cm.when()) + + task.cancel() + + with self.assertRaises(asyncio.CancelledError): + await task + self.assertFalse(cm.expired()) + + async def test_repr_active(self): + async with asyncio.timeout(10) as cm: + self.assertRegex(repr(cm), r"") + + async def test_repr_expired(self): + with self.assertRaises(TimeoutError): + async with asyncio.timeout(0.01) as cm: + await asyncio.sleep(10) + self.assertEqual(repr(cm), "") + + async def test_repr_finished(self): + async with asyncio.timeout(10) as cm: + await asyncio.sleep(0) + + self.assertEqual(repr(cm), "") + + async def test_repr_disabled(self): + async with asyncio.timeout(None) as cm: + self.assertEqual(repr(cm), r"") + + async def test_nested_timeout_in_finally(self): + with self.assertRaises(TimeoutError): + async with asyncio.timeout(0.01): + try: + await asyncio.sleep(1) + finally: + with self.assertRaises(TimeoutError): + async with asyncio.timeout(0.01): + await asyncio.sleep(10) + + +if __name__ == '__main__': + unittest.main() diff --git a/Misc/NEWS.d/next/Library/2022-02-21-11-41-23.bpo-464471.fL06TV.rst b/Misc/NEWS.d/next/Library/2022-02-21-11-41-23.bpo-464471.fL06TV.rst new file mode 100644 index 0000000000000..b8a48d658250f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-02-21-11-41-23.bpo-464471.fL06TV.rst @@ -0,0 +1,2 @@ +:func:`asyncio.timeout` and :func:`asyncio.timeout_at` context managers +added. Patch by Tin Tvrtkovi? and Andrew Svetlov. From webhook-mailer at python.org Thu Mar 10 11:20:24 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Thu, 10 Mar 2022 16:20:24 -0000 Subject: [Python-checkins] bpo-46198: rename duplicate tests and remove unused code (GH-30297) Message-ID: https://github.com/python/cpython/commit/6c83c8e6b56b57a8a794e7b6c07837be4ce3bb97 commit: 6c83c8e6b56b57a8a794e7b6c07837be4ce3bb97 branch: main author: Nikita Sobolev committer: JelleZijlstra date: 2022-03-10T08:20:11-08:00 summary: bpo-46198: rename duplicate tests and remove unused code (GH-30297) files: M Lib/test/datetimetester.py M Lib/test/support/__init__.py M Lib/test/test_asyncio/test_sslproto.py M Lib/test/test_codecs.py M Lib/test/test_compile.py M Lib/test/test_dict.py M Lib/test/test_email/test__header_value_parser.py M Lib/test/test_enum.py M Lib/test/test_pty.py M Lib/test/test_tabnanny.py diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index 810478c7db2be..df3764d61b186 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -1864,8 +1864,6 @@ def test_fromisoformat_fails(self): def test_fromisoformat_fails_typeerror(self): # Test that fromisoformat fails when passed the wrong type - import io - bad_types = [b'2009-03-01', None, io.StringIO('2009-03-01')] for bad_type in bad_types: with self.assertRaises(TypeError): @@ -3988,8 +3986,6 @@ def test_fromisoformat_fails(self): def test_fromisoformat_fails_typeerror(self): # Test the fromisoformat fails when passed the wrong type - import io - bad_types = [b'12:30:45', None, io.StringIO('12:30:45')] for bad_type in bad_types: diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 865fb976f532e..c7bee8be662cc 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -1442,9 +1442,6 @@ def __init__(self, link=None): self._platform_specific() - def _platform_specific(self): - pass - if sys.platform == "win32": def _platform_specific(self): import glob @@ -1472,6 +1469,9 @@ def _platform_specific(self): self._env["PYTHONHOME"] = os.path.dirname(self.real) if sysconfig.is_python_build(True): self._env["PYTHONPATH"] = STDLIB_DIR + else: + def _platform_specific(self): + pass def __enter__(self): os.symlink(self.real, self.link) diff --git a/Lib/test/test_asyncio/test_sslproto.py b/Lib/test/test_asyncio/test_sslproto.py index 6e8de7c84c0aa..4095b4dfa84eb 100644 --- a/Lib/test/test_asyncio/test_sslproto.py +++ b/Lib/test/test_asyncio/test_sslproto.py @@ -2,7 +2,6 @@ import logging import socket -from test import support import unittest import weakref from unittest import mock diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index 8118ec6f4727b..5853e08819715 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -36,7 +36,7 @@ def check(input, expect): # On small versions of Windows like Windows IoT or Windows Nano Server not all codepages are present def is_code_page_present(cp): from ctypes import POINTER, WINFUNCTYPE, WinDLL - from ctypes.wintypes import BOOL, UINT, BYTE, WCHAR, UINT, DWORD + from ctypes.wintypes import BOOL, BYTE, WCHAR, UINT, DWORD MAX_LEADBYTES = 12 # 5 ranges, 2 bytes ea., 0 term. MAX_DEFAULTCHAR = 2 # single or double byte diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 79046b8615e3e..8499d2855bdd4 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -1189,7 +1189,7 @@ def test_func_kwargs(self): kwargs = (f'a{i}=x' for i in range(self.N)) self.check_stack_size("f(" + ", ".join(kwargs) + ")") - def test_func_args(self): + def test_meth_args(self): self.check_stack_size("o.m(" + "x, " * self.N + ")") def test_meth_kwargs(self): diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index e60ae4309cbc1..5b8baaf9e6e28 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -1455,7 +1455,7 @@ def test_dict_items_result_gc(self): self.assertTrue(gc.is_tracked(next(it))) @support.cpython_only - def test_dict_items_result_gc(self): + def test_dict_items_result_gc_reversed(self): # Same as test_dict_items_result_gc above, but reversed. it = reversed({None: []}.items()) gc.collect() diff --git a/Lib/test/test_email/test__header_value_parser.py b/Lib/test/test_email/test__header_value_parser.py index 1bdcfa129b4c8..854f2ff009c61 100644 --- a/Lib/test/test_email/test__header_value_parser.py +++ b/Lib/test/test_email/test__header_value_parser.py @@ -395,7 +395,7 @@ def test_get_unstructured_without_trailing_whitespace_hang_case(self): [errors.InvalidHeaderDefect], '') - def test_get_unstructured_invalid_ew(self): + def test_get_unstructured_invalid_ew2(self): self._test_get_x(self._get_unst, '=?utf-8?q?=somevalue?=', '=?utf-8?q?=somevalue?=', diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index b8a7914355c53..f2572b2ac351a 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -3708,7 +3708,7 @@ class Sillier(IntEnum): triple = 3 value = 4 -class TestHelpers(unittest.TestCase): +class TestInternals(unittest.TestCase): sunder_names = '_bad_', '_good_', '_what_ho_' dunder_names = '__mal__', '__bien__', '__que_que__' diff --git a/Lib/test/test_pty.py b/Lib/test/test_pty.py index 0781cde1e1582..fa0dbcc16f3ce 100644 --- a/Lib/test/test_pty.py +++ b/Lib/test/test_pty.py @@ -17,7 +17,6 @@ import unittest import struct -import tty import fcntl import warnings diff --git a/Lib/test/test_tabnanny.py b/Lib/test/test_tabnanny.py index 59fdfc5573d37..e0a82e95c486b 100644 --- a/Lib/test/test_tabnanny.py +++ b/Lib/test/test_tabnanny.py @@ -4,7 +4,6 @@ * errored : Whitespace related problems present in file. """ from unittest import TestCase, mock -from unittest import mock import errno import os import tabnanny From webhook-mailer at python.org Thu Mar 10 11:41:05 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Thu, 10 Mar 2022 16:41:05 -0000 Subject: [Python-checkins] bpo-46677: Add examples of inheritance and attributes to `TypedDict` docs (GH-31349) Message-ID: https://github.com/python/cpython/commit/8a207e0321db75f3342692905e342f1d5e1add54 commit: 8a207e0321db75f3342692905e342f1d5e1add54 branch: main author: Charlie Zhao <68189100+CharlieZhao95 at users.noreply.github.com> committer: JelleZijlstra date: 2022-03-10T08:40:54-08:00 summary: bpo-46677: Add examples of inheritance and attributes to `TypedDict` docs (GH-31349) Co-authored-by: Jelle Zijlstra files: M Doc/library/typing.rst diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 935a261362658..0c23a233c0d7d 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1469,9 +1469,6 @@ These are not used in annotations. They are building blocks for declaring types. assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first') - The type info for introspection can be accessed via ``Point2D.__annotations__``, - ``Point2D.__total__``, ``Point2D.__required_keys__``, and - ``Point2D.__optional_keys__``. To allow using this feature with older versions of Python that do not support :pep:`526`, ``TypedDict`` supports two additional equivalent syntactic forms: @@ -1488,6 +1485,18 @@ These are not used in annotations. They are building blocks for declaring types. The keyword-argument syntax is deprecated in 3.11 and will be removed in 3.13. It may also be unsupported by static type checkers. + The functional syntax should also be used when any of the keys are not valid + :ref:`identifiers`, for example because they are keywords or contain hyphens. + Example:: + + # raises SyntaxError + class Point2D(TypedDict): + in: int # 'in' is a keyword + x-y: int # name with hyphens + + # OK, functional syntax + Point2D = TypedDict('Point2D', {'in': int, 'x-y': int}) + By default, all keys must be present in a ``TypedDict``. It is possible to override this by specifying totality. Usage:: @@ -1504,6 +1513,82 @@ These are not used in annotations. They are building blocks for declaring types. ``True`` as the value of the ``total`` argument. ``True`` is the default, and makes all items defined in the class body required. + It is possible for a ``TypedDict`` type to inherit from one or more other ``TypedDict`` types + using the class-based syntax. + Usage:: + + class Point3D(Point2D): + z: int + + ``Point3D`` has three items: ``x``, ``y`` and ``z``. It is equivalent to this + definition:: + + class Point3D(TypedDict): + x: int + y: int + z: int + + A ``TypedDict`` cannot inherit from a non-TypedDict class, + notably including :class:`Generic`. For example:: + + class X(TypedDict): + x: int + + class Y(TypedDict): + y: int + + class Z(object): pass # A non-TypedDict class + + class XY(X, Y): pass # OK + + class XZ(X, Z): pass # raises TypeError + + T = TypeVar('T') + class XT(X, Generic[T]): pass # raises TypeError + + A ``TypedDict`` can be introspected via annotations dicts + (see :ref:`annotations-howto` for more information on annotations best practices), + :attr:`__total__`, :attr:`__required_keys__`, and :attr:`__optional_keys__`. + + .. attribute:: __total__ + + ``Point2D.__total__`` gives the value of the ``total`` argument. + Example:: + + >>> from typing import TypedDict + >>> class Point2D(TypedDict): pass + >>> Point2D.__total__ + True + >>> class Point2D(TypedDict, total=False): pass + >>> Point2D.__total__ + False + >>> class Point3D(Point2D): pass + >>> Point3D.__total__ + True + + .. attribute:: __required_keys__ + .. attribute:: __optional_keys__ + + ``Point2D.__required_keys__`` and ``Point2D.__optional_keys__`` return + :class:`frozenset` objects containing required and non-required keys, respectively. + Currently the only way to declare both required and non-required keys in the + same ``TypedDict`` is mixed inheritance, declaring a ``TypedDict`` with one value + for the ``total`` argument and then inheriting it from another ``TypedDict`` with + a different value for ``total``. + Usage:: + + >>> class Point2D(TypedDict, total=False): + ... x: int + ... y: int + ... + >>> class Point3D(Point2D): + ... z: int + ... + >>> Point3D.__required_keys__ == frozenset({'z'}) + True + >>> Point3D.__optional_keys__ == frozenset({'x', 'y'}) + True + See :pep:`589` for more examples and detailed rules of using ``TypedDict``. .. versionadded:: 3.8 From webhook-mailer at python.org Thu Mar 10 11:47:27 2022 From: webhook-mailer at python.org (vstinner) Date: Thu, 10 Mar 2022 16:47:27 -0000 Subject: [Python-checkins] bpo-46917: math.nan is now always available (GH-31793) Message-ID: https://github.com/python/cpython/commit/7854012077009b9f364f198a8ae38b546ec58313 commit: 7854012077009b9f364f198a8ae38b546ec58313 branch: main author: Victor Stinner committer: vstinner date: 2022-03-10T17:47:18+01:00 summary: bpo-46917: math.nan is now always available (GH-31793) files: A Misc/NEWS.d/next/Library/2022-03-10-14-47-16.bpo-46917.s19zcy.rst M Doc/library/math.rst M Doc/whatsnew/3.11.rst diff --git a/Doc/library/math.rst b/Doc/library/math.rst index 1ad60459e8d37..bcbcdef51d3fc 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -649,6 +649,9 @@ Constants A floating-point "not a number" (NaN) value. Equivalent to the output of ``float('nan')``. + .. versionchanged:: 3.11 + It is now always available. + .. versionadded:: 3.5 diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 0e3ccb62cbf39..ce15fb72f3c49 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -254,6 +254,7 @@ inspect math ---- + * Add :func:`math.exp2`: return 2 raised to the power of x. (Contributed by Gideon Mitchell in :issue:`45917`.) @@ -266,6 +267,9 @@ math ``inf``. Previously they raised :exc:`ValueError`. (Contributed by Mark Dickinson in :issue:`44339`.) +* The :data:`math.nan` value is now always available. + (Contributed by Victor Stinner in :issue:`46917`.) + operator -------- diff --git a/Misc/NEWS.d/next/Library/2022-03-10-14-47-16.bpo-46917.s19zcy.rst b/Misc/NEWS.d/next/Library/2022-03-10-14-47-16.bpo-46917.s19zcy.rst new file mode 100644 index 0000000000000..3fbd84a428816 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-10-14-47-16.bpo-46917.s19zcy.rst @@ -0,0 +1 @@ +The :data:`math.nan` value is now always available. Patch by Victor Stinner. From webhook-mailer at python.org Thu Mar 10 12:01:34 2022 From: webhook-mailer at python.org (rhettinger) Date: Thu, 10 Mar 2022 17:01:34 -0000 Subject: [Python-checkins] Remove print race from task_done example. (GH-31795) Message-ID: https://github.com/python/cpython/commit/a0eb69c1a2e3aee75cb48e9868ef06a531b94a70 commit: a0eb69c1a2e3aee75cb48e9868ef06a531b94a70 branch: main author: Raymond Hettinger committer: rhettinger date: 2022-03-10T11:01:23-06:00 summary: Remove print race from task_done example. (GH-31795) files: M Doc/library/queue.rst diff --git a/Doc/library/queue.rst b/Doc/library/queue.rst index 0ec5900bef5bb..cbf27d2bb10d0 100644 --- a/Doc/library/queue.rst +++ b/Doc/library/queue.rst @@ -201,15 +201,14 @@ Example of how to wait for enqueued tasks to be completed:: print(f'Finished {item}') q.task_done() - # turn-on the worker thread + # Turn-on the worker thread. threading.Thread(target=worker, daemon=True).start() - # send thirty task requests to the worker + # Send thirty task requests to the worker. for item in range(30): q.put(item) - print('All task requests sent\n', end='') - # block until all tasks are done + # Block until all tasks are done. q.join() print('All work completed') From webhook-mailer at python.org Thu Mar 10 12:03:38 2022 From: webhook-mailer at python.org (tiran) Date: Thu, 10 Mar 2022 17:03:38 -0000 Subject: [Python-checkins] bpo-46973: Add regen-configure make target (GH-31792) Message-ID: https://github.com/python/cpython/commit/434ffb7f1f86e6b0cdfad3ede59993934d86e464 commit: 434ffb7f1f86e6b0cdfad3ede59993934d86e464 branch: main author: Christian Heimes committer: tiran date: 2022-03-10T18:03:27+01:00 summary: bpo-46973: Add regen-configure make target (GH-31792) files: A Misc/NEWS.d/next/Build/2022-03-10-14-30-39.bpo-46973._LEvnc.rst M .github/workflows/build.yml M Makefile.pre.in diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f6df74357d2f5..8b1709d37f9aa 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -74,12 +74,14 @@ jobs: grep "aclocal 1.16.3" aclocal.m4 grep -q "runstatedir" configure grep -q "PKG_PROG_PKG_CONFIG" aclocal.m4 - - name: Regenerate autoconf files - run: docker run --rm -v $(pwd):/src quay.io/tiran/cpython_autoconf:269 - - name: Build CPython + - name: Configure CPython run: | # Build Python with the libpython dynamic library ./configure --with-pydebug --enable-shared + - name: Regenerate autoconf files with container image + run: make regen-configure + - name: Build CPython + run: | make -j4 regen-all make regen-stdlib-module-names - name: Check for changes diff --git a/Makefile.pre.in b/Makefile.pre.in index 9deffadb8881d..c4034dc248c65 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1196,7 +1196,7 @@ regen-all: regen-opcode regen-opcode-targets regen-typeslots \ regen-pegen-metaparser regen-pegen regen-test-frozenmain \ regen-global-objects @echo - @echo "Note: make regen-stdlib-module-names and make autoconf should be run manually" + @echo "Note: make regen-stdlib-module-names and make regen-configure should be run manually" ############################################################################ # Special rules for object files @@ -2294,10 +2294,16 @@ recheck: # Regenerate configure and pyconfig.h.in .PHONY: autoconf autoconf: - # Regenerate the configure script from configure.ac using autoconf - (cd $(srcdir); autoconf -Wall) - # Regenerate pyconfig.h.in from configure.ac using autoheader - (cd $(srcdir); autoheader -Wall) + (cd $(srcdir); autoreconf -ivf -Werror) + +.PHONY: regen-configure +regen-configure: + @if command -v podman >/dev/null; then RUNTIME="podman"; else RUNTIME="docker"; fi; \ + if ! command -v $$RUNTIME; then echo "$@ needs either Podman or Docker container runtime." >&2; exit 1; fi; \ + if command -v selinuxenabled >/dev/null && selinuxenabled; then OPT=":Z"; fi; \ + CMD="$$RUNTIME run --rm --pull=always -v $(abs_srcdir):/src$$OPT quay.io/tiran/cpython_autoconf:269"; \ + echo $$CMD; \ + $$CMD || exit $? # Create a tags file for vi tags:: diff --git a/Misc/NEWS.d/next/Build/2022-03-10-14-30-39.bpo-46973._LEvnc.rst b/Misc/NEWS.d/next/Build/2022-03-10-14-30-39.bpo-46973._LEvnc.rst new file mode 100644 index 0000000000000..62d71d15fdcd2 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2022-03-10-14-30-39.bpo-46973._LEvnc.rst @@ -0,0 +1,2 @@ +Add ``regen-configure`` make target to regenerate configure script with +Christian's container image ``quay.io/tiran/cpython_autoconf:269``. From webhook-mailer at python.org Thu Mar 10 12:22:59 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 10 Mar 2022 17:22:59 -0000 Subject: [Python-checkins] Remove print race from task_done example. (GH-31795) Message-ID: https://github.com/python/cpython/commit/3386f87dcb2d305965293df18c6484de0dfa132d commit: 3386f87dcb2d305965293df18c6484de0dfa132d branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-10T09:22:46-08:00 summary: Remove print race from task_done example. (GH-31795) (cherry picked from commit a0eb69c1a2e3aee75cb48e9868ef06a531b94a70) Co-authored-by: Raymond Hettinger files: M Doc/library/queue.rst diff --git a/Doc/library/queue.rst b/Doc/library/queue.rst index 0ec5900bef5bb..cbf27d2bb10d0 100644 --- a/Doc/library/queue.rst +++ b/Doc/library/queue.rst @@ -201,15 +201,14 @@ Example of how to wait for enqueued tasks to be completed:: print(f'Finished {item}') q.task_done() - # turn-on the worker thread + # Turn-on the worker thread. threading.Thread(target=worker, daemon=True).start() - # send thirty task requests to the worker + # Send thirty task requests to the worker. for item in range(30): q.put(item) - print('All task requests sent\n', end='') - # block until all tasks are done + # Block until all tasks are done. q.join() print('All work completed') From webhook-mailer at python.org Thu Mar 10 16:18:31 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Thu, 10 Mar 2022 21:18:31 -0000 Subject: [Python-checkins] [3.9] bpo-46198: rename duplicate tests and remove unused code (GH-30297) (GH-31797) Message-ID: https://github.com/python/cpython/commit/f7f7838b41d45efa129a61f104136f8e12f3488a commit: f7f7838b41d45efa129a61f104136f8e12f3488a branch: 3.9 author: Jelle Zijlstra committer: JelleZijlstra date: 2022-03-10T13:18:27-08:00 summary: [3.9] bpo-46198: rename duplicate tests and remove unused code (GH-30297) (GH-31797) (cherry picked from commit 6c83c8e6b56b57a8a794e7b6c07837be4ce3bb97) Co-authored-by: Nikita Sobolev files: M Lib/test/datetimetester.py M Lib/test/support/__init__.py M Lib/test/test_asyncio/test_sslproto.py M Lib/test/test_codecs.py M Lib/test/test_dict.py M Lib/test/test_email/test__header_value_parser.py M Lib/test/test_tabnanny.py diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index 85241526739cb..361d5e9ba7e0a 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -1861,8 +1861,6 @@ def test_fromisoformat_fails(self): def test_fromisoformat_fails_typeerror(self): # Test that fromisoformat fails when passed the wrong type - import io - bad_types = [b'2009-03-01', None, io.StringIO('2009-03-01')] for bad_type in bad_types: with self.assertRaises(TypeError): @@ -3985,8 +3983,6 @@ def test_fromisoformat_fails(self): def test_fromisoformat_fails_typeerror(self): # Test the fromisoformat fails when passed the wrong type - import io - bad_types = [b'12:30:45', None, io.StringIO('12:30:45')] for bad_type in bad_types: diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index c4115a850b2e4..86ac8f096695f 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -2390,9 +2390,6 @@ def __init__(self, link=None): self._platform_specific() - def _platform_specific(self): - pass - if sys.platform == "win32": def _platform_specific(self): import _winapi @@ -2419,6 +2416,9 @@ def _platform_specific(self): self._env["PYTHONHOME"] = os.path.dirname(self.real) if sysconfig.is_python_build(True): self._env["PYTHONPATH"] = os.path.dirname(os.__file__) + else: + def _platform_specific(self): + pass def __enter__(self): os.symlink(self.real, self.link) diff --git a/Lib/test/test_asyncio/test_sslproto.py b/Lib/test/test_asyncio/test_sslproto.py index bc01a8bbf2d35..d658a00de96b5 100644 --- a/Lib/test/test_asyncio/test_sslproto.py +++ b/Lib/test/test_asyncio/test_sslproto.py @@ -2,7 +2,6 @@ import logging import socket -from test import support import unittest import weakref from unittest import mock diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index 2f7f93a29f662..fc50e70df24b9 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -30,7 +30,7 @@ def check(input, expect): # On small versions of Windows like Windows IoT or Windows Nano Server not all codepages are present def is_code_page_present(cp): from ctypes import POINTER, WINFUNCTYPE, WinDLL - from ctypes.wintypes import BOOL, UINT, BYTE, WCHAR, UINT, DWORD + from ctypes.wintypes import BOOL, BYTE, WCHAR, UINT, DWORD MAX_LEADBYTES = 12 # 5 ranges, 2 bytes ea., 0 term. MAX_DEFAULTCHAR = 2 # single or double byte diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index d05ed302ede84..a3014cb09f985 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -1435,7 +1435,7 @@ def test_dict_items_result_gc(self): self.assertTrue(gc.is_tracked(next(it))) @support.cpython_only - def test_dict_items_result_gc(self): + def test_dict_items_result_gc_reversed(self): # Same as test_dict_items_result_gc above, but reversed. it = reversed({None: []}.items()) gc.collect() diff --git a/Lib/test/test_email/test__header_value_parser.py b/Lib/test/test_email/test__header_value_parser.py index 1bdcfa129b4c8..854f2ff009c61 100644 --- a/Lib/test/test_email/test__header_value_parser.py +++ b/Lib/test/test_email/test__header_value_parser.py @@ -395,7 +395,7 @@ def test_get_unstructured_without_trailing_whitespace_hang_case(self): [errors.InvalidHeaderDefect], '') - def test_get_unstructured_invalid_ew(self): + def test_get_unstructured_invalid_ew2(self): self._test_get_x(self._get_unst, '=?utf-8?q?=somevalue?=', '=?utf-8?q?=somevalue?=', diff --git a/Lib/test/test_tabnanny.py b/Lib/test/test_tabnanny.py index 7f3308d745aa0..6dab678c33067 100644 --- a/Lib/test/test_tabnanny.py +++ b/Lib/test/test_tabnanny.py @@ -4,7 +4,6 @@ * errored : Whitespace related problems present in file. """ from unittest import TestCase, mock -from unittest import mock import errno import os import tabnanny From webhook-mailer at python.org Thu Mar 10 16:36:36 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Thu, 10 Mar 2022 21:36:36 -0000 Subject: [Python-checkins] bpo-46198: Fix `test_asyncio.test_sslproto` (GH-31801) Message-ID: https://github.com/python/cpython/commit/4052dd2296da2ff304b1fa787b100befffa1c9ca commit: 4052dd2296da2ff304b1fa787b100befffa1c9ca branch: main author: Alex Waygood committer: JelleZijlstra date: 2022-03-10T13:36:22-08:00 summary: bpo-46198: Fix `test_asyncio.test_sslproto` (GH-31801) GH-30297 removed a duplicate `from test import support` statement from `test_asyncio.test_sslproto`. However, in between that PR being filed and it being merged, GH-31275 removed the _other_ `from test import support` statement. This means that `support` is now undefined in `test_asyncio.test_sslproto`, causing the CI to fail on all platforms for all PRS. files: M Lib/test/test_asyncio/test_sslproto.py diff --git a/Lib/test/test_asyncio/test_sslproto.py b/Lib/test/test_asyncio/test_sslproto.py index 4095b4dfa84eb..52a45f1c7c6e9 100644 --- a/Lib/test/test_asyncio/test_sslproto.py +++ b/Lib/test/test_asyncio/test_sslproto.py @@ -4,6 +4,7 @@ import socket import unittest import weakref +from test import support from unittest import mock try: import ssl From webhook-mailer at python.org Thu Mar 10 16:53:59 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Thu, 10 Mar 2022 21:53:59 -0000 Subject: [Python-checkins] [3.10] bpo-46198: rename duplicate tests and remove unused code (GH-30297) (GH-31796) Message-ID: https://github.com/python/cpython/commit/4199b7ffbbaa5fe52a4c85c8672ac6773a75ba8f commit: 4199b7ffbbaa5fe52a4c85c8672ac6773a75ba8f branch: 3.10 author: Jelle Zijlstra committer: JelleZijlstra date: 2022-03-10T13:53:50-08:00 summary: [3.10] bpo-46198: rename duplicate tests and remove unused code (GH-30297) (GH-31796) (cherry picked from commit 6c83c8e6b56b57a8a794e7b6c07837be4ce3bb97) Co-authored-by: Nikita Sobolev files: M Lib/test/datetimetester.py M Lib/test/support/__init__.py M Lib/test/test_asyncio/test_sslproto.py M Lib/test/test_codecs.py M Lib/test/test_compile.py M Lib/test/test_dict.py M Lib/test/test_email/test__header_value_parser.py M Lib/test/test_pty.py M Lib/test/test_tabnanny.py diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index 9f551d9b9748d..58336595c1f57 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -1861,8 +1861,6 @@ def test_fromisoformat_fails(self): def test_fromisoformat_fails_typeerror(self): # Test that fromisoformat fails when passed the wrong type - import io - bad_types = [b'2009-03-01', None, io.StringIO('2009-03-01')] for bad_type in bad_types: with self.assertRaises(TypeError): @@ -3985,8 +3983,6 @@ def test_fromisoformat_fails(self): def test_fromisoformat_fails_typeerror(self): # Test the fromisoformat fails when passed the wrong type - import io - bad_types = [b'12:30:45', None, io.StringIO('12:30:45')] for bad_type in bad_types: diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index ed6f1979732d3..63435780c9a58 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -1381,9 +1381,6 @@ def __init__(self, link=None): self._platform_specific() - def _platform_specific(self): - pass - if sys.platform == "win32": def _platform_specific(self): import glob @@ -1411,6 +1408,9 @@ def _platform_specific(self): self._env["PYTHONHOME"] = os.path.dirname(self.real) if sysconfig.is_python_build(True): self._env["PYTHONPATH"] = os.path.dirname(os.__file__) + else: + def _platform_specific(self): + pass def __enter__(self): os.symlink(self.real, self.link) diff --git a/Lib/test/test_asyncio/test_sslproto.py b/Lib/test/test_asyncio/test_sslproto.py index 22a216a83e3f9..f7411a8142cc8 100644 --- a/Lib/test/test_asyncio/test_sslproto.py +++ b/Lib/test/test_asyncio/test_sslproto.py @@ -2,7 +2,6 @@ import logging import socket -from test import support import unittest import weakref from unittest import mock diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index f7310fbb1474a..a9c43d9554bea 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -32,7 +32,7 @@ def check(input, expect): # On small versions of Windows like Windows IoT or Windows Nano Server not all codepages are present def is_code_page_present(cp): from ctypes import POINTER, WINFUNCTYPE, WinDLL - from ctypes.wintypes import BOOL, UINT, BYTE, WCHAR, UINT, DWORD + from ctypes.wintypes import BOOL, BYTE, WCHAR, UINT, DWORD MAX_LEADBYTES = 12 # 5 ranges, 2 bytes ea., 0 term. MAX_DEFAULTCHAR = 2 # single or double byte diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 5f80a583450ea..9859d9a46710d 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -1023,7 +1023,7 @@ def test_func_kwargs(self): kwargs = (f'a{i}=x' for i in range(self.N)) self.check_stack_size("f(" + ", ".join(kwargs) + ")") - def test_func_args(self): + def test_meth_args(self): self.check_stack_size("o.m(" + "x, " * self.N + ")") def test_meth_kwargs(self): diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 54d100288cb62..8aad4a5967b34 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -1465,7 +1465,7 @@ def test_dict_items_result_gc(self): self.assertTrue(gc.is_tracked(next(it))) @support.cpython_only - def test_dict_items_result_gc(self): + def test_dict_items_result_gc_reversed(self): # Same as test_dict_items_result_gc above, but reversed. it = reversed({None: []}.items()) gc.collect() diff --git a/Lib/test/test_email/test__header_value_parser.py b/Lib/test/test_email/test__header_value_parser.py index 1bdcfa129b4c8..854f2ff009c61 100644 --- a/Lib/test/test_email/test__header_value_parser.py +++ b/Lib/test/test_email/test__header_value_parser.py @@ -395,7 +395,7 @@ def test_get_unstructured_without_trailing_whitespace_hang_case(self): [errors.InvalidHeaderDefect], '') - def test_get_unstructured_invalid_ew(self): + def test_get_unstructured_invalid_ew2(self): self._test_get_x(self._get_unst, '=?utf-8?q?=somevalue?=', '=?utf-8?q?=somevalue?=', diff --git a/Lib/test/test_pty.py b/Lib/test/test_pty.py index 0c178127571b0..0243b8a30b936 100644 --- a/Lib/test/test_pty.py +++ b/Lib/test/test_pty.py @@ -16,7 +16,6 @@ import unittest import struct -import tty import fcntl import warnings diff --git a/Lib/test/test_tabnanny.py b/Lib/test/test_tabnanny.py index 59fdfc5573d37..e0a82e95c486b 100644 --- a/Lib/test/test_tabnanny.py +++ b/Lib/test/test_tabnanny.py @@ -4,7 +4,6 @@ * errored : Whitespace related problems present in file. """ from unittest import TestCase, mock -from unittest import mock import errno import os import tabnanny From webhook-mailer at python.org Thu Mar 10 20:52:57 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Fri, 11 Mar 2022 01:52:57 -0000 Subject: [Python-checkins] sqlite3: normalise pre-acronym determiners (GH-31772) Message-ID: https://github.com/python/cpython/commit/2d5835a019a46573d5b1b614c8ef88d6b564d8d4 commit: 2d5835a019a46573d5b1b614c8ef88d6b564d8d4 branch: main author: Erlend Egeberg Aasland committer: JelleZijlstra date: 2022-03-10T17:52:47-08:00 summary: sqlite3: normalise pre-acronym determiners (GH-31772) For consistency, replace "a SQL" with "an SQL". files: M Doc/library/sqlite3.rst M Modules/_sqlite/clinic/cursor.c.h M Modules/_sqlite/cursor.c diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index c456905bc956c..a1a7e1bd49e8e 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -17,7 +17,7 @@ SQLite for internal data storage. It's also possible to prototype an application using SQLite and then port the code to a larger database such as PostgreSQL or Oracle. -The sqlite3 module was written by Gerhard H?ring. It provides a SQL interface +The sqlite3 module was written by Gerhard H?ring. It provides an SQL interface compliant with the DB-API 2.0 specification described by :pep:`249`, and requires SQLite 3.7.15 or newer. @@ -373,7 +373,7 @@ Connection Objects .. class:: Connection - A SQLite database connection has the following attributes and methods: + An SQLite database connection has the following attributes and methods: .. attribute:: isolation_level @@ -589,7 +589,7 @@ Connection Objects .. method:: load_extension(path) - This routine loads a SQLite extension from a shared library. You have to + This routine loads an SQLite extension from a shared library. You have to enable extension loading with :meth:`enable_load_extension` before you can use this routine. @@ -665,7 +665,7 @@ Connection Objects .. method:: backup(target, *, pages=-1, progress=None, name="main", sleep=0.250) - This method makes a backup of a SQLite database even while it's being accessed + This method makes a backup of an SQLite database even while it's being accessed by other clients, or concurrently by the same connection. The copy will be written into the mandatory argument *target*, that must be another :class:`Connection` instance. @@ -1068,7 +1068,7 @@ This is how SQLite types are converted to Python types by default: +-------------+----------------------------------------------+ The type system of the :mod:`sqlite3` module is extensible in two ways: you can -store additional Python types in a SQLite database via object adaptation, and +store additional Python types in an SQLite database via object adaptation, and you can let the :mod:`sqlite3` module convert SQLite types to different Python types via converters. diff --git a/Modules/_sqlite/clinic/cursor.c.h b/Modules/_sqlite/clinic/cursor.c.h index 03bdbb766e965..561d17f45b8e7 100644 --- a/Modules/_sqlite/clinic/cursor.c.h +++ b/Modules/_sqlite/clinic/cursor.c.h @@ -35,7 +35,7 @@ PyDoc_STRVAR(pysqlite_cursor_execute__doc__, "execute($self, sql, parameters=(), /)\n" "--\n" "\n" -"Executes a SQL statement."); +"Executes an SQL statement."); #define PYSQLITE_CURSOR_EXECUTE_METHODDEF \ {"execute", (PyCFunction)(void(*)(void))pysqlite_cursor_execute, METH_FASTCALL, pysqlite_cursor_execute__doc__}, @@ -77,7 +77,7 @@ PyDoc_STRVAR(pysqlite_cursor_executemany__doc__, "executemany($self, sql, seq_of_parameters, /)\n" "--\n" "\n" -"Repeatedly executes a SQL statement."); +"Repeatedly executes an SQL statement."); #define PYSQLITE_CURSOR_EXECUTEMANY_METHODDEF \ {"executemany", (PyCFunction)(void(*)(void))pysqlite_cursor_executemany, METH_FASTCALL, pysqlite_cursor_executemany__doc__}, @@ -289,4 +289,4 @@ pysqlite_cursor_close(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) { return pysqlite_cursor_close_impl(self); } -/*[clinic end generated code: output=1bee279bc861f6d3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=bde165664155b2bf input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 69beccd0f09dc..e48a95867298b 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -672,13 +672,13 @@ _sqlite3.Cursor.execute as pysqlite_cursor_execute parameters: object(c_default = 'NULL') = () / -Executes a SQL statement. +Executes an SQL statement. [clinic start generated code]*/ static PyObject * pysqlite_cursor_execute_impl(pysqlite_Cursor *self, PyObject *sql, PyObject *parameters) -/*[clinic end generated code: output=d81b4655c7c0bbad input=91d7bb36f127f597]*/ +/*[clinic end generated code: output=d81b4655c7c0bbad input=a8e0200a11627f94]*/ { return _pysqlite_query_execute(self, 0, sql, parameters); } @@ -690,13 +690,13 @@ _sqlite3.Cursor.executemany as pysqlite_cursor_executemany seq_of_parameters: object / -Repeatedly executes a SQL statement. +Repeatedly executes an SQL statement. [clinic start generated code]*/ static PyObject * pysqlite_cursor_executemany_impl(pysqlite_Cursor *self, PyObject *sql, PyObject *seq_of_parameters) -/*[clinic end generated code: output=2c65a3c4733fb5d8 input=440707b7af87fba8]*/ +/*[clinic end generated code: output=2c65a3c4733fb5d8 input=0d0a52e5eb7ccd35]*/ { return _pysqlite_query_execute(self, 1, sql, seq_of_parameters); } From webhook-mailer at python.org Fri Mar 11 03:47:56 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Fri, 11 Mar 2022 08:47:56 -0000 Subject: [Python-checkins] bpo-44796: Unify TypeVar and ParamSpec substitution (GH-31143) Message-ID: https://github.com/python/cpython/commit/b6a5d8590c4bfe4553d796b36af03bda8c0d5af5 commit: b6a5d8590c4bfe4553d796b36af03bda8c0d5af5 branch: main author: Serhiy Storchaka committer: serhiy-storchaka date: 2022-03-11T10:47:26+02:00 summary: bpo-44796: Unify TypeVar and ParamSpec substitution (GH-31143) Add methods __typing_subst__() in TypeVar and ParamSpec. Simplify code by using more object-oriented approach, especially the C code for types.GenericAlias and the Python code for collections.abc.Callable. files: M Include/internal/pycore_global_strings.h M Include/internal/pycore_runtime_init.h M Lib/_collections_abc.py M Lib/test/test_typing.py M Lib/typing.py M Objects/genericaliasobject.c diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h index 755d69a873cdc..35bffa7aff949 100644 --- a/Include/internal/pycore_global_strings.h +++ b/Include/internal/pycore_global_strings.h @@ -199,6 +199,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(__subclasshook__) STRUCT_FOR_ID(__truediv__) STRUCT_FOR_ID(__trunc__) + STRUCT_FOR_ID(__typing_subst__) STRUCT_FOR_ID(__warningregistry__) STRUCT_FOR_ID(__weakref__) STRUCT_FOR_ID(__xor__) diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h index 5ba18267aeb34..20d543a8cbc56 100644 --- a/Include/internal/pycore_runtime_init.h +++ b/Include/internal/pycore_runtime_init.h @@ -822,6 +822,7 @@ extern "C" { INIT_ID(__subclasshook__), \ INIT_ID(__truediv__), \ INIT_ID(__trunc__), \ + INIT_ID(__typing_subst__), \ INIT_ID(__warningregistry__), \ INIT_ID(__weakref__), \ INIT_ID(__xor__), \ diff --git a/Lib/_collections_abc.py b/Lib/_collections_abc.py index 40417dc1d3133..86eb042e3a75a 100644 --- a/Lib/_collections_abc.py +++ b/Lib/_collections_abc.py @@ -430,25 +430,13 @@ def __new__(cls, origin, args): raise TypeError( "Callable must be used as Callable[[arg, ...], result].") t_args, t_result = args - if isinstance(t_args, list): + if isinstance(t_args, (tuple, list)): args = (*t_args, t_result) elif not _is_param_expr(t_args): raise TypeError(f"Expected a list of types, an ellipsis, " f"ParamSpec, or Concatenate. Got {t_args}") return super().__new__(cls, origin, args) - @property - def __parameters__(self): - params = [] - for arg in self.__args__: - # Looks like a genericalias - if hasattr(arg, "__parameters__") and isinstance(arg.__parameters__, tuple): - params.extend(arg.__parameters__) - else: - if _is_typevarlike(arg): - params.append(arg) - return tuple(dict.fromkeys(params)) - def __repr__(self): if len(self.__args__) == 2 and _is_param_expr(self.__args__[0]): return super().__repr__() @@ -468,57 +456,24 @@ def __getitem__(self, item): # code is copied from typing's _GenericAlias and the builtin # types.GenericAlias. - # A special case in PEP 612 where if X = Callable[P, int], - # then X[int, str] == X[[int, str]]. - param_len = len(self.__parameters__) - if param_len == 0: - raise TypeError(f'{self} is not a generic class') if not isinstance(item, tuple): item = (item,) - if (param_len == 1 and _is_param_expr(self.__parameters__[0]) + # A special case in PEP 612 where if X = Callable[P, int], + # then X[int, str] == X[[int, str]]. + if (len(self.__parameters__) == 1 + and _is_param_expr(self.__parameters__[0]) and item and not _is_param_expr(item[0])): - item = (list(item),) - item_len = len(item) - if item_len != param_len: - raise TypeError(f'Too {"many" if item_len > param_len else "few"}' - f' arguments for {self};' - f' actual {item_len}, expected {param_len}') - subst = dict(zip(self.__parameters__, item)) - new_args = [] - for arg in self.__args__: - if _is_typevarlike(arg): - if _is_param_expr(arg): - arg = subst[arg] - if not _is_param_expr(arg): - raise TypeError(f"Expected a list of types, an ellipsis, " - f"ParamSpec, or Concatenate. Got {arg}") - else: - arg = subst[arg] - # Looks like a GenericAlias - elif hasattr(arg, '__parameters__') and isinstance(arg.__parameters__, tuple): - subparams = arg.__parameters__ - if subparams: - subargs = tuple(subst[x] for x in subparams) - arg = arg[subargs] - if isinstance(arg, tuple): - new_args.extend(arg) - else: - new_args.append(arg) + item = (item,) + + new_args = super().__getitem__(item).__args__ # args[0] occurs due to things like Z[[int, str, bool]] from PEP 612 - if not isinstance(new_args[0], list): + if not isinstance(new_args[0], (tuple, list)): t_result = new_args[-1] t_args = new_args[:-1] new_args = (t_args, t_result) return _CallableGenericAlias(Callable, tuple(new_args)) - -def _is_typevarlike(arg): - obj = type(arg) - # looks like a TypeVar/ParamSpec - return (obj.__module__ == 'typing' - and obj.__name__ in {'ParamSpec', 'TypeVar'}) - def _is_param_expr(obj): """Checks if obj matches either a list of types, ``...``, ``ParamSpec`` or ``_ConcatenateGenericAlias`` from typing.py diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index fc596e4d90b21..91b2e77e97b5a 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -360,10 +360,31 @@ def test_no_bivariant(self): with self.assertRaises(ValueError): TypeVar('T', covariant=True, contravariant=True) + def test_var_substitution(self): + T = TypeVar('T') + subst = T.__typing_subst__ + self.assertIs(subst(int), int) + self.assertEqual(subst(list[int]), list[int]) + self.assertEqual(subst(List[int]), List[int]) + self.assertEqual(subst(List), List) + self.assertIs(subst(Any), Any) + self.assertIs(subst(None), type(None)) + self.assertIs(subst(T), T) + self.assertEqual(subst(int|str), int|str) + self.assertEqual(subst(Union[int, str]), Union[int, str]) + def test_bad_var_substitution(self): T = TypeVar('T') - for arg in (), (int, str): + P = ParamSpec("P") + bad_args = ( + 42, ..., [int], (), (int, str), Union, + Generic, Generic[T], Protocol, Protocol[T], + Final, Final[int], ClassVar, ClassVar[int], + ) + for arg in bad_args: with self.subTest(arg=arg): + with self.assertRaises(TypeError): + T.__typing_subst__(arg) with self.assertRaises(TypeError): List[T][arg] with self.assertRaises(TypeError): @@ -1110,8 +1131,7 @@ def test_var_substitution(self): C2 = Callable[[KT, T], VT] C3 = Callable[..., T] self.assertEqual(C1[str], Callable[[int, str], str]) - if Callable is typing.Callable: - self.assertEqual(C1[None], Callable[[int, type(None)], type(None)]) + self.assertEqual(C1[None], Callable[[int, type(None)], type(None)]) self.assertEqual(C2[int, float, str], Callable[[int, float], str]) self.assertEqual(C3[int], Callable[..., int]) self.assertEqual(C3[NoReturn], Callable[..., NoReturn]) @@ -2696,7 +2716,10 @@ def test_all_repr_eq_any(self): for obj in objs: self.assertNotEqual(repr(obj), '') self.assertEqual(obj, obj) - if getattr(obj, '__parameters__', None) and len(obj.__parameters__) == 1: + if (getattr(obj, '__parameters__', None) + and not isinstance(obj, typing.TypeVar) + and isinstance(obj.__parameters__, tuple) + and len(obj.__parameters__) == 1): self.assertEqual(obj[Any].__args__, (Any,)) if isinstance(obj, type): for base in obj.__mro__: @@ -5748,33 +5771,30 @@ class X(Generic[P, P2]): self.assertEqual(G1.__args__, ((int, str), (bytes,))) self.assertEqual(G2.__args__, ((int,), (str, bytes))) + def test_var_substitution(self): + T = TypeVar("T") + P = ParamSpec("P") + subst = P.__typing_subst__ + self.assertEqual(subst((int, str)), (int, str)) + self.assertEqual(subst([int, str]), (int, str)) + self.assertEqual(subst([None]), (type(None),)) + self.assertIs(subst(...), ...) + self.assertIs(subst(P), P) + self.assertEqual(subst(Concatenate[int, P]), Concatenate[int, P]) + def test_bad_var_substitution(self): T = TypeVar('T') P = ParamSpec('P') bad_args = (42, int, None, T, int|str, Union[int, str]) for arg in bad_args: with self.subTest(arg=arg): + with self.assertRaises(TypeError): + P.__typing_subst__(arg) with self.assertRaises(TypeError): typing.Callable[P, T][arg, str] with self.assertRaises(TypeError): collections.abc.Callable[P, T][arg, str] - def test_no_paramspec_in__parameters__(self): - # ParamSpec should not be found in __parameters__ - # of generics. Usages outside Callable, Concatenate - # and Generic are invalid. - T = TypeVar("T") - P = ParamSpec("P") - self.assertNotIn(P, List[P].__parameters__) - self.assertIn(T, Tuple[T, P].__parameters__) - - # Test for consistency with builtin generics. - self.assertNotIn(P, list[P].__parameters__) - self.assertIn(T, tuple[T, P].__parameters__) - - self.assertNotIn(P, (list[P] | int).__parameters__) - self.assertIn(T, (tuple[T, P] | int).__parameters__) - def test_paramspec_in_nested_generics(self): # Although ParamSpec should not be found in __parameters__ of most # generics, they probably should be found when nested in diff --git a/Lib/typing.py b/Lib/typing.py index e3015563b3e8c..062c01ef2a9b9 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -179,7 +179,9 @@ def _type_check(arg, msg, is_argument=True, module=None, *, allow_special_forms= if (isinstance(arg, _GenericAlias) and arg.__origin__ in invalid_generic_forms): raise TypeError(f"{arg} is not valid as type argument") - if arg in (Any, NoReturn, Never, Self, ClassVar, Final, TypeAlias): + if arg in (Any, NoReturn, Never, Self, TypeAlias): + return arg + if allow_special_forms and arg in (ClassVar, Final): return arg if isinstance(arg, _SpecialForm) or arg in (Generic, Protocol): raise TypeError(f"Plain {arg} is not valid as type argument") @@ -217,21 +219,22 @@ def _type_repr(obj): return repr(obj) -def _collect_type_vars(types_, typevar_types=None): - """Collect all type variable contained - in types in order of first appearance (lexicographic order). For example:: +def _collect_parameters(args): + """Collect all type variables and parameter specifications in args + in order of first appearance (lexicographic order). For example:: - _collect_type_vars((T, List[S, T])) == (T, S) + _collect_parameters((T, Callable[P, T])) == (T, P) """ - if typevar_types is None: - typevar_types = TypeVar - tvars = [] - for t in types_: - if isinstance(t, typevar_types) and t not in tvars: - tvars.append(t) - if isinstance(t, (_GenericAlias, GenericAlias, types.UnionType)): - tvars.extend([t for t in t.__parameters__ if t not in tvars]) - return tuple(tvars) + parameters = [] + for t in args: + if hasattr(t, '__typing_subst__'): + if t not in parameters: + parameters.append(t) + else: + for x in getattr(t, '__parameters__', ()): + if x not in parameters: + parameters.append(x) + return tuple(parameters) def _check_generic(cls, parameters, elen): @@ -671,7 +674,6 @@ def Concatenate(self, parameters): msg = "Concatenate[arg, ...]: each arg must be a type." parameters = (*(_type_check(p, msg) for p in parameters[:-1]), parameters[-1]) return _ConcatenateGenericAlias(self, parameters, - _typevar_types=(TypeVar, ParamSpec), _paramspec_tvars=True) @@ -909,6 +911,11 @@ def __init__(self, name, *constraints, bound=None, if def_mod != 'typing': self.__module__ = def_mod + def __typing_subst__(self, arg): + msg = "Parameters to generic types must be types." + arg = _type_check(arg, msg, is_argument=True) + return arg + class TypeVarTuple(_Final, _Immutable, _root=True): """Type variable tuple. @@ -942,6 +949,9 @@ def __iter__(self): def __repr__(self): return self._name + def __typing_subst__(self, arg): + raise AssertionError + class ParamSpecArgs(_Final, _Immutable, _root=True): """The args for a ParamSpec object. @@ -1052,6 +1062,14 @@ def __init__(self, name, *, bound=None, covariant=False, contravariant=False): if def_mod != 'typing': self.__module__ = def_mod + def __typing_subst__(self, arg): + if isinstance(arg, (list, tuple)): + arg = tuple(_type_check(a, "Expected a type.") for a in arg) + elif not _is_param_expr(arg): + raise TypeError(f"Expected a list of types, an ellipsis, " + f"ParamSpec, or Concatenate. Got {arg}") + return arg + def _is_dunder(attr): return attr.startswith('__') and attr.endswith('__') @@ -1106,7 +1124,7 @@ def __getattr__(self, attr): def __setattr__(self, attr, val): if _is_dunder(attr) or attr in {'_name', '_inst', '_nparams', - '_typevar_types', '_paramspec_tvars'}: + '_paramspec_tvars'}: super().__setattr__(attr, val) else: setattr(self.__origin__, attr, val) @@ -1199,7 +1217,6 @@ class _GenericAlias(_BaseGenericAlias, _root=True): # TypeVar[bool] def __init__(self, origin, args, *, inst=True, name=None, - _typevar_types=(TypeVar, TypeVarTuple), _paramspec_tvars=False): super().__init__(origin, inst=inst, name=name) if not isinstance(args, tuple): @@ -1207,8 +1224,7 @@ def __init__(self, origin, args, *, inst=True, name=None, self.__args__ = tuple(... if a is _TypingEllipsis else () if a is _TypingEmpty else a for a in args) - self.__parameters__ = _collect_type_vars(args, typevar_types=_typevar_types) - self._typevar_types = _typevar_types + self.__parameters__ = _collect_parameters(args) self._paramspec_tvars = _paramspec_tvars if not name: self.__module__ = origin.__module__ @@ -1291,26 +1307,20 @@ def _determine_new_args(self, args): new_args = [] for old_arg in self.__args__: - if isinstance(old_arg, ParamSpec): - new_arg = new_arg_by_param[old_arg] - if not _is_param_expr(new_arg): - raise TypeError(f"Expected a list of types, an ellipsis, " - f"ParamSpec, or Concatenate. Got {new_arg}") - elif isinstance(old_arg, self._typevar_types): - new_arg = new_arg_by_param[old_arg] - elif (TypeVarTuple in self._typevar_types - and _is_unpacked_typevartuple(old_arg)): + if _is_unpacked_typevartuple(old_arg): original_typevartuple = old_arg.__parameters__[0] new_arg = new_arg_by_param[original_typevartuple] - elif isinstance(old_arg, (_GenericAlias, GenericAlias, types.UnionType)): - subparams = old_arg.__parameters__ - if not subparams: - new_arg = old_arg - else: - subargs = tuple(new_arg_by_param[x] for x in subparams) - new_arg = old_arg[subargs] else: - new_arg = old_arg + substfunc = getattr(old_arg, '__typing_subst__', None) + if substfunc: + new_arg = substfunc(new_arg_by_param[old_arg]) + else: + subparams = getattr(old_arg, '__parameters__', ()) + if not subparams: + new_arg = old_arg + else: + subargs = tuple(new_arg_by_param[x] for x in subparams) + new_arg = old_arg[subargs] if self.__origin__ == collections.abc.Callable and isinstance(new_arg, tuple): # Consider the following `Callable`. @@ -1342,7 +1352,6 @@ def _determine_new_args(self, args): def copy_with(self, args): return self.__class__(self.__origin__, args, name=self._name, inst=self._inst, - _typevar_types=self._typevar_types, _paramspec_tvars=self._paramspec_tvars) def __repr__(self): @@ -1454,7 +1463,6 @@ class _CallableType(_SpecialGenericAlias, _root=True): def copy_with(self, params): return _CallableGenericAlias(self.__origin__, params, name=self._name, inst=self._inst, - _typevar_types=(TypeVar, ParamSpec), _paramspec_tvars=True) def __getitem__(self, params): @@ -1675,11 +1683,8 @@ def __class_getitem__(cls, params): # don't check variadic generic arity at runtime (to reduce # complexity of typing.py). _check_generic(cls, params, len(cls.__parameters__)) - return _GenericAlias( - cls, params, - _typevar_types=(TypeVar, TypeVarTuple, ParamSpec), - _paramspec_tvars=True, - ) + return _GenericAlias(cls, params, + _paramspec_tvars=True) def __init_subclass__(cls, *args, **kwargs): super().__init_subclass__(*args, **kwargs) @@ -1691,9 +1696,7 @@ def __init_subclass__(cls, *args, **kwargs): if error: raise TypeError("Cannot inherit from plain Generic") if '__orig_bases__' in cls.__dict__: - tvars = _collect_type_vars( - cls.__orig_bases__, (TypeVar, TypeVarTuple, ParamSpec) - ) + tvars = _collect_parameters(cls.__orig_bases__) # Look for Generic[T1, ..., Tn]. # If found, tvars must be a subset of it. # If not found, tvars is it. diff --git a/Objects/genericaliasobject.c b/Objects/genericaliasobject.c index b41644910f5d2..45caf2e2ee7db 100644 --- a/Objects/genericaliasobject.c +++ b/Objects/genericaliasobject.c @@ -152,25 +152,6 @@ ga_repr(PyObject *self) return NULL; } -// isinstance(obj, TypeVar) without importing typing.py. -// Returns -1 for errors. -static int -is_typevar(PyObject *obj) -{ - PyTypeObject *type = Py_TYPE(obj); - if (strcmp(type->tp_name, "TypeVar") != 0) { - return 0; - } - PyObject *module = PyObject_GetAttrString((PyObject *)type, "__module__"); - if (module == NULL) { - return -1; - } - int res = PyUnicode_Check(module) - && _PyUnicode_EqualToASCIIString(module, "typing"); - Py_DECREF(module); - return res; -} - // Index of item in self[:len], or -1 if not found (self is a tuple) static Py_ssize_t tuple_index(PyObject *self, Py_ssize_t len, PyObject *item) @@ -205,13 +186,14 @@ _Py_make_parameters(PyObject *args) Py_ssize_t iparam = 0; for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) { PyObject *t = PyTuple_GET_ITEM(args, iarg); - int typevar = is_typevar(t); - if (typevar < 0) { + PyObject *subst; + if (_PyObject_LookupAttr(t, &_Py_ID(__typing_subst__), &subst) < 0) { Py_DECREF(parameters); return NULL; } - if (typevar) { + if (subst) { iparam += tuple_add(parameters, iparam, t); + Py_DECREF(subst); } else { PyObject *subparams; @@ -295,7 +277,7 @@ _Py_subs_parameters(PyObject *self, PyObject *args, PyObject *parameters, PyObje Py_ssize_t nparams = PyTuple_GET_SIZE(parameters); if (nparams == 0) { return PyErr_Format(PyExc_TypeError, - "There are no type variables left in %R", + "%R is not a generic class", self); } int is_tuple = PyTuple_Check(item); @@ -320,23 +302,23 @@ _Py_subs_parameters(PyObject *self, PyObject *args, PyObject *parameters, PyObje } for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) { PyObject *arg = PyTuple_GET_ITEM(args, iarg); - int typevar = is_typevar(arg); - if (typevar < 0) { + PyObject *subst; + if (_PyObject_LookupAttr(arg, &_Py_ID(__typing_subst__), &subst) < 0) { Py_DECREF(newargs); return NULL; } - if (typevar) { + if (subst) { Py_ssize_t iparam = tuple_index(parameters, nparams, arg); assert(iparam >= 0); - arg = argitems[iparam]; - Py_INCREF(arg); + arg = PyObject_CallOneArg(subst, argitems[iparam]); + Py_DECREF(subst); } else { arg = subs_tvars(arg, parameters, argitems); - if (arg == NULL) { - Py_DECREF(newargs); - return NULL; - } + } + if (arg == NULL) { + Py_DECREF(newargs); + return NULL; } PyTuple_SET_ITEM(newargs, iarg, arg); } From webhook-mailer at python.org Fri Mar 11 04:05:17 2022 From: webhook-mailer at python.org (Fidget-Spinner) Date: Fri, 11 Mar 2022 09:05:17 -0000 Subject: [Python-checkins] bpo-46881: Fix refleak from GH-31616 (GH-31805) Message-ID: https://github.com/python/cpython/commit/54ab9ad312ea53db40e31712454272e1d4c0315f commit: 54ab9ad312ea53db40e31712454272e1d4c0315f branch: main author: Jelle Zijlstra committer: Fidget-Spinner date: 2022-03-11T17:05:08+08:00 summary: bpo-46881: Fix refleak from GH-31616 (GH-31805) files: M Objects/unicodeobject.c diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 9052c53f11b8e..2261b9a031625 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -677,10 +677,12 @@ unicode_result_ready(PyObject *unicode) if (kind == PyUnicode_1BYTE_KIND) { const Py_UCS1 *data = PyUnicode_1BYTE_DATA(unicode); Py_UCS1 ch = data[0]; - if (unicode != LATIN1(ch)) { + PyObject *latin1_char = LATIN1(ch); + if (unicode != latin1_char) { + Py_INCREF(latin1_char); Py_DECREF(unicode); } - return get_latin1_char(ch); + return latin1_char; } } From webhook-mailer at python.org Fri Mar 11 09:29:22 2022 From: webhook-mailer at python.org (markshannon) Date: Fri, 11 Mar 2022 14:29:22 -0000 Subject: [Python-checkins] Update adaptive.md for inline caching (GH-31817) Message-ID: https://github.com/python/cpython/commit/4f74ffc5e333a9ca931153f4844c8c785b1362a3 commit: 4f74ffc5e333a9ca931153f4844c8c785b1362a3 branch: main author: Mark Shannon committer: markshannon date: 2022-03-11T14:29:10Z summary: Update adaptive.md for inline caching (GH-31817) files: M Python/adaptive.md diff --git a/Python/adaptive.md b/Python/adaptive.md index 81880ce8cf242..e8161bcdd5b9c 100644 --- a/Python/adaptive.md +++ b/Python/adaptive.md @@ -14,16 +14,16 @@ A family of instructions has the following fundamental properties: it executes the non-adaptive instruction. * It has at least one specialized form of the instruction that is tailored for a particular value or set of values at runtime. -* All members of the family have access to the same number of cache entries. - Individual family members do not need to use all of the entries. +* All members of the family must have the same number of inline cache entries, + to ensure correct execution. + Individual family members do not need to use all of the entries, + but must skip over any unused entries when executing. The current implementation also requires the following, although these are not fundamental and may change: -* If a family uses one or more entries, then the first entry must be a - `_PyAdaptiveEntry` entry. -* If a family uses no cache entries, then the `oparg` is used as the - counter for the adaptive instruction. +* All families uses one or more inline cache entries, + the first entry is always the counter. * All instruction names should start with the name of the non-adaptive instruction. * The adaptive instruction should end in `_ADAPTIVE`. @@ -76,6 +76,10 @@ keeping `Ti` low which means minimizing branches and dependent memory accesses (pointer chasing). These two objectives may be in conflict, requiring judgement and experimentation to design the family of instructions. +The size of the inline cache should as small as possible, +without impairing performance, to reduce the number of +`EXTENDED_ARG` jumps, and to reduce pressure on the CPU's data cache. + ### Gathering data Before choosing how to specialize an instruction, it is important to gather @@ -106,7 +110,7 @@ This can be tested quickly: * `globals->keys->dk_version == expected_version` and the operation can be performed quickly: -* `value = globals->keys->entries[index].value`. +* `value = entries[cache->index].me_value;`. Because it is impossible to measure the performance of an instruction without also measuring unrelated factors, the assessment of the quality of a @@ -119,8 +123,7 @@ base instruction. In general, specialized instructions should be implemented in two parts: 1. A sequence of guards, each of the form - `DEOPT_IF(guard-condition-is-false, BASE_NAME)`, - followed by a `record_cache_hit()`. + `DEOPT_IF(guard-condition-is-false, BASE_NAME)`. 2. The operation, which should ideally have no branches and a minimum number of dependent memory accesses. @@ -129,3 +132,11 @@ can be re-used in the operation. If there are branches in the operation, then consider further specialization to eliminate the branches. + +### Maintaining stats + +Finally, take care that stats are gather correctly. +After the last `DEOPT_IF` has passed, a hit should be recorded with +`STAT_INC(BASE_INSTRUCTION, hit)`. +After a optimization has been deferred in the `ADAPTIVE` form, +that should be recorded with `STAT_INC(BASE_INSTRUCTION, deferred)`. From webhook-mailer at python.org Fri Mar 11 09:37:26 2022 From: webhook-mailer at python.org (markshannon) Date: Fri, 11 Mar 2022 14:37:26 -0000 Subject: [Python-checkins] bpo-46944: use FASTCALL calling convention in generator.throw (GH-31723) Message-ID: https://github.com/python/cpython/commit/304197b3820309e3ed695ff3e6a71461881a1728 commit: 304197b3820309e3ed695ff3e6a71461881a1728 branch: main author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> committer: markshannon date: 2022-03-11T14:37:14Z summary: bpo-46944: use FASTCALL calling convention in generator.throw (GH-31723) files: A Misc/NEWS.d/next/Core and Builtins/2022-03-08-10-50-42.bpo-46944.cnaIK3.rst M Objects/genobject.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-08-10-50-42.bpo-46944.cnaIK3.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-08-10-50-42.bpo-46944.cnaIK3.rst new file mode 100644 index 0000000000000..f940ebbbd1f5c --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-08-10-50-42.bpo-46944.cnaIK3.rst @@ -0,0 +1 @@ +Speed up throwing exception in generator with :const:`METH_FASTCALL` calling convention. Patch by Kumar Aditya. diff --git a/Objects/genobject.c b/Objects/genobject.c index bfa1ea5c45f66..4fac0ce241c09 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -561,16 +561,23 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, static PyObject * -gen_throw(PyGenObject *gen, PyObject *args) +gen_throw(PyGenObject *gen, PyObject *const *args, Py_ssize_t nargs) { PyObject *typ; PyObject *tb = NULL; PyObject *val = NULL; - if (!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb)) { + if (!_PyArg_CheckPositional("throw", nargs, 1, 3)) { return NULL; } - + typ = args[0]; + if (nargs == 3) { + val = args[1]; + tb = args[2]; + } + else if (nargs == 2) { + val = args[1]; + } return _gen_throw(gen, 1, typ, val, tb); } @@ -813,7 +820,7 @@ PyDoc_STRVAR(sizeof__doc__, static PyMethodDef gen_methods[] = { {"send",(PyCFunction)gen_send, METH_O, send_doc}, - {"throw",(PyCFunction)gen_throw, METH_VARARGS, throw_doc}, + {"throw",(PyCFunction)(void(*)(void))gen_throw, METH_FASTCALL, throw_doc}, {"close",(PyCFunction)gen_close, METH_NOARGS, close_doc}, {"__sizeof__", (PyCFunction)gen_sizeof, METH_NOARGS, sizeof__doc__}, {NULL, NULL} /* Sentinel */ @@ -1159,7 +1166,7 @@ PyDoc_STRVAR(coro_close_doc, static PyMethodDef coro_methods[] = { {"send",(PyCFunction)gen_send, METH_O, coro_send_doc}, - {"throw",(PyCFunction)gen_throw, METH_VARARGS, coro_throw_doc}, + {"throw",(PyCFunction)(void(*)(void))gen_throw, METH_FASTCALL, coro_throw_doc}, {"close",(PyCFunction)gen_close, METH_NOARGS, coro_close_doc}, {"__sizeof__", (PyCFunction)gen_sizeof, METH_NOARGS, sizeof__doc__}, {NULL, NULL} /* Sentinel */ @@ -1246,9 +1253,9 @@ coro_wrapper_send(PyCoroWrapper *cw, PyObject *arg) } static PyObject * -coro_wrapper_throw(PyCoroWrapper *cw, PyObject *args) +coro_wrapper_throw(PyCoroWrapper *cw, PyObject *const *args, Py_ssize_t nargs) { - return gen_throw((PyGenObject *)cw->cw_coroutine, args); + return gen_throw((PyGenObject *)cw->cw_coroutine, args, nargs); } static PyObject * @@ -1266,7 +1273,8 @@ coro_wrapper_traverse(PyCoroWrapper *cw, visitproc visit, void *arg) static PyMethodDef coro_wrapper_methods[] = { {"send",(PyCFunction)coro_wrapper_send, METH_O, coro_send_doc}, - {"throw",(PyCFunction)coro_wrapper_throw, METH_VARARGS, coro_throw_doc}, + {"throw",(PyCFunction)(void(*)(void))coro_wrapper_throw, + METH_FASTCALL, coro_throw_doc}, {"close",(PyCFunction)coro_wrapper_close, METH_NOARGS, coro_close_doc}, {NULL, NULL} /* Sentinel */ }; @@ -1789,7 +1797,7 @@ async_gen_asend_iternext(PyAsyncGenASend *o) static PyObject * -async_gen_asend_throw(PyAsyncGenASend *o, PyObject *args) +async_gen_asend_throw(PyAsyncGenASend *o, PyObject *const *args, Py_ssize_t nargs) { PyObject *result; @@ -1800,7 +1808,7 @@ async_gen_asend_throw(PyAsyncGenASend *o, PyObject *args) return NULL; } - result = gen_throw((PyGenObject*)o->ags_gen, args); + result = gen_throw((PyGenObject*)o->ags_gen, args, nargs); result = async_gen_unwrap_value(o->ags_gen, result); if (result == NULL) { @@ -1821,7 +1829,7 @@ async_gen_asend_close(PyAsyncGenASend *o, PyObject *args) static PyMethodDef async_gen_asend_methods[] = { {"send", (PyCFunction)async_gen_asend_send, METH_O, send_doc}, - {"throw", (PyCFunction)async_gen_asend_throw, METH_VARARGS, throw_doc}, + {"throw", (PyCFunction)(void(*)(void))async_gen_asend_throw, METH_FASTCALL, throw_doc}, {"close", (PyCFunction)async_gen_asend_close, METH_NOARGS, close_doc}, {NULL, NULL} /* Sentinel */ }; @@ -2183,7 +2191,7 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg) static PyObject * -async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *args) +async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *const *args, Py_ssize_t nargs) { PyObject *retval; @@ -2194,7 +2202,7 @@ async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *args) return NULL; } - retval = gen_throw((PyGenObject*)o->agt_gen, args); + retval = gen_throw((PyGenObject*)o->agt_gen, args, nargs); if (o->agt_args) { return async_gen_unwrap_value(o->agt_gen, retval); } else { @@ -2239,7 +2247,8 @@ async_gen_athrow_close(PyAsyncGenAThrow *o, PyObject *args) static PyMethodDef async_gen_athrow_methods[] = { {"send", (PyCFunction)async_gen_athrow_send, METH_O, send_doc}, - {"throw", (PyCFunction)async_gen_athrow_throw, METH_VARARGS, throw_doc}, + {"throw", (PyCFunction)(void(*)(void))async_gen_athrow_throw, + METH_FASTCALL, throw_doc}, {"close", (PyCFunction)async_gen_athrow_close, METH_NOARGS, close_doc}, {NULL, NULL} /* Sentinel */ }; From webhook-mailer at python.org Fri Mar 11 09:47:49 2022 From: webhook-mailer at python.org (ericvsmith) Date: Fri, 11 Mar 2022 14:47:49 -0000 Subject: [Python-checkins] Remove an old, elementtree-specific leak detector (GH-31811) Message-ID: https://github.com/python/cpython/commit/f84c867dd7c87c49d830e5d195a13afe7eb86caa commit: f84c867dd7c87c49d830e5d195a13afe7eb86caa branch: main author: Oleg Iarygin committer: ericvsmith date: 2022-03-11T09:47:42-05:00 summary: Remove an old, elementtree-specific leak detector (GH-31811) files: M Modules/_elementtree.c diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index f54c28447ca8f..1794124aa45ad 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -36,17 +36,6 @@ /* -------------------------------------------------------------------- */ -#if 0 -static int memory = 0; -#define ALLOC(size, comment)\ -do { memory += size; printf("%8d - %s\n", memory, comment); } while (0) -#define RELEASE(size, comment)\ -do { memory -= size; printf("%8d - %s\n", memory, comment); } while (0) -#else -#define ALLOC(size, comment) -#define RELEASE(size, comment) -#endif - /* compiler tweaks */ #if defined(_MSC_VER) #define LOCAL(type) static __inline type __fastcall @@ -301,7 +290,6 @@ create_new_element(PyObject* tag, PyObject* attrib) self->weakreflist = NULL; - ALLOC(sizeof(ElementObject), "create element"); PyObject_GC_Track(self); if (attrib != NULL && !is_empty_dict(attrib)) { @@ -676,7 +664,6 @@ element_dealloc(ElementObject* self) */ element_gc_clear(self); - RELEASE(sizeof(ElementObject), "destroy element"); Py_TYPE(self)->tp_free((PyObject *)self); Py_TRASHCAN_END } From webhook-mailer at python.org Fri Mar 11 09:58:06 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Fri, 11 Mar 2022 14:58:06 -0000 Subject: [Python-checkins] [3.10] bpo-46581: Propagate private vars via _GenericAlias.copy_with (GH-31061) (GH-31821) Message-ID: https://github.com/python/cpython/commit/3bc801960655ea265599805eac24173164b511a6 commit: 3bc801960655ea265599805eac24173164b511a6 branch: 3.10 author: Matt Bogosian committer: serhiy-storchaka date: 2022-03-11T16:57:52+02:00 summary: [3.10] bpo-46581: Propagate private vars via _GenericAlias.copy_with (GH-31061) (GH-31821) (Cherry-picked from 32bf3597922ac3f613989582afa2bff43bea8a2f.) GH-26091 added the _typevar_types and _paramspec_tvars instance variables to _GenericAlias. However, they were not propagated consistently. This commit addresses the most prominent deficiency identified in bpo-46581 (namely their absence from _GenericAlias.copy_with), but there could be others. Co-authored-by: Ken Jin <28750310+Fidget-Spinner at users.noreply.github.com> Co-authored-by: Serhiy Storchaka Co-authored-by: Ken Jin <28750310+Fidget-Spinner at users.noreply.github.com> Co-authored-by: Serhiy Storchaka files: A Misc/NEWS.d/next/Library/2022-02-01-11-32-47.bpo-46581.t7Zw65.rst M Lib/test/test_typing.py M Lib/typing.py M Misc/ACKS diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index f3ebece4b4a7f..779e1758d51d8 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -4990,6 +4990,27 @@ def test_paramspec_in_nested_generics(self): self.assertEqual(G2[[int, str], float], list[C]) self.assertEqual(G3[[int, str], float], list[C] | int) + def test_paramspec_gets_copied(self): + # bpo-46581 + P = ParamSpec('P') + P2 = ParamSpec('P2') + C1 = Callable[P, int] + self.assertEqual(C1.__parameters__, (P,)) + self.assertEqual(C1[P2].__parameters__, (P2,)) + self.assertEqual(C1[str].__parameters__, ()) + self.assertEqual(C1[str, T].__parameters__, (T,)) + self.assertEqual(C1[Concatenate[str, P2]].__parameters__, (P2,)) + self.assertEqual(C1[Concatenate[T, P2]].__parameters__, (T, P2)) + self.assertEqual(C1[...].__parameters__, ()) + + C2 = Callable[Concatenate[str, P], int] + self.assertEqual(C2.__parameters__, (P,)) + self.assertEqual(C2[P2].__parameters__, (P2,)) + self.assertEqual(C2[str].__parameters__, ()) + self.assertEqual(C2[str, T].__parameters__, (T,)) + self.assertEqual(C2[Concatenate[str, P2]].__parameters__, (P2,)) + self.assertEqual(C2[Concatenate[T, P2]].__parameters__, (T, P2)) + class ConcatenateTests(BaseTestCase): def test_basics(self): diff --git a/Lib/typing.py b/Lib/typing.py index da393eefc53a4..086d0f3f9594c 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -600,7 +600,9 @@ def Concatenate(self, parameters): "ParamSpec variable.") msg = "Concatenate[arg, ...]: each arg must be a type." parameters = (*(_type_check(p, msg) for p in parameters[:-1]), parameters[-1]) - return _ConcatenateGenericAlias(self, parameters) + return _ConcatenateGenericAlias(self, parameters, + _typevar_types=(TypeVar, ParamSpec), + _paramspec_tvars=True) @_SpecialForm @@ -1079,7 +1081,9 @@ def __getitem__(self, params): return self.copy_with(tuple(new_args)) def copy_with(self, params): - return self.__class__(self.__origin__, params, name=self._name, inst=self._inst) + return self.__class__(self.__origin__, params, name=self._name, inst=self._inst, + _typevar_types=self._typevar_types, + _paramspec_tvars=self._paramspec_tvars) def __repr__(self): if self._name: @@ -1281,11 +1285,6 @@ def __hash__(self): class _ConcatenateGenericAlias(_GenericAlias, _root=True): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs, - _typevar_types=(TypeVar, ParamSpec), - _paramspec_tvars=True) - def copy_with(self, params): if isinstance(params[-1], (list, tuple)): return (*params[:-1], *params[-1]) diff --git a/Misc/ACKS b/Misc/ACKS index c9bf79d035fcf..7668caf43bc36 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -190,6 +190,7 @@ Paul Boddie Matthew Boedicker Robin Boerdijk Andra Bogildea +Matt Bogosian Nikolay Bogoychev David Bolen Wouter Bolsterlee diff --git a/Misc/NEWS.d/next/Library/2022-02-01-11-32-47.bpo-46581.t7Zw65.rst b/Misc/NEWS.d/next/Library/2022-02-01-11-32-47.bpo-46581.t7Zw65.rst new file mode 100644 index 0000000000000..1982c1d70093f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-02-01-11-32-47.bpo-46581.t7Zw65.rst @@ -0,0 +1,2 @@ +Brings :class:`ParamSpec` propagation for :class:`GenericAlias` in line with +:class:`Concatenate` (and others). From webhook-mailer at python.org Fri Mar 11 11:47:28 2022 From: webhook-mailer at python.org (asvetlov) Date: Fri, 11 Mar 2022 16:47:28 -0000 Subject: [Python-checkins] Use FASTCALL for __import__ (GH-31752) Message-ID: https://github.com/python/cpython/commit/6f3b9e2243d8c5b6cf1be988eb5d2bd3da65a422 commit: 6f3b9e2243d8c5b6cf1be988eb5d2bd3da65a422 branch: main author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> committer: asvetlov date: 2022-03-11T18:46:55+02:00 summary: Use FASTCALL for __import__ (GH-31752) files: M Python/bltinmodule.c M Python/clinic/bltinmodule.c.h diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index b253f88a04bae..332f4cbbd0dcc 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -243,38 +243,41 @@ PyDoc_STRVAR(build_class_doc, \n\ Internal helper function used by the class statement."); +/*[clinic input] +__import__ as builtin___import__ + + name: object + globals: object(c_default="NULL") = None + locals: object(c_default="NULL") = None + fromlist: object(c_default="NULL") = () + level: int = 0 + +Import a module. + +Because this function is meant for use by the Python +interpreter and not for general use, it is better to use +importlib.import_module() to programmatically import a module. + +The globals argument is only used to determine the context; +they are not modified. The locals argument is unused. The fromlist +should be a list of names to emulate ``from name import ...'', or an +empty list to emulate ``import name''. +When importing a module from a package, note that __import__('A.B', ...) +returns package A when fromlist is empty, but its submodule B when +fromlist is not empty. The level argument is used to determine whether to +perform absolute or relative imports: 0 is absolute, while a positive number +is the number of parent directories to search relative to the current module. +[clinic start generated code]*/ + static PyObject * -builtin___import__(PyObject *self, PyObject *args, PyObject *kwds) +builtin___import___impl(PyObject *module, PyObject *name, PyObject *globals, + PyObject *locals, PyObject *fromlist, int level) +/*[clinic end generated code: output=4febeda88a0cd245 input=35e9a6460412430f]*/ { - static char *kwlist[] = {"name", "globals", "locals", "fromlist", - "level", 0}; - PyObject *name, *globals = NULL, *locals = NULL, *fromlist = NULL; - int level = 0; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "U|OOOi:__import__", - kwlist, &name, &globals, &locals, &fromlist, &level)) - return NULL; return PyImport_ImportModuleLevelObject(name, globals, locals, fromlist, level); } -PyDoc_STRVAR(import_doc, -"__import__(name, globals=None, locals=None, fromlist=(), level=0) -> module\n\ -\n\ -Import a module. Because this function is meant for use by the Python\n\ -interpreter and not for general use, it is better to use\n\ -importlib.import_module() to programmatically import a module.\n\ -\n\ -The globals argument is only used to determine the context;\n\ -they are not modified. The locals argument is unused. The fromlist\n\ -should be a list of names to emulate ``from name import ...'', or an\n\ -empty list to emulate ``import name''.\n\ -When importing a module from a package, note that __import__('A.B', ...)\n\ -returns package A when fromlist is empty, but its submodule B when\n\ -fromlist is not empty. The level argument is used to determine whether to\n\ -perform absolute or relative imports: 0 is absolute, while a positive number\n\ -is the number of parent directories to search relative to the current module."); - /*[clinic input] abs as builtin_abs @@ -2903,7 +2906,7 @@ PyTypeObject PyZip_Type = { static PyMethodDef builtin_methods[] = { {"__build_class__", (PyCFunction)(void(*)(void))builtin___build_class__, METH_FASTCALL | METH_KEYWORDS, build_class_doc}, - {"__import__", (PyCFunction)(void(*)(void))builtin___import__, METH_VARARGS | METH_KEYWORDS, import_doc}, + BUILTIN___IMPORT___METHODDEF BUILTIN_ABS_METHODDEF BUILTIN_ALL_METHODDEF BUILTIN_ANY_METHODDEF diff --git a/Python/clinic/bltinmodule.c.h b/Python/clinic/bltinmodule.c.h index 1fade994f40e3..4053f5a341e1f 100644 --- a/Python/clinic/bltinmodule.c.h +++ b/Python/clinic/bltinmodule.c.h @@ -2,6 +2,85 @@ preserve [clinic start generated code]*/ +PyDoc_STRVAR(builtin___import____doc__, +"__import__($module, /, name, globals=None, locals=None, fromlist=(),\n" +" level=0)\n" +"--\n" +"\n" +"Import a module.\n" +"\n" +"Because this function is meant for use by the Python\n" +"interpreter and not for general use, it is better to use\n" +"importlib.import_module() to programmatically import a module.\n" +"\n" +"The globals argument is only used to determine the context;\n" +"they are not modified. The locals argument is unused. The fromlist\n" +"should be a list of names to emulate ``from name import ...\'\', or an\n" +"empty list to emulate ``import name\'\'.\n" +"When importing a module from a package, note that __import__(\'A.B\', ...)\n" +"returns package A when fromlist is empty, but its submodule B when\n" +"fromlist is not empty. The level argument is used to determine whether to\n" +"perform absolute or relative imports: 0 is absolute, while a positive number\n" +"is the number of parent directories to search relative to the current module."); + +#define BUILTIN___IMPORT___METHODDEF \ + {"__import__", (PyCFunction)(void(*)(void))builtin___import__, METH_FASTCALL|METH_KEYWORDS, builtin___import____doc__}, + +static PyObject * +builtin___import___impl(PyObject *module, PyObject *name, PyObject *globals, + PyObject *locals, PyObject *fromlist, int level); + +static PyObject * +builtin___import__(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"name", "globals", "locals", "fromlist", "level", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "__import__", 0}; + PyObject *argsbuf[5]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *name; + PyObject *globals = NULL; + PyObject *locals = NULL; + PyObject *fromlist = NULL; + int level = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 5, 0, argsbuf); + if (!args) { + goto exit; + } + name = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + globals = args[1]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[2]) { + locals = args[2]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[3]) { + fromlist = args[3]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + level = _PyLong_AsInt(args[4]); + if (level == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = builtin___import___impl(module, name, globals, locals, fromlist, level); + +exit: + return return_value; +} + PyDoc_STRVAR(builtin_abs__doc__, "abs($module, x, /)\n" "--\n" @@ -951,4 +1030,4 @@ builtin_issubclass(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=77ace832b3fb38e0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d341fa7525f30070 input=a9049054013a1b77]*/ From webhook-mailer at python.org Fri Mar 11 14:05:59 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 11 Mar 2022 19:05:59 -0000 Subject: [Python-checkins] bpo-31327: Update time documentation to reflect possible errors (GH-31460) Message-ID: https://github.com/python/cpython/commit/c83fc9c02c9846ec3a2d0123999c98e02f00b3f5 commit: c83fc9c02c9846ec3a2d0123999c98e02f00b3f5 branch: main author: slateny <46876382+slateny at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-11T11:05:51-08:00 summary: bpo-31327: Update time documentation to reflect possible errors (GH-31460) As per the comments, this mirrors the [datetime documentation](https://docs.python.org/3/library/datetime.html#datetime.datetime.fromtimestamp). ``` >>> import time >>> time.localtime(999999999999999999999) Traceback (most recent call last): File "", line 1, in OverflowError: timestamp out of range for platform time_t >>> time.localtime(-3600) Traceback (most recent call last): File "", line 1, in OSError: [Errno 22] Invalid argument ``` files: M Doc/library/time.rst diff --git a/Doc/library/time.rst b/Doc/library/time.rst index d524f4ffebc75..be17fa68eb7b5 100644 --- a/Doc/library/time.rst +++ b/Doc/library/time.rst @@ -257,6 +257,12 @@ Functions :const:`None`, the current time as returned by :func:`.time` is used. The dst flag is set to ``1`` when DST applies to the given time. + :func:`localtime` may raise :exc:`OverflowError`, if the timestamp is + outside the range of values supported by the platform C :c:func:`localtime` + or :c:func:`gmtime` functions, and :exc:`OSError` on :c:func:`localtime` or + :c:func:`gmtime` failure. It's common for this to be restricted to years + between 1970 and 2038. + .. function:: mktime(t) From webhook-mailer at python.org Fri Mar 11 14:28:48 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 11 Mar 2022 19:28:48 -0000 Subject: [Python-checkins] bpo-31327: Update time documentation to reflect possible errors (GH-31460) Message-ID: https://github.com/python/cpython/commit/30d80213ae305bd0f0ed6bec7a0dff3e97b1c321 commit: 30d80213ae305bd0f0ed6bec7a0dff3e97b1c321 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-11T11:28:19-08:00 summary: bpo-31327: Update time documentation to reflect possible errors (GH-31460) As per the comments, this mirrors the [datetime documentation](https://docs.python.org/3/library/datetime.htmlGH-datetime.datetime.fromtimestamp). ``` >>> import time >>> time.localtime(999999999999999999999) Traceback (most recent call last): File "", line 1, in OverflowError: timestamp out of range for platform time_t >>> time.localtime(-3600) Traceback (most recent call last): File "", line 1, in OSError: [Errno 22] Invalid argument ``` (cherry picked from commit c83fc9c02c9846ec3a2d0123999c98e02f00b3f5) Co-authored-by: slateny <46876382+slateny at users.noreply.github.com> files: M Doc/library/time.rst diff --git a/Doc/library/time.rst b/Doc/library/time.rst index 0dca9a8eed24b..45f2ef14b4bf4 100644 --- a/Doc/library/time.rst +++ b/Doc/library/time.rst @@ -253,6 +253,12 @@ Functions :const:`None`, the current time as returned by :func:`.time` is used. The dst flag is set to ``1`` when DST applies to the given time. + :func:`localtime` may raise :exc:`OverflowError`, if the timestamp is + outside the range of values supported by the platform C :c:func:`localtime` + or :c:func:`gmtime` functions, and :exc:`OSError` on :c:func:`localtime` or + :c:func:`gmtime` failure. It's common for this to be restricted to years + between 1970 and 2038. + .. function:: mktime(t) From webhook-mailer at python.org Fri Mar 11 14:29:56 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 11 Mar 2022 19:29:56 -0000 Subject: [Python-checkins] bpo-31327: Update time documentation to reflect possible errors (GH-31460) Message-ID: https://github.com/python/cpython/commit/b35b36e106152245fe68880f4073fd99ec17f65d commit: b35b36e106152245fe68880f4073fd99ec17f65d branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-11T11:29:48-08:00 summary: bpo-31327: Update time documentation to reflect possible errors (GH-31460) As per the comments, this mirrors the [datetime documentation](https://docs.python.org/3/library/datetime.htmlGH-datetime.datetime.fromtimestamp). ``` >>> import time >>> time.localtime(999999999999999999999) Traceback (most recent call last): File "", line 1, in OverflowError: timestamp out of range for platform time_t >>> time.localtime(-3600) Traceback (most recent call last): File "", line 1, in OSError: [Errno 22] Invalid argument ``` (cherry picked from commit c83fc9c02c9846ec3a2d0123999c98e02f00b3f5) Co-authored-by: slateny <46876382+slateny at users.noreply.github.com> files: M Doc/library/time.rst diff --git a/Doc/library/time.rst b/Doc/library/time.rst index 735588a17e6e3..ed1f71dea4a0d 100644 --- a/Doc/library/time.rst +++ b/Doc/library/time.rst @@ -259,6 +259,12 @@ Functions :const:`None`, the current time as returned by :func:`.time` is used. The dst flag is set to ``1`` when DST applies to the given time. + :func:`localtime` may raise :exc:`OverflowError`, if the timestamp is + outside the range of values supported by the platform C :c:func:`localtime` + or :c:func:`gmtime` functions, and :exc:`OSError` on :c:func:`localtime` or + :c:func:`gmtime` failure. It's common for this to be restricted to years + between 1970 and 2038. + .. function:: mktime(t) From webhook-mailer at python.org Fri Mar 11 14:44:16 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Fri, 11 Mar 2022 19:44:16 -0000 Subject: [Python-checkins] bpo-43224: Implement substitution of unpacked TypeVarTuple (GH-31800) Message-ID: https://github.com/python/cpython/commit/5b1b9eacb92dd47d10793a8868246df6ea477ed6 commit: 5b1b9eacb92dd47d10793a8868246df6ea477ed6 branch: main author: Serhiy Storchaka committer: serhiy-storchaka date: 2022-03-11T21:43:58+02:00 summary: bpo-43224: Implement substitution of unpacked TypeVarTuple (GH-31800) files: M Lib/test/test_typing.py M Lib/typing.py diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 91b2e77e97b5a..a6936653bc566 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -411,6 +411,10 @@ def test_cannot_be_called(self): class TypeVarTupleTests(BaseTestCase): + def assertEndsWith(self, string, tail): + if not string.endswith(tail): + self.fail(f"String {string!r} does not end with {tail!r}") + def test_instance_is_equal_to_itself(self): Ts = TypeVarTuple('Ts') self.assertEqual(Ts, Ts) @@ -457,6 +461,56 @@ def test_tuple_args_and_parameters_are_correct(self): self.assertEqual(t2.__args__, (Unpack[Ts],)) self.assertEqual(t2.__parameters__, (Ts,)) + def test_var_substitution(self): + Ts = TypeVarTuple('Ts') + T = TypeVar('T') + T2 = TypeVar('T2') + class G(Generic[Unpack[Ts]]): pass + + for A in G, Tuple: + B = A[Unpack[Ts]] + if A != Tuple: + self.assertEqual(B[()], A[()]) + self.assertEqual(B[float], A[float]) + self.assertEqual(B[float, str], A[float, str]) + + C = List[A[Unpack[Ts]]] + if A != Tuple: + self.assertEqual(C[()], List[A[()]]) + self.assertEqual(C[float], List[A[float]]) + self.assertEqual(C[float, str], List[A[float, str]]) + + D = A[T, Unpack[Ts], T2] + with self.assertRaises(TypeError): + D[()] + with self.assertRaises(TypeError): + D[float] + self.assertEqual(D[float, str], A[float, str]) + self.assertEqual(D[float, str, int], A[float, str, int]) + self.assertEqual(D[float, str, int, bytes], A[float, str, int, bytes]) + + E = Tuple[List[T], A[Unpack[Ts]], List[T2]] + with self.assertRaises(TypeError): + E[()] + with self.assertRaises(TypeError): + E[float] + if A != Tuple: + self.assertEqual(E[float, str], + Tuple[List[float], A[()], List[str]]) + self.assertEqual(E[float, str, int], + Tuple[List[float], A[str], List[int]]) + self.assertEqual(E[float, str, int, bytes], + Tuple[List[float], A[str, int], List[bytes]]) + + def test_repr_is_correct(self): + Ts = TypeVarTuple('Ts') + self.assertEqual(repr(Ts), 'Ts') + self.assertEqual(repr(Unpack[Ts]), '*Ts') + self.assertEqual(repr(tuple[Unpack[Ts]]), 'tuple[*Ts]') + self.assertEqual(repr(Tuple[Unpack[Ts]]), 'typing.Tuple[*Ts]') + self.assertEqual(repr(Unpack[tuple[Unpack[Ts]]]), '*tuple[*Ts]') + self.assertEqual(repr(Unpack[Tuple[Unpack[Ts]]]), '*typing.Tuple[*Ts]') + def test_repr_is_correct(self): Ts = TypeVarTuple('Ts') self.assertEqual(repr(Ts), 'Ts') @@ -470,78 +524,51 @@ def test_variadic_class_repr_is_correct(self): Ts = TypeVarTuple('Ts') class A(Generic[Unpack[Ts]]): pass - self.assertTrue(repr(A[()]).endswith('A[()]')) - self.assertTrue(repr(A[float]).endswith('A[float]')) - self.assertTrue(repr(A[float, str]).endswith('A[float, str]')) - self.assertTrue(repr( - A[Unpack[tuple[int, ...]]] - ).endswith( - 'A[*tuple[int, ...]]' - )) - self.assertTrue(repr( - A[float, Unpack[tuple[int, ...]]] - ).endswith( - 'A[float, *tuple[int, ...]]' - )) - self.assertTrue(repr( - A[Unpack[tuple[int, ...]], str] - ).endswith( - 'A[*tuple[int, ...], str]' - )) - self.assertTrue(repr( - A[float, Unpack[tuple[int, ...]], str] - ).endswith( - 'A[float, *tuple[int, ...], str]' - )) + self.assertEndsWith(repr(A[()]), 'A[()]') + self.assertEndsWith(repr(A[float]), 'A[float]') + self.assertEndsWith(repr(A[float, str]), 'A[float, str]') + self.assertEndsWith(repr(A[Unpack[tuple[int, ...]]]), + 'A[*tuple[int, ...]]') + self.assertEndsWith(repr(A[float, Unpack[tuple[int, ...]]]), + 'A[float, *tuple[int, ...]]') + self.assertEndsWith(repr(A[Unpack[tuple[int, ...]], str]), + 'A[*tuple[int, ...], str]') + self.assertEndsWith(repr(A[float, Unpack[tuple[int, ...]], str]), + 'A[float, *tuple[int, ...], str]') def test_variadic_class_alias_repr_is_correct(self): Ts = TypeVarTuple('Ts') class A(Generic[Unpack[Ts]]): pass B = A[Unpack[Ts]] - self.assertTrue(repr(B).endswith('A[*Ts]')) - with self.assertRaises(NotImplementedError): - B[()] - with self.assertRaises(NotImplementedError): - B[float] - with self.assertRaises(NotImplementedError): - B[float, str] + self.assertEndsWith(repr(B), 'A[*Ts]') + self.assertEndsWith(repr(B[()]), 'A[()]') + self.assertEndsWith(repr(B[float]), 'A[float]') + self.assertEndsWith(repr(B[float, str]), 'A[float, str]') C = A[Unpack[Ts], int] - self.assertTrue(repr(C).endswith('A[*Ts, int]')) - with self.assertRaises(NotImplementedError): - C[()] - with self.assertRaises(NotImplementedError): - C[float] - with self.assertRaises(NotImplementedError): - C[float, str] + self.assertEndsWith(repr(C), 'A[*Ts, int]') + self.assertEndsWith(repr(C[()]), 'A[int]') + self.assertEndsWith(repr(C[float]), 'A[float, int]') + self.assertEndsWith(repr(C[float, str]), 'A[float, str, int]') D = A[int, Unpack[Ts]] - self.assertTrue(repr(D).endswith('A[int, *Ts]')) - with self.assertRaises(NotImplementedError): - D[()] - with self.assertRaises(NotImplementedError): - D[float] - with self.assertRaises(NotImplementedError): - D[float, str] + self.assertEndsWith(repr(D), 'A[int, *Ts]') + self.assertEndsWith(repr(D[()]), 'A[int]') + self.assertEndsWith(repr(D[float]), 'A[int, float]') + self.assertEndsWith(repr(D[float, str]), 'A[int, float, str]') E = A[int, Unpack[Ts], str] - self.assertTrue(repr(E).endswith('A[int, *Ts, str]')) - with self.assertRaises(NotImplementedError): - E[()] - with self.assertRaises(NotImplementedError): - E[float] - with self.assertRaises(NotImplementedError): - E[float, bool] + self.assertEndsWith(repr(E), 'A[int, *Ts, str]') + self.assertEndsWith(repr(E[()]), 'A[int, str]') + self.assertEndsWith(repr(E[float]), 'A[int, float, str]') + self.assertEndsWith(repr(E[float, str]), 'A[int, float, str, str]') F = A[Unpack[Ts], Unpack[tuple[str, ...]]] - self.assertTrue(repr(F).endswith('A[*Ts, *tuple[str, ...]]')) - with self.assertRaises(NotImplementedError): - F[()] - with self.assertRaises(NotImplementedError): - F[float] - with self.assertRaises(NotImplementedError): - F[float, int] + self.assertEndsWith(repr(F), 'A[*Ts, *tuple[str, ...]]') + self.assertEndsWith(repr(F[()]), 'A[*tuple[str, ...]]') + self.assertEndsWith(repr(F[float]), 'A[float, *tuple[str, ...]]') + self.assertEndsWith(repr(F[float, str]), 'A[float, str, *tuple[str, ...]]') def test_cannot_subclass_class(self): with self.assertRaises(TypeError): diff --git a/Lib/typing.py b/Lib/typing.py index 062c01ef2a9b9..842554f193ca7 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1297,30 +1297,39 @@ def _determine_new_args(self, args): # anything more exotic than a plain `TypeVar`, we need to consider # edge cases. - if any(isinstance(p, TypeVarTuple) for p in self.__parameters__): - raise NotImplementedError( - "Type substitution for TypeVarTuples is not yet implemented" - ) + params = self.__parameters__ # In the example above, this would be {T3: str} - new_arg_by_param = dict(zip(self.__parameters__, args)) + new_arg_by_param = {} + for i, param in enumerate(params): + if isinstance(param, TypeVarTuple): + j = len(args) - (len(params) - i - 1) + if j < i: + raise TypeError(f"Too few arguments for {self}") + new_arg_by_param.update(zip(params[:i], args[:i])) + new_arg_by_param[param] = args[i: j] + new_arg_by_param.update(zip(params[i + 1:], args[j:])) + break + else: + new_arg_by_param.update(zip(params, args)) new_args = [] for old_arg in self.__args__: - if _is_unpacked_typevartuple(old_arg): - original_typevartuple = old_arg.__parameters__[0] - new_arg = new_arg_by_param[original_typevartuple] + substfunc = getattr(old_arg, '__typing_subst__', None) + if substfunc: + new_arg = substfunc(new_arg_by_param[old_arg]) else: - substfunc = getattr(old_arg, '__typing_subst__', None) - if substfunc: - new_arg = substfunc(new_arg_by_param[old_arg]) + subparams = getattr(old_arg, '__parameters__', ()) + if not subparams: + new_arg = old_arg else: - subparams = getattr(old_arg, '__parameters__', ()) - if not subparams: - new_arg = old_arg - else: - subargs = tuple(new_arg_by_param[x] for x in subparams) - new_arg = old_arg[subargs] + subargs = [] + for x in subparams: + if isinstance(x, TypeVarTuple): + subargs.extend(new_arg_by_param[x]) + else: + subargs.append(new_arg_by_param[x]) + new_arg = old_arg[tuple(subargs)] if self.__origin__ == collections.abc.Callable and isinstance(new_arg, tuple): # Consider the following `Callable`. @@ -1612,6 +1621,12 @@ def __repr__(self): # a single item. return '*' + repr(self.__args__[0]) + def __getitem__(self, args): + if (len(self.__parameters__) == 1 and + isinstance(self.__parameters__[0], TypeVarTuple)): + return args + return super().__getitem__(args) + class Generic: """Abstract base class for generic types. From webhook-mailer at python.org Fri Mar 11 17:01:45 2022 From: webhook-mailer at python.org (vstinner) Date: Fri, 11 Mar 2022 22:01:45 -0000 Subject: [Python-checkins] bpo-46968: Add os.sysconf_names['SC_MINSIGSTKSZ'] (GH-31824) Message-ID: https://github.com/python/cpython/commit/dc374ac7b0fabaed49461a2044c220765f48d229 commit: dc374ac7b0fabaed49461a2044c220765f48d229 branch: main author: Victor Stinner committer: vstinner date: 2022-03-11T23:01:40+01:00 summary: bpo-46968: Add os.sysconf_names['SC_MINSIGSTKSZ'] (GH-31824) files: A Misc/NEWS.d/next/Library/2022-03-11-17-56-25.bpo-46968.pPVvNo.rst M Doc/library/os.rst M Modules/posixmodule.c diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 234ea3238ef99..6dffc4513365e 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -4755,6 +4755,9 @@ Miscellaneous System Information .. availability:: Unix. + .. versionchanged:: 3.11 + Add ``'SC_MINSIGSTKSZ'`` name. + The following data values are used to support path manipulation operations. These are defined for all platforms. diff --git a/Misc/NEWS.d/next/Library/2022-03-11-17-56-25.bpo-46968.pPVvNo.rst b/Misc/NEWS.d/next/Library/2022-03-11-17-56-25.bpo-46968.pPVvNo.rst new file mode 100644 index 0000000000000..f526fa30cd60e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-11-17-56-25.bpo-46968.pPVvNo.rst @@ -0,0 +1 @@ +Add ``os.sysconf_names['SC_MINSIGSTKSZ']``. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 3431c85e2dfde..700cbd2617ad8 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -12346,6 +12346,9 @@ static struct constdef posix_constants_sysconf[] = { #ifdef _SC_XOPEN_XPG4 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4}, #endif +#ifdef _SC_MINSIGSTKSZ + {"SC_MINSIGSTKSZ", _SC_MINSIGSTKSZ}, +#endif }; static int From webhook-mailer at python.org Fri Mar 11 17:19:43 2022 From: webhook-mailer at python.org (vstinner) Date: Fri, 11 Mar 2022 22:19:43 -0000 Subject: [Python-checkins] bpo-46968: Fix faulthandler for Sapphire Rapids Xeon (GH-31789) Message-ID: https://github.com/python/cpython/commit/3b128c054885fe881c3b57a5978de3ea89c81a9c commit: 3b128c054885fe881c3b57a5978de3ea89c81a9c branch: main author: Oleksandr Pavlyk committer: vstinner date: 2022-03-11T23:19:35+01:00 summary: bpo-46968: Fix faulthandler for Sapphire Rapids Xeon (GH-31789) In Linux kernel 5.14 one can dynamically request size of altstacksize based on hardware capabilities with getauxval(AT_MINSIGSTKSZ). This changes allows for Python extension's request to Linux kernel to use AMX_TILE instruction set on Sapphire Rapids Xeon processor to succeed, unblocking use of the ISA in frameworks. Introduced HAVE_LINUX_AUXVEC_H in configure.ac and pyconfig.h.in Used cpython_autoconf:269 docker container to generate configure. files: A Misc/NEWS.d/next/Library/2022-03-10-14-51-11.bpo-46968.ym2QxL.rst M Modules/faulthandler.c M configure M configure.ac M pyconfig.h.in diff --git a/Misc/NEWS.d/next/Library/2022-03-10-14-51-11.bpo-46968.ym2QxL.rst b/Misc/NEWS.d/next/Library/2022-03-10-14-51-11.bpo-46968.ym2QxL.rst new file mode 100644 index 0000000000000..0da5ae76572ba --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-10-14-51-11.bpo-46968.ym2QxL.rst @@ -0,0 +1,5 @@ +:mod:`faulthandler`: On Linux 5.14 and newer, dynamically determine size of +signal handler stack size CPython allocates using ``getauxval(AT_MINSIGSTKSZ)``. +This changes allows for Python extension's request to Linux kernel to use +AMX_TILE instruction set on Sapphire Rapids Xeon processor to succeed, +unblocking use of the ISA in frameworks. diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index db3f4fbe5c616..744698cd7aba2 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -20,6 +20,17 @@ # include #endif +/* Using an alternative stack requires sigaltstack() + and sigaction() SA_ONSTACK */ +#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) +# define FAULTHANDLER_USE_ALT_STACK +#endif + +#if defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_LINUX_AUXVEC_H) +# include +# include +#endif + /* Allocate at maximum 100 MiB of the stack to raise the stack overflow */ #define STACK_OVERFLOW_MAX_SIZE (100 * 1024 * 1024) @@ -137,12 +148,6 @@ static fault_handler_t faulthandler_handlers[] = { static const size_t faulthandler_nsignals = \ Py_ARRAY_LENGTH(faulthandler_handlers); -/* Using an alternative stack requires sigaltstack() - and sigaction() SA_ONSTACK */ -#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) -# define FAULTHANDLER_USE_ALT_STACK -#endif - #ifdef FAULTHANDLER_USE_ALT_STACK static stack_t stack; static stack_t old_stack; @@ -1373,6 +1378,15 @@ _PyFaulthandler_Init(int enable) signal handler uses more than SIGSTKSZ bytes of stack memory on some platforms. */ stack.ss_size = SIGSTKSZ * 2; +#ifdef AT_MINSIGSTKSZ + /* bpo-46968: Query Linux for minimal stack size to ensure signal delivery + for the hardware running CPython. This OS feature is available in + Linux kernel version >= 5.14 */ + unsigned long at_minstack_size = getauxval(AT_MINSIGSTKSZ); + if (at_minstack_size != 0) { + stack.ss_size = SIGSTKSZ + at_minstack_size; + } +#endif #endif memset(&thread, 0, sizeof(thread)); diff --git a/configure b/configure index a8e78ce73e708..4d585eba626a6 100755 --- a/configure +++ b/configure @@ -8652,7 +8652,7 @@ $as_echo "#define STDC_HEADERS 1" >>confdefs.h # checks for header files for ac_header in \ alloca.h asm/types.h bluetooth.h conio.h crypt.h direct.h dlfcn.h endian.h errno.h fcntl.h grp.h \ - ieeefp.h io.h langinfo.h libintl.h libutil.h linux/memfd.h linux/random.h linux/soundcard.h \ + ieeefp.h io.h langinfo.h libintl.h libutil.h linux/auxvec.h linux/memfd.h linux/random.h linux/soundcard.h \ linux/tipc.h linux/wait.h netinet/in.h netpacket/packet.h poll.h process.h pthread.h pty.h \ sched.h setjmp.h shadow.h signal.h spawn.h stropts.h sys/audioio.h sys/bsdtty.h sys/devpoll.h \ sys/endian.h sys/epoll.h sys/event.h sys/eventfd.h sys/file.h sys/ioctl.h sys/kern_control.h \ diff --git a/configure.ac b/configure.ac index 3e7d04b8eae62..81262ae38e534 100644 --- a/configure.ac +++ b/configure.ac @@ -2375,7 +2375,7 @@ AC_DEFINE(STDC_HEADERS, 1, [Define to 1 if you have the ANSI C header files.]) # checks for header files AC_CHECK_HEADERS([ \ alloca.h asm/types.h bluetooth.h conio.h crypt.h direct.h dlfcn.h endian.h errno.h fcntl.h grp.h \ - ieeefp.h io.h langinfo.h libintl.h libutil.h linux/memfd.h linux/random.h linux/soundcard.h \ + ieeefp.h io.h langinfo.h libintl.h libutil.h linux/auxvec.h linux/memfd.h linux/random.h linux/soundcard.h \ linux/tipc.h linux/wait.h netinet/in.h netpacket/packet.h poll.h process.h pthread.h pty.h \ sched.h setjmp.h shadow.h signal.h spawn.h stropts.h sys/audioio.h sys/bsdtty.h sys/devpoll.h \ sys/endian.h sys/epoll.h sys/event.h sys/eventfd.h sys/file.h sys/ioctl.h sys/kern_control.h \ diff --git a/pyconfig.h.in b/pyconfig.h.in index 40057e0ff87d9..1b84ee108fbfc 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -661,6 +661,9 @@ /* Define to 1 if you have the `linkat' function. */ #undef HAVE_LINKAT +/* Define to 1 if you have the header file. */ +#undef HAVE_LINUX_AUXVEC_H + /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_CAN_BCM_H From webhook-mailer at python.org Fri Mar 11 17:25:24 2022 From: webhook-mailer at python.org (tiran) Date: Fri, 11 Mar 2022 22:25:24 -0000 Subject: [Python-checkins] bpo-40280: Disable AF_UNIX, AF_PACKET, SO_REUSE* on Emscripten (#31829) Message-ID: https://github.com/python/cpython/commit/ecfff63e06e77e22035a7f7caa26986f033f3aea commit: ecfff63e06e77e22035a7f7caa26986f033f3aea branch: main author: Christian Heimes committer: tiran date: 2022-03-11T23:25:14+01:00 summary: bpo-40280: Disable AF_UNIX, AF_PACKET, SO_REUSE* on Emscripten (#31829) Emscripten's socket emulation is limited. AF_UNIX, AF_PACKET, setsockopt(), and most SO_* constants are not supported. files: M Lib/socketserver.py M Modules/socketmodule.c M Modules/socketmodule.h M Tools/wasm/config.site-wasm32-emscripten diff --git a/Lib/socketserver.py b/Lib/socketserver.py index 5e070bc3912af..30a5cfa59fe05 100644 --- a/Lib/socketserver.py +++ b/Lib/socketserver.py @@ -465,9 +465,9 @@ def server_bind(self): May be overridden. """ - if self.allow_reuse_address: + if self.allow_reuse_address and hasattr(socket, "SO_REUSEADDR"): self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - if self.allow_reuse_port: + if self.allow_reuse_port and hasattr(socket, "SO_REUSEPORT"): self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) self.socket.bind(self.server_address) self.server_address = self.socket.getsockname() diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 3fca9f68512e8..fbdd1a164db25 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -7933,7 +7933,7 @@ PyInit__socket(void) #ifdef IPPROTO_VRRP PyModule_AddIntMacro(m, IPPROTO_VRRP); #endif -#if defined(IPPROTO_SCTP) && !defined(__EMSCRIPTEN__) +#ifdef IPPROTO_SCTP PyModule_AddIntMacro(m, IPPROTO_SCTP); #endif #ifdef IPPROTO_BIP diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h index db26c046c3637..1b35b11cdee6a 100644 --- a/Modules/socketmodule.h +++ b/Modules/socketmodule.h @@ -192,6 +192,21 @@ typedef int socklen_t; #endif /* HAVE_SOCKADDR_ALG */ +#ifdef __EMSCRIPTEN__ +// wasm32-emscripten sockets only support subset of IPv4 and IPv6. +// SCTP protocol crashes runtime. +#ifdef IPPROTO_SCTP +# undef IPPROTO_SCTP +#endif +// setsockopt() fails with ENOPROTOOPT, getsockopt only supports SO_ERROR. +// undef SO_REUSEADDR and SO_REUSEPORT so they cannot be used. +#ifdef SO_REUSEADDR +# undef SO_REUSEADDR +#endif +#ifdef SO_REUSEPORT +# undef SO_REUSEPORT +#endif +#endif // __EMSCRIPTEN__ #ifndef Py__SOCKET_H #define Py__SOCKET_H diff --git a/Tools/wasm/config.site-wasm32-emscripten b/Tools/wasm/config.site-wasm32-emscripten index 5eaa7933776a8..2a601987ccedf 100644 --- a/Tools/wasm/config.site-wasm32-emscripten +++ b/Tools/wasm/config.site-wasm32-emscripten @@ -74,8 +74,10 @@ ac_cv_func_posix_fallocate=no ac_cv_func_utimensat=no ac_cv_header_sys_ioctl_h=no -# sockets are supported, but only in non-blocking mode -# ac_cv_header_sys_socket_h=no +# sockets are supported, but only AF_INET / AF_INET6 in non-blocking mode. +# Disable AF_UNIX and AF_PACKET support, see socketmodule.h. +ac_cv_header_sys_un_h=no +ac_cv_header_netpacket_packet_h=no # aborts with bad ioctl ac_cv_func_openpty=no From webhook-mailer at python.org Fri Mar 11 18:04:30 2022 From: webhook-mailer at python.org (vstinner) Date: Fri, 11 Mar 2022 23:04:30 -0000 Subject: [Python-checkins] bpo-46968: Fix faulthandler for Sapphire Rapids Xeon (GH-31789) (GH-31830) Message-ID: https://github.com/python/cpython/commit/393e2bf6bc6effbfe821f051a230978f0edd70df commit: 393e2bf6bc6effbfe821f051a230978f0edd70df branch: 3.10 author: Victor Stinner committer: vstinner date: 2022-03-12T00:04:14+01:00 summary: bpo-46968: Fix faulthandler for Sapphire Rapids Xeon (GH-31789) (GH-31830) In Linux kernel 5.14 one can dynamically request size of altstacksize based on hardware capabilities with getauxval(AT_MINSIGSTKSZ). This changes allows for Python extension's request to Linux kernel to use AMX_TILE instruction set on Sapphire Rapids Xeon processor to succeed, unblocking use of the ISA in frameworks. Introduced HAVE_LINUX_AUXVEC_H in configure.ac and pyconfig.h.in Used cpython_autoconf:269 docker container to generate configure. (cherry picked from commit 3b128c054885fe881c3b57a5978de3ea89c81a9c) Co-authored-by: Oleksandr Pavlyk files: A Misc/NEWS.d/next/Library/2022-03-10-14-51-11.bpo-46968.ym2QxL.rst M Modules/faulthandler.c M configure M configure.ac M pyconfig.h.in diff --git a/Misc/NEWS.d/next/Library/2022-03-10-14-51-11.bpo-46968.ym2QxL.rst b/Misc/NEWS.d/next/Library/2022-03-10-14-51-11.bpo-46968.ym2QxL.rst new file mode 100644 index 0000000000000..0da5ae76572ba --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-10-14-51-11.bpo-46968.ym2QxL.rst @@ -0,0 +1,5 @@ +:mod:`faulthandler`: On Linux 5.14 and newer, dynamically determine size of +signal handler stack size CPython allocates using ``getauxval(AT_MINSIGSTKSZ)``. +This changes allows for Python extension's request to Linux kernel to use +AMX_TILE instruction set on Sapphire Rapids Xeon processor to succeed, +unblocking use of the ISA in frameworks. diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index e03f6d96c8edb..88a5b9376aa7d 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -17,6 +17,17 @@ # include #endif +/* Using an alternative stack requires sigaltstack() + and sigaction() SA_ONSTACK */ +#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) +# define FAULTHANDLER_USE_ALT_STACK +#endif + +#if defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_LINUX_AUXVEC_H) +# include +# include +#endif + /* Allocate at maximum 100 MiB of the stack to raise the stack overflow */ #define STACK_OVERFLOW_MAX_SIZE (100 * 1024 * 1024) @@ -139,12 +150,6 @@ static fault_handler_t faulthandler_handlers[] = { static const size_t faulthandler_nsignals = \ Py_ARRAY_LENGTH(faulthandler_handlers); -/* Using an alternative stack requires sigaltstack() - and sigaction() SA_ONSTACK */ -#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) -# define FAULTHANDLER_USE_ALT_STACK -#endif - #ifdef FAULTHANDLER_USE_ALT_STACK static stack_t stack; static stack_t old_stack; @@ -1374,6 +1379,15 @@ _PyFaulthandler_Init(int enable) signal handler uses more than SIGSTKSZ bytes of stack memory on some platforms. */ stack.ss_size = SIGSTKSZ * 2; +#ifdef AT_MINSIGSTKSZ + /* bpo-46968: Query Linux for minimal stack size to ensure signal delivery + for the hardware running CPython. This OS feature is available in + Linux kernel version >= 5.14 */ + unsigned long at_minstack_size = getauxval(AT_MINSIGSTKSZ); + if (at_minstack_size != 0) { + stack.ss_size = SIGSTKSZ + at_minstack_size; + } +#endif #endif memset(&thread, 0, sizeof(thread)); diff --git a/configure b/configure index e68e00b0b338b..0cc86f9ed7687 100755 --- a/configure +++ b/configure @@ -8101,7 +8101,7 @@ sys/stat.h sys/syscall.h sys/sys_domain.h sys/termio.h sys/time.h \ sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \ libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \ linux/tipc.h linux/random.h spawn.h util.h alloca.h endian.h \ -sys/endian.h sys/sysmacros.h linux/memfd.h linux/wait.h sys/memfd.h \ +sys/endian.h sys/sysmacros.h linux/auxvec.h linux/memfd.h linux/wait.h sys/memfd.h \ sys/mman.h sys/eventfd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` diff --git a/configure.ac b/configure.ac index 0efeb8f585d09..547255ff31ebc 100644 --- a/configure.ac +++ b/configure.ac @@ -2225,7 +2225,7 @@ sys/stat.h sys/syscall.h sys/sys_domain.h sys/termio.h sys/time.h \ sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \ libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \ linux/tipc.h linux/random.h spawn.h util.h alloca.h endian.h \ -sys/endian.h sys/sysmacros.h linux/memfd.h linux/wait.h sys/memfd.h \ +sys/endian.h sys/sysmacros.h linux/auxvec.h linux/memfd.h linux/wait.h sys/memfd.h \ sys/mman.h sys/eventfd.h) AC_HEADER_DIRENT AC_HEADER_MAJOR diff --git a/pyconfig.h.in b/pyconfig.h.in index 8a4aeda646923..b0948e9b9b79d 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -637,6 +637,9 @@ /* Define to 1 if you have the `linkat' function. */ #undef HAVE_LINKAT +/* Define to 1 if you have the header file. */ +#undef HAVE_LINUX_AUXVEC_H + /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_CAN_BCM_H From webhook-mailer at python.org Fri Mar 11 18:10:11 2022 From: webhook-mailer at python.org (vstinner) Date: Fri, 11 Mar 2022 23:10:11 -0000 Subject: [Python-checkins] bpo-46906: Add PyFloat_Pack8() to the C API (GH-31657) Message-ID: https://github.com/python/cpython/commit/882d8096c262a5945e0cfdd706e5db3ad2b73543 commit: 882d8096c262a5945e0cfdd706e5db3ad2b73543 branch: main author: Victor Stinner committer: vstinner date: 2022-03-12T00:10:02+01:00 summary: bpo-46906: Add PyFloat_Pack8() to the C API (GH-31657) Add new functions to pack and unpack C double (serialize and deserialize): * PyFloat_Pack2(), PyFloat_Pack4(), PyFloat_Pack8() * PyFloat_Unpack2(), PyFloat_Unpack4(), PyFloat_Unpack8() Document these functions and add unit tests. Rename private functions and move them from the internal C API to the public C API: * _PyFloat_Pack2() => PyFloat_Pack2() * _PyFloat_Pack4() => PyFloat_Pack4() * _PyFloat_Pack8() => PyFloat_Pack8() * _PyFloat_Unpack2() => PyFloat_Unpack2() * _PyFloat_Unpack4() => PyFloat_Unpack4() * _PyFloat_Unpack8() => PyFloat_Unpack8() Replace the "unsigned char*" type with "char*" which is more common and easy to use. files: A Misc/NEWS.d/next/C API/2022-03-03-11-12-33.bpo-46906.-olyBI.rst M Doc/c-api/float.rst M Doc/whatsnew/3.11.rst M Include/cpython/floatobject.h M Include/internal/pycore_floatobject.h M Lib/test/test_float.py M Modules/_ctypes/cfield.c M Modules/_pickle.c M Modules/_struct.c M Modules/_testcapimodule.c M Modules/arraymodule.c M Objects/floatobject.c M Python/marshal.c diff --git a/Doc/c-api/float.rst b/Doc/c-api/float.rst index c107243a88dfc..fd81683452db2 100644 --- a/Doc/c-api/float.rst +++ b/Doc/c-api/float.rst @@ -76,3 +76,85 @@ Floating Point Objects .. c:function:: double PyFloat_GetMin() Return the minimum normalized positive float *DBL_MIN* as C :c:type:`double`. + + +Pack and Unpack functions +========================= + +The pack and unpack functions provide an efficient platform-independent way to +store floating-point values as byte strings. The Pack routines produce a bytes +string from a C :c:type:`double`, and the Unpack routines produce a C +:c:type:`double` from such a bytes string. The suffix (2, 4 or 8) specifies the +number of bytes in the bytes string. + +On platforms that appear to use IEEE 754 formats these functions work by +copying bits. On other platforms, the 2-byte format is identical to the IEEE +754 binary16 half-precision format, the 4-byte format (32-bit) is identical to +the IEEE 754 binary32 single precision format, and the 8-byte format to the +IEEE 754 binary64 double precision format, although the packing of INFs and +NaNs (if such things exist on the platform) isn't handled correctly, and +attempting to unpack a bytes string containing an IEEE INF or NaN will raise an +exception. + +On non-IEEE platforms with more precision, or larger dynamic range, than IEEE +754 supports, not all values can be packed; on non-IEEE platforms with less +precision, or smaller dynamic range, not all values can be unpacked. What +happens in such cases is partly accidental (alas). + +.. versionadded:: 3.11 + +Pack functions +-------------- + +The pack routines write 2, 4 or 8 bytes, starting at *p*. *le* is an +:c:type:`int` argument, non-zero if you want the bytes string in little-endian +format (exponent last, at ``p+1``, ``p+3``, or ``p+6`` ``p+7``), zero if you +want big-endian format (exponent first, at *p*). + +Return value: ``0`` if all is OK, ``-1`` if error (and an exception is set, +most likely :exc:`OverflowError`). + +There are two problems on non-IEEE platforms: + +* What this does is undefined if *x* is a NaN or infinity. +* ``-0.0`` and ``+0.0`` produce the same bytes string. + +.. c:function:: int PyFloat_Pack2(double x, unsigned char *p, int le) + + Pack a C double as the IEEE 754 binary16 half-precision format. + +.. c:function:: int PyFloat_Pack4(double x, unsigned char *p, int le) + + Pack a C double as the IEEE 754 binary32 single precision format. + +.. c:function:: int PyFloat_Pack8(double x, unsigned char *p, int le) + + Pack a C double as the IEEE 754 binary64 double precision format. + + +Unpack functions +---------------- + +The unpack routines read 2, 4 or 8 bytes, starting at *p*. *le* is an +:c:type:`int` argument, non-zero if the bytes string is in little-endian format +(exponent last, at ``p+1``, ``p+3`` or ``p+6`` and ``p+7``), zero if big-endian +(exponent first, at *p*). + +Return value: The unpacked double. On error, this is ``-1.0`` and +:c:func:`PyErr_Occurred` is true (and an exception is set, most likely +:exc:`OverflowError`). + +Note that on a non-IEEE platform this will refuse to unpack a bytes string that +represents a NaN or infinity. + +.. c:function:: double PyFloat_Unpack2(const unsigned char *p, int le) + + Unpack the IEEE 754 binary16 half-precision format as a C double. + +.. c:function:: double PyFloat_Unpack4(const unsigned char *p, int le) + + Unpack the IEEE 754 binary32 single precision format as a C double. + +.. c:function:: double PyFloat_Unpack8(const unsigned char *p, int le) + + Unpack the IEEE 754 binary64 double precision format as a C double. diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index ce15fb72f3c49..8ab6854663030 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -766,6 +766,12 @@ New Features available directly (via :c:type:`PyCMethod`). (Contributed by Petr Viktorin in :issue:`46613`.) +* Add new functions to pack and unpack C double (serialize and deserialize): + :c:func:`PyFloat_Pack2`, :c:func:`PyFloat_Pack4`, :c:func:`PyFloat_Pack8`, + :c:func:`PyFloat_Unpack2`, :c:func:`PyFloat_Unpack4` and + :c:func:`PyFloat_Unpack8`. + (Contributed by Victor Stinner in :issue:`46906`.) + Porting to Python 3.11 ---------------------- diff --git a/Include/cpython/floatobject.h b/Include/cpython/floatobject.h index fffd468690274..7795d9f83f05c 100644 --- a/Include/cpython/floatobject.h +++ b/Include/cpython/floatobject.h @@ -10,3 +10,12 @@ typedef struct { // Macro version of PyFloat_AsDouble() trading safety for speed. // It doesn't check if op is a double object. #define PyFloat_AS_DOUBLE(op) (((PyFloatObject *)(op))->ob_fval) + + +PyAPI_FUNC(int) PyFloat_Pack2(double x, char *p, int le); +PyAPI_FUNC(int) PyFloat_Pack4(double x, char *p, int le); +PyAPI_FUNC(int) PyFloat_Pack8(double x, char *p, int le); + +PyAPI_FUNC(double) PyFloat_Unpack2(const char *p, int le); +PyAPI_FUNC(double) PyFloat_Unpack4(const char *p, int le); +PyAPI_FUNC(double) PyFloat_Unpack8(const char *p, int le); diff --git a/Include/internal/pycore_floatobject.h b/Include/internal/pycore_floatobject.h index 891e422f59472..a099f2ebc0fec 100644 --- a/Include/internal/pycore_floatobject.h +++ b/Include/internal/pycore_floatobject.h @@ -38,54 +38,6 @@ struct _Py_float_state { #endif }; -/* _PyFloat_{Pack,Unpack}{4,8} - * - * The struct and pickle (at least) modules need an efficient platform- - * independent way to store floating-point values as byte strings. - * The Pack routines produce a string from a C double, and the Unpack - * routines produce a C double from such a string. The suffix (4 or 8) - * specifies the number of bytes in the string. - * - * On platforms that appear to use (see _PyFloat_Init()) IEEE-754 formats - * these functions work by copying bits. On other platforms, the formats the - * 4- byte format is identical to the IEEE-754 single precision format, and - * the 8-byte format to the IEEE-754 double precision format, although the - * packing of INFs and NaNs (if such things exist on the platform) isn't - * handled correctly, and attempting to unpack a string containing an IEEE - * INF or NaN will raise an exception. - * - * On non-IEEE platforms with more precision, or larger dynamic range, than - * 754 supports, not all values can be packed; on non-IEEE platforms with less - * precision, or smaller dynamic range, not all values can be unpacked. What - * happens in such cases is partly accidental (alas). - */ - -/* The pack routines write 2, 4 or 8 bytes, starting at p. le is a bool - * argument, true if you want the string in little-endian format (exponent - * last, at p+1, p+3 or p+7), false if you want big-endian format (exponent - * first, at p). - * Return value: 0 if all is OK, -1 if error (and an exception is - * set, most likely OverflowError). - * There are two problems on non-IEEE platforms: - * 1): What this does is undefined if x is a NaN or infinity. - * 2): -0.0 and +0.0 produce the same string. - */ -PyAPI_FUNC(int) _PyFloat_Pack2(double x, unsigned char *p, int le); -PyAPI_FUNC(int) _PyFloat_Pack4(double x, unsigned char *p, int le); -PyAPI_FUNC(int) _PyFloat_Pack8(double x, unsigned char *p, int le); - -/* The unpack routines read 2, 4 or 8 bytes, starting at p. le is a bool - * argument, true if the string is in little-endian format (exponent - * last, at p+1, p+3 or p+7), false if big-endian (exponent first, at p). - * Return value: The unpacked double. On error, this is -1.0 and - * PyErr_Occurred() is true (and an exception is set, most likely - * OverflowError). Note that on a non-IEEE platform this will refuse - * to unpack a string that represents a NaN or infinity. - */ -PyAPI_FUNC(double) _PyFloat_Unpack2(const unsigned char *p, int le); -PyAPI_FUNC(double) _PyFloat_Unpack4(const unsigned char *p, int le); -PyAPI_FUNC(double) _PyFloat_Unpack8(const unsigned char *p, int le); - PyAPI_FUNC(void) _PyFloat_DebugMallocStats(FILE* out); diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py index 61950289ae1d2..9cf223f892678 100644 --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -12,7 +12,14 @@ from test.test_grammar import (VALID_UNDERSCORE_LITERALS, INVALID_UNDERSCORE_LITERALS) from math import isinf, isnan, copysign, ldexp +import math +try: + import _testcapi +except ImportError: + _testcapi = None + +HAVE_IEEE_754 = float.__getformat__("double").startswith("IEEE") INF = float("inf") NAN = float("nan") @@ -652,8 +659,9 @@ def test_float_specials_do_unpack(self): struct.unpack(fmt, data) @support.requires_IEEE_754 + @unittest.skipIf(_testcapi is None, 'needs _testcapi') def test_serialized_float_rounding(self): - FLT_MAX = import_helper.import_module('_testcapi').FLT_MAX + FLT_MAX = _testcapi.FLT_MAX self.assertEqual(struct.pack("\x00') + self.assertEqual(_testcapi.float_pack(4, 1.5, BIG_ENDIAN), + b'?\xc0\x00\x00') + self.assertEqual(_testcapi.float_pack(8, 1.5, BIG_ENDIAN), + b'?\xf8\x00\x00\x00\x00\x00\x00') + self.assertEqual(_testcapi.float_pack(2, 1.5, LITTLE_ENDIAN), + b'\x00>') + self.assertEqual(_testcapi.float_pack(4, 1.5, LITTLE_ENDIAN), + b'\x00\x00\xc0?') + self.assertEqual(_testcapi.float_pack(8, 1.5, LITTLE_ENDIAN), + b'\x00\x00\x00\x00\x00\x00\xf8?') + + def test_unpack(self): + self.assertEqual(_testcapi.float_unpack(b'>\x00', BIG_ENDIAN), + 1.5) + self.assertEqual(_testcapi.float_unpack(b'?\xc0\x00\x00', BIG_ENDIAN), + 1.5) + self.assertEqual(_testcapi.float_unpack(b'?\xf8\x00\x00\x00\x00\x00\x00', BIG_ENDIAN), + 1.5) + self.assertEqual(_testcapi.float_unpack(b'\x00>', LITTLE_ENDIAN), + 1.5) + self.assertEqual(_testcapi.float_unpack(b'\x00\x00\xc0?', LITTLE_ENDIAN), + 1.5) + self.assertEqual(_testcapi.float_unpack(b'\x00\x00\x00\x00\x00\x00\xf8?', LITTLE_ENDIAN), + 1.5) + + def test_roundtrip(self): + large = 2.0 ** 100 + values = [1.0, 1.5, large, 1.0/7, math.pi] + if HAVE_IEEE_754: + values.extend((INF, NAN)) + for value in values: + for size in (2, 4, 8,): + if size == 2 and value == large: + # too large for 16-bit float + continue + rel_tol = EPSILON[size] + for endian in (BIG_ENDIAN, LITTLE_ENDIAN): + with self.subTest(value=value, size=size, endian=endian): + data = _testcapi.float_pack(size, value, endian) + value2 = _testcapi.float_unpack(data, endian) + if isnan(value): + self.assertTrue(isnan(value2), (value, value2)) + elif size < 8: + self.assertTrue(math.isclose(value2, value, rel_tol=rel_tol), + (value, value2)) + else: + self.assertEqual(value2, value) + + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/C API/2022-03-03-11-12-33.bpo-46906.-olyBI.rst b/Misc/NEWS.d/next/C API/2022-03-03-11-12-33.bpo-46906.-olyBI.rst new file mode 100644 index 0000000000000..9f9cbb5e914ab --- /dev/null +++ b/Misc/NEWS.d/next/C API/2022-03-03-11-12-33.bpo-46906.-olyBI.rst @@ -0,0 +1,4 @@ +Add new functions to pack and unpack C double (serialize and deserialize): +:c:func:`PyFloat_Pack2`, :c:func:`PyFloat_Pack4`, :c:func:`PyFloat_Pack8`, +:c:func:`PyFloat_Unpack2`, :c:func:`PyFloat_Unpack4` and +:c:func:`PyFloat_Unpack8`. Patch by Victor Stinner. diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 2992d34934194..3b769f950a459 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -10,7 +10,6 @@ #include "pycore_bitutils.h" // _Py_bswap32() #include "pycore_call.h" // _PyObject_CallNoArgs() -#include "pycore_floatobject.h" // _PyFloat_Pack8() #include #include "ctypes.h" @@ -1009,10 +1008,10 @@ d_set_sw(void *ptr, PyObject *value, Py_ssize_t size) if (x == -1 && PyErr_Occurred()) return NULL; #ifdef WORDS_BIGENDIAN - if (_PyFloat_Pack8(x, (unsigned char *)ptr, 1)) + if (PyFloat_Pack8(x, ptr, 1)) return NULL; #else - if (_PyFloat_Pack8(x, (unsigned char *)ptr, 0)) + if (PyFloat_Pack8(x, ptr, 0)) return NULL; #endif _RET(value); @@ -1022,9 +1021,9 @@ static PyObject * d_get_sw(void *ptr, Py_ssize_t size) { #ifdef WORDS_BIGENDIAN - return PyFloat_FromDouble(_PyFloat_Unpack8(ptr, 1)); + return PyFloat_FromDouble(PyFloat_Unpack8(ptr, 1)); #else - return PyFloat_FromDouble(_PyFloat_Unpack8(ptr, 0)); + return PyFloat_FromDouble(PyFloat_Unpack8(ptr, 0)); #endif } @@ -1057,10 +1056,10 @@ f_set_sw(void *ptr, PyObject *value, Py_ssize_t size) if (x == -1 && PyErr_Occurred()) return NULL; #ifdef WORDS_BIGENDIAN - if (_PyFloat_Pack4(x, (unsigned char *)ptr, 1)) + if (PyFloat_Pack4(x, ptr, 1)) return NULL; #else - if (_PyFloat_Pack4(x, (unsigned char *)ptr, 0)) + if (PyFloat_Pack4(x, ptr, 0)) return NULL; #endif _RET(value); @@ -1070,9 +1069,9 @@ static PyObject * f_get_sw(void *ptr, Py_ssize_t size) { #ifdef WORDS_BIGENDIAN - return PyFloat_FromDouble(_PyFloat_Unpack4(ptr, 1)); + return PyFloat_FromDouble(PyFloat_Unpack4(ptr, 1)); #else - return PyFloat_FromDouble(_PyFloat_Unpack4(ptr, 0)); + return PyFloat_FromDouble(PyFloat_Unpack4(ptr, 0)); #endif } diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 19e8a71073c97..84f469dee9984 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -9,7 +9,6 @@ #endif #include "Python.h" -#include "pycore_floatobject.h" // _PyFloat_Pack8() #include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_runtime.h" // _Py_ID() #include "pycore_pystate.h" // _PyThreadState_GET() @@ -2244,7 +2243,7 @@ save_float(PicklerObject *self, PyObject *obj) if (self->bin) { char pdata[9]; pdata[0] = BINFLOAT; - if (_PyFloat_Pack8(x, (unsigned char *)&pdata[1], 0) < 0) + if (PyFloat_Pack8(x, &pdata[1], 0) < 0) return -1; if (_Pickler_Write(self, pdata, 9) < 0) return -1; @@ -5395,7 +5394,7 @@ load_binfloat(UnpicklerObject *self) if (_Unpickler_Read(self, &s, 8) < 0) return -1; - x = _PyFloat_Unpack8((unsigned char *)s, 0); + x = PyFloat_Unpack8(s, 0); if (x == -1.0 && PyErr_Occurred()) return -1; diff --git a/Modules/_struct.c b/Modules/_struct.c index a2e14e89d26d4..7cd0ef8d87b36 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -10,7 +10,6 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" -#include "pycore_floatobject.h" // _PyFloat_Unpack2() #include "pycore_moduleobject.h" // _PyModule_GetState() #include "structmember.h" // PyMemberDef #include @@ -303,9 +302,7 @@ static PyObject * unpack_halffloat(const char *p, /* start of 2-byte string */ int le) /* true for little-endian, false for big-endian */ { - double x; - - x = _PyFloat_Unpack2((unsigned char *)p, le); + double x = PyFloat_Unpack2(p, le); if (x == -1.0 && PyErr_Occurred()) { return NULL; } @@ -324,7 +321,7 @@ pack_halffloat(_structmodulestate *state, "required argument is not a float"); return -1; } - return _PyFloat_Pack2(x, (unsigned char *)p, le); + return PyFloat_Pack2(x, p, le); } static PyObject * @@ -333,7 +330,7 @@ unpack_float(const char *p, /* start of 4-byte string */ { double x; - x = _PyFloat_Unpack4((unsigned char *)p, le); + x = PyFloat_Unpack4(p, le); if (x == -1.0 && PyErr_Occurred()) return NULL; return PyFloat_FromDouble(x); @@ -345,7 +342,7 @@ unpack_double(const char *p, /* start of 8-byte string */ { double x; - x = _PyFloat_Unpack8((unsigned char *)p, le); + x = PyFloat_Unpack8(p, le); if (x == -1.0 && PyErr_Occurred()) return NULL; return PyFloat_FromDouble(x); @@ -979,7 +976,7 @@ bp_float(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) "required argument is not a float"); return -1; } - return _PyFloat_Pack4(x, (unsigned char *)p, 0); + return PyFloat_Pack4(x, p, 0); } static int @@ -991,7 +988,7 @@ bp_double(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) "required argument is not a float"); return -1; } - return _PyFloat_Pack8(x, (unsigned char *)p, 0); + return PyFloat_Pack8(x, p, 0); } static int @@ -1194,7 +1191,7 @@ lp_float(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) "required argument is not a float"); return -1; } - return _PyFloat_Pack4(x, (unsigned char *)p, 1); + return PyFloat_Pack4(x, p, 1); } static int @@ -1206,7 +1203,7 @@ lp_double(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) "required argument is not a float"); return -1; } - return _PyFloat_Pack8(x, (unsigned char *)p, 1); + return PyFloat_Pack8(x, p, 1); } static formatdef lilendian_table[] = { diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 6fa0cced4ecfb..019c2b85b6156 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -5775,6 +5775,85 @@ test_tstate_capi(PyObject *self, PyObject *Py_UNUSED(args)) } +// Test PyFloat_Pack2(), PyFloat_Pack4() and PyFloat_Pack8() +static PyObject * +test_float_pack(PyObject *self, PyObject *args) +{ + int size; + double d; + int le; + if (!PyArg_ParseTuple(args, "idi", &size, &d, &le)) { + return NULL; + } + switch (size) + { + case 2: + { + char data[2]; + if (PyFloat_Pack2(d, data, le) < 0) { + return NULL; + } + return PyBytes_FromStringAndSize(data, Py_ARRAY_LENGTH(data)); + } + case 4: + { + char data[4]; + if (PyFloat_Pack4(d, data, le) < 0) { + return NULL; + } + return PyBytes_FromStringAndSize(data, Py_ARRAY_LENGTH(data)); + } + case 8: + { + char data[8]; + if (PyFloat_Pack8(d, data, le) < 0) { + return NULL; + } + return PyBytes_FromStringAndSize(data, Py_ARRAY_LENGTH(data)); + } + default: break; + } + + PyErr_SetString(PyExc_ValueError, "size must 2, 4 or 8"); + return NULL; +} + + +// Test PyFloat_Unpack2(), PyFloat_Unpack4() and PyFloat_Unpack8() +static PyObject * +test_float_unpack(PyObject *self, PyObject *args) +{ + assert(!PyErr_Occurred()); + const char *data; + Py_ssize_t size; + int le; + if (!PyArg_ParseTuple(args, "y#i", &data, &size, &le)) { + return NULL; + } + double d; + switch (size) + { + case 2: + d = PyFloat_Unpack2(data, le); + break; + case 4: + d = PyFloat_Unpack4(data, le); + break; + case 8: + d = PyFloat_Unpack8(data, le); + break; + default: + PyErr_SetString(PyExc_ValueError, "data length must 2, 4 or 8 bytes"); + return NULL; + } + + if (d == -1.0 && PyErr_Occurred()) { + return NULL; + } + return PyFloat_FromDouble(d); +} + + static PyObject *negative_dictoffset(PyObject *, PyObject *); static PyObject *test_buildvalue_issue38913(PyObject *, PyObject *); static PyObject *getargs_s_hash_int(PyObject *, PyObject *, PyObject*); @@ -6061,6 +6140,8 @@ static PyMethodDef TestMethods[] = { PyDoc_STR("fatal_error(message, release_gil=False): call Py_FatalError(message)")}, {"type_get_version", type_get_version, METH_O, PyDoc_STR("type->tp_version_tag")}, {"test_tstate_capi", test_tstate_capi, METH_NOARGS, NULL}, + {"float_pack", test_float_pack, METH_VARARGS, NULL}, + {"float_unpack", test_float_unpack, METH_VARARGS, NULL}, {NULL, NULL} /* sentinel */ }; diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 73104ce8f1787..18991f81480d0 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -9,7 +9,6 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" -#include "pycore_floatobject.h" // _PyFloat_Unpack4() #include "pycore_moduleobject.h" // _PyModule_GetState() #include "structmember.h" // PyMemberDef #include // offsetof() @@ -2056,15 +2055,14 @@ array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype, Py_ssize_t i; int le = (mformat_code == IEEE_754_FLOAT_LE) ? 1 : 0; Py_ssize_t itemcount = Py_SIZE(items) / 4; - const unsigned char *memstr = - (unsigned char *)PyBytes_AS_STRING(items); + const char *memstr = PyBytes_AS_STRING(items); converted_items = PyList_New(itemcount); if (converted_items == NULL) return NULL; for (i = 0; i < itemcount; i++) { PyObject *pyfloat = PyFloat_FromDouble( - _PyFloat_Unpack4(&memstr[i * 4], le)); + PyFloat_Unpack4(&memstr[i * 4], le)); if (pyfloat == NULL) { Py_DECREF(converted_items); return NULL; @@ -2078,15 +2076,14 @@ array__array_reconstructor_impl(PyObject *module, PyTypeObject *arraytype, Py_ssize_t i; int le = (mformat_code == IEEE_754_DOUBLE_LE) ? 1 : 0; Py_ssize_t itemcount = Py_SIZE(items) / 8; - const unsigned char *memstr = - (unsigned char *)PyBytes_AS_STRING(items); + const char *memstr = PyBytes_AS_STRING(items); converted_items = PyList_New(itemcount); if (converted_items == NULL) return NULL; for (i = 0; i < itemcount; i++) { PyObject *pyfloat = PyFloat_FromDouble( - _PyFloat_Unpack8(&memstr[i * 8], le)); + PyFloat_Unpack8(&memstr[i * 8], le)); if (pyfloat == NULL) { Py_DECREF(converted_items); return NULL; diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 91ca848bf26e8..736ddc95d6836 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -2033,7 +2033,7 @@ _PyFloat_DebugMallocStats(FILE *out) /*---------------------------------------------------------------------------- - * _PyFloat_{Pack,Unpack}{2,4,8}. See floatobject.h. + * PyFloat_{Pack,Unpack}{2,4,8}. See floatobject.h. * To match the NPY_HALF_ROUND_TIES_TO_EVEN behavior in: * https://github.com/numpy/numpy/blob/master/numpy/core/src/npymath/halffloat.c * We use: @@ -2044,8 +2044,9 @@ _PyFloat_DebugMallocStats(FILE *out) */ int -_PyFloat_Pack2(double x, unsigned char *p, int le) +PyFloat_Pack2(double x, char *data, int le) { + unsigned char *p = (unsigned char *)data; unsigned char sign; int e; double f; @@ -2148,8 +2149,9 @@ _PyFloat_Pack2(double x, unsigned char *p, int le) } int -_PyFloat_Pack4(double x, unsigned char *p, int le) +PyFloat_Pack4(double x, char *data, int le) { + unsigned char *p = (unsigned char *)data; if (float_format == unknown_format) { unsigned char sign; int e; @@ -2255,8 +2257,9 @@ _PyFloat_Pack4(double x, unsigned char *p, int le) } int -_PyFloat_Pack8(double x, unsigned char *p, int le) +PyFloat_Pack8(double x, char *data, int le) { + unsigned char *p = (unsigned char *)data; if (double_format == unknown_format) { unsigned char sign; int e; @@ -2384,8 +2387,9 @@ _PyFloat_Pack8(double x, unsigned char *p, int le) } double -_PyFloat_Unpack2(const unsigned char *p, int le) +PyFloat_Unpack2(const char *data, int le) { + unsigned char *p = (unsigned char *)data; unsigned char sign; int e; unsigned int f; @@ -2446,8 +2450,9 @@ _PyFloat_Unpack2(const unsigned char *p, int le) } double -_PyFloat_Unpack4(const unsigned char *p, int le) +PyFloat_Unpack4(const char *data, int le) { + unsigned char *p = (unsigned char *)data; if (float_format == unknown_format) { unsigned char sign; int e; @@ -2524,8 +2529,9 @@ _PyFloat_Unpack4(const unsigned char *p, int le) } double -_PyFloat_Unpack8(const unsigned char *p, int le) +PyFloat_Unpack8(const char *data, int le) { + unsigned char *p = (unsigned char *)data; if (double_format == unknown_format) { unsigned char sign; int e; diff --git a/Python/marshal.c b/Python/marshal.c index 44e492925cb25..810244ba8ac78 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -11,7 +11,6 @@ #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_code.h" // _PyCode_New() -#include "pycore_floatobject.h" // _PyFloat_Pack8() #include "pycore_hashtable.h" // _Py_hashtable_t #include "code.h" #include "marshal.h" // Py_MARSHAL_VERSION @@ -271,8 +270,8 @@ w_PyLong(const PyLongObject *ob, char flag, WFILE *p) static void w_float_bin(double v, WFILE *p) { - unsigned char buf[8]; - if (_PyFloat_Pack8(v, buf, 1) < 0) { + char buf[8]; + if (PyFloat_Pack8(v, buf, 1) < 0) { p->error = WFERR_UNMARSHALLABLE; return; } @@ -883,10 +882,10 @@ r_PyLong(RFILE *p) static double r_float_bin(RFILE *p) { - const unsigned char *buf = (const unsigned char *) r_string(8, p); + const char *buf = r_string(8, p); if (buf == NULL) return -1; - return _PyFloat_Unpack8(buf, 1); + return PyFloat_Unpack8(buf, 1); } /* Issue #33720: Disable inlining for reducing the C stack consumption From webhook-mailer at python.org Fri Mar 11 18:37:39 2022 From: webhook-mailer at python.org (vstinner) Date: Fri, 11 Mar 2022 23:37:39 -0000 Subject: [Python-checkins] bpo-46968: Fix faulthandler for Sapphire Rapids Xeon (GH-31789) (GH-31831) Message-ID: https://github.com/python/cpython/commit/ba2b7956fa3932769a5c0aa2575de5c8d7e7ba4b commit: ba2b7956fa3932769a5c0aa2575de5c8d7e7ba4b branch: 3.9 author: Victor Stinner committer: vstinner date: 2022-03-12T00:37:16+01:00 summary: bpo-46968: Fix faulthandler for Sapphire Rapids Xeon (GH-31789) (GH-31831) In Linux kernel 5.14 one can dynamically request size of altstacksize based on hardware capabilities with getauxval(AT_MINSIGSTKSZ). This changes allows for Python extension's request to Linux kernel to use AMX_TILE instruction set on Sapphire Rapids Xeon processor to succeed, unblocking use of the ISA in frameworks. Introduced HAVE_LINUX_AUXVEC_H in configure.ac and pyconfig.h.in Used cpython_autoconf:269 docker container to generate configure. (cherry picked from commit 3b128c054885fe881c3b57a5978de3ea89c81a9c) Co-authored-by: Oleksandr Pavlyk files: A Misc/NEWS.d/next/Library/2022-03-10-14-51-11.bpo-46968.ym2QxL.rst M Modules/faulthandler.c M configure M configure.ac M pyconfig.h.in diff --git a/Misc/NEWS.d/next/Library/2022-03-10-14-51-11.bpo-46968.ym2QxL.rst b/Misc/NEWS.d/next/Library/2022-03-10-14-51-11.bpo-46968.ym2QxL.rst new file mode 100644 index 0000000000000..0da5ae76572ba --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-10-14-51-11.bpo-46968.ym2QxL.rst @@ -0,0 +1,5 @@ +:mod:`faulthandler`: On Linux 5.14 and newer, dynamically determine size of +signal handler stack size CPython allocates using ``getauxval(AT_MINSIGSTKSZ)``. +This changes allows for Python extension's request to Linux kernel to use +AMX_TILE instruction set on Sapphire Rapids Xeon processor to succeed, +unblocking use of the ISA in frameworks. diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index 9855a3e0065ca..764ff439d77d9 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -15,6 +15,17 @@ # include #endif +/* Using an alternative stack requires sigaltstack() + and sigaction() SA_ONSTACK */ +#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) +# define FAULTHANDLER_USE_ALT_STACK +#endif + +#if defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_LINUX_AUXVEC_H) +# include +# include +#endif + /* Allocate at maximum 100 MiB of the stack to raise the stack overflow */ #define STACK_OVERFLOW_MAX_SIZE (100 * 1024 * 1024) @@ -137,12 +148,6 @@ static fault_handler_t faulthandler_handlers[] = { static const size_t faulthandler_nsignals = \ Py_ARRAY_LENGTH(faulthandler_handlers); -/* Using an alternative stack requires sigaltstack() - and sigaction() SA_ONSTACK */ -#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) -# define FAULTHANDLER_USE_ALT_STACK -#endif - #ifdef FAULTHANDLER_USE_ALT_STACK static stack_t stack; static stack_t old_stack; @@ -1395,6 +1400,15 @@ _PyFaulthandler_Init(int enable) signal handler uses more than SIGSTKSZ bytes of stack memory on some platforms. */ stack.ss_size = SIGSTKSZ * 2; +#ifdef AT_MINSIGSTKSZ + /* bpo-46968: Query Linux for minimal stack size to ensure signal delivery + for the hardware running CPython. This OS feature is available in + Linux kernel version >= 5.14 */ + unsigned long at_minstack_size = getauxval(AT_MINSIGSTKSZ); + if (at_minstack_size != 0) { + stack.ss_size = SIGSTKSZ + at_minstack_size; + } +#endif #endif memset(&thread, 0, sizeof(thread)); diff --git a/configure b/configure index 5232ce64b27fd..7f9749091dc01 100755 --- a/configure +++ b/configure @@ -8042,7 +8042,7 @@ sys/stat.h sys/syscall.h sys/sys_domain.h sys/termio.h sys/time.h \ sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \ libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \ linux/tipc.h linux/random.h spawn.h util.h alloca.h endian.h \ -sys/endian.h sys/sysmacros.h linux/memfd.h linux/wait.h sys/memfd.h sys/mman.h +sys/endian.h sys/sysmacros.h linux/auxvec.h linux/memfd.h linux/wait.h sys/memfd.h sys/mman.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" diff --git a/configure.ac b/configure.ac index 754621844b1ed..1354cc0a8dd68 100644 --- a/configure.ac +++ b/configure.ac @@ -2228,7 +2228,7 @@ sys/stat.h sys/syscall.h sys/sys_domain.h sys/termio.h sys/time.h \ sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \ libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \ linux/tipc.h linux/random.h spawn.h util.h alloca.h endian.h \ -sys/endian.h sys/sysmacros.h linux/memfd.h linux/wait.h sys/memfd.h sys/mman.h) +sys/endian.h sys/sysmacros.h linux/auxvec.h linux/memfd.h linux/wait.h sys/memfd.h sys/mman.h) AC_HEADER_DIRENT AC_HEADER_MAJOR diff --git a/pyconfig.h.in b/pyconfig.h.in index b7bfc2541f8ba..ce850fcad8280 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -622,6 +622,9 @@ /* Define to 1 if you have the `linkat' function. */ #undef HAVE_LINKAT +/* Define to 1 if you have the header file. */ +#undef HAVE_LINUX_AUXVEC_H + /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_CAN_BCM_H From webhook-mailer at python.org Fri Mar 11 19:31:59 2022 From: webhook-mailer at python.org (brandtbucher) Date: Sat, 12 Mar 2022 00:31:59 -0000 Subject: [Python-checkins] bpo-46841: Add a _Py_SET_OPCODE macro (GH-31780) Message-ID: https://github.com/python/cpython/commit/a89c29fbcc7e7e85848499443d819c3fab68c78a commit: a89c29fbcc7e7e85848499443d819c3fab68c78a branch: main author: Brandt Bucher committer: brandtbucher date: 2022-03-11T16:31:50-08:00 summary: bpo-46841: Add a _Py_SET_OPCODE macro (GH-31780) files: M Include/cpython/code.h M Python/ceval.c M Python/specialize.c diff --git a/Include/cpython/code.h b/Include/cpython/code.h index f3e0761d95345..ab827c5ae87ff 100644 --- a/Include/cpython/code.h +++ b/Include/cpython/code.h @@ -23,6 +23,9 @@ typedef uint16_t _Py_CODEUNIT; # define _Py_MAKECODEUNIT(opcode, oparg) ((opcode)|((oparg)<<8)) #endif +// Use "unsigned char" instead of "uint8_t" here to avoid illegal aliasing: +#define _Py_SET_OPCODE(word, opcode) (((unsigned char *)&(word))[0] = (opcode)) + /* Bytecode object */ struct PyCodeObject { diff --git a/Python/ceval.c b/Python/ceval.c index 83309e2c5219a..f751479664219 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -5517,7 +5517,7 @@ opname ## _miss: \ _Py_CODEUNIT *counter = (_Py_CODEUNIT *)next_instr; \ *counter -= 1; \ if (*counter == 0) { \ - next_instr[-1] = _Py_MAKECODEUNIT(opname ## _ADAPTIVE, _Py_OPARG(next_instr[-1])); \ + _Py_SET_OPCODE(next_instr[-1], opname ## _ADAPTIVE); \ STAT_INC(opname, deopt); \ *counter = ADAPTIVE_CACHE_BACKOFF; \ } \ diff --git a/Python/specialize.c b/Python/specialize.c index a11a76c4ef118..d84adac352078 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -294,59 +294,55 @@ static void optimize(_Py_CODEUNIT *instructions, int len) { int previous_opcode = -1; - int previous_oparg = -1; for(int i = 0; i < len; i++) { int opcode = _Py_OPCODE(instructions[i]); - int oparg = _Py_OPARG(instructions[i]); uint8_t adaptive_opcode = adaptive_opcodes[opcode]; if (adaptive_opcode) { - instructions[i] = _Py_MAKECODEUNIT(adaptive_opcode, oparg); + _Py_SET_OPCODE(instructions[i], adaptive_opcode); // Make sure the adaptive counter is zero: assert(instructions[i + 1] == 0); previous_opcode = -1; - previous_oparg = -1; i += _PyOpcode_InlineCacheEntries[opcode]; } else { assert(!_PyOpcode_InlineCacheEntries[opcode]); switch (opcode) { case JUMP_ABSOLUTE: - instructions[i] = _Py_MAKECODEUNIT(JUMP_ABSOLUTE_QUICK, oparg); + _Py_SET_OPCODE(instructions[i], JUMP_ABSOLUTE_QUICK); break; case RESUME: - instructions[i] = _Py_MAKECODEUNIT(RESUME_QUICK, oparg); + _Py_SET_OPCODE(instructions[i], RESUME_QUICK); break; case LOAD_FAST: switch(previous_opcode) { case LOAD_FAST: - assert(0 <= previous_oparg); - instructions[i-1] = _Py_MAKECODEUNIT(LOAD_FAST__LOAD_FAST, previous_oparg); + _Py_SET_OPCODE(instructions[i - 1], + LOAD_FAST__LOAD_FAST); break; case STORE_FAST: - assert(0 <= previous_oparg); - instructions[i-1] = _Py_MAKECODEUNIT(STORE_FAST__LOAD_FAST, previous_oparg); + _Py_SET_OPCODE(instructions[i - 1], + STORE_FAST__LOAD_FAST); break; case LOAD_CONST: - assert(0 <= previous_oparg); - instructions[i-1] = _Py_MAKECODEUNIT(LOAD_CONST__LOAD_FAST, previous_oparg); + _Py_SET_OPCODE(instructions[i - 1], + LOAD_CONST__LOAD_FAST); break; } break; case STORE_FAST: if (previous_opcode == STORE_FAST) { - assert(0 <= previous_oparg); - instructions[i-1] = _Py_MAKECODEUNIT(STORE_FAST__STORE_FAST, previous_oparg); + _Py_SET_OPCODE(instructions[i - 1], + STORE_FAST__STORE_FAST); } break; case LOAD_CONST: if (previous_opcode == LOAD_FAST) { - assert(0 <= previous_oparg); - instructions[i-1] = _Py_MAKECODEUNIT(LOAD_FAST__LOAD_CONST, previous_oparg); + _Py_SET_OPCODE(instructions[i - 1], + LOAD_FAST__LOAD_CONST); } break; } previous_opcode = opcode; - previous_oparg = oparg; } } } @@ -573,7 +569,7 @@ specialize_module_load_attr(PyObject *owner, _Py_CODEUNIT *instr, } write_u32(cache->version, keys_version); cache->index = (uint16_t)index; - *instr = _Py_MAKECODEUNIT(opcode_module, _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, opcode_module); return 0; } @@ -684,7 +680,7 @@ specialize_dict_access( } write_u32(cache->version, type->tp_version_tag); cache->index = (uint16_t)index; - *instr = _Py_MAKECODEUNIT(values_op, _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, values_op); } else { if (!PyDict_CheckExact(dict)) { @@ -701,7 +697,7 @@ specialize_dict_access( } cache->index = (uint16_t)hint; write_u32(cache->version, type->tp_version_tag); - *instr = _Py_MAKECODEUNIT(hint_op, _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, hint_op); } return 1; } @@ -755,7 +751,7 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) assert(offset > 0); cache->index = (uint16_t)offset; write_u32(cache->version, type->tp_version_tag); - *instr = _Py_MAKECODEUNIT(LOAD_ATTR_SLOT, _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, LOAD_ATTR_SLOT); goto success; } case DUNDER_CLASS: @@ -764,7 +760,7 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) assert(offset == (uint16_t)offset); cache->index = (uint16_t)offset; write_u32(cache->version, type->tp_version_tag); - *instr = _Py_MAKECODEUNIT(LOAD_ATTR_SLOT, _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, LOAD_ATTR_SLOT); goto success; } case OTHER_SLOT: @@ -845,7 +841,7 @@ _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) assert(offset > 0); cache->index = (uint16_t)offset; write_u32(cache->version, type->tp_version_tag); - *instr = _Py_MAKECODEUNIT(STORE_ATTR_SLOT, _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, STORE_ATTR_SLOT); goto success; } case DUNDER_CLASS: @@ -938,7 +934,7 @@ specialize_class_load_method(PyObject *owner, _Py_CODEUNIT *instr, case NON_DESCRIPTOR: write_u32(cache->type_version, ((PyTypeObject *)owner)->tp_version_tag); write_obj(cache->descr, descr); - *instr = _Py_MAKECODEUNIT(LOAD_METHOD_CLASS, _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, LOAD_METHOD_CLASS); return 0; #ifdef Py_STATS case ABSENT: @@ -1052,19 +1048,19 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) } switch(dictkind) { case NO_DICT: - *instr = _Py_MAKECODEUNIT(LOAD_METHOD_NO_DICT, _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, LOAD_METHOD_NO_DICT); break; case MANAGED_VALUES: - *instr = _Py_MAKECODEUNIT(LOAD_METHOD_WITH_VALUES, _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, LOAD_METHOD_WITH_VALUES); break; case MANAGED_DICT: *(int16_t *)&cache->dict_offset = (int16_t)MANAGED_DICT_OFFSET; - *instr = _Py_MAKECODEUNIT(LOAD_METHOD_WITH_DICT, _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, LOAD_METHOD_WITH_DICT); break; case OFFSET_DICT: assert(owner_cls->tp_dictoffset > 0 && owner_cls->tp_dictoffset <= INT16_MAX); cache->dict_offset = (uint16_t)owner_cls->tp_dictoffset; - *instr = _Py_MAKECODEUNIT(LOAD_METHOD_WITH_DICT, _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, LOAD_METHOD_WITH_DICT); break; } /* `descr` is borrowed. This is safe for methods (even inherited ones from @@ -1130,7 +1126,7 @@ _Py_Specialize_LoadGlobal( } cache->index = (uint16_t)index; write_u32(cache->module_keys_version, keys_version); - *instr = _Py_MAKECODEUNIT(LOAD_GLOBAL_MODULE, _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, LOAD_GLOBAL_MODULE); goto success; } if (!PyDict_CheckExact(builtins)) { @@ -1166,7 +1162,7 @@ _Py_Specialize_LoadGlobal( cache->index = (uint16_t)index; write_u32(cache->module_keys_version, globals_version); cache->builtin_keys_version = (uint16_t)builtins_version; - *instr = _Py_MAKECODEUNIT(LOAD_GLOBAL_BUILTIN, _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, LOAD_GLOBAL_BUILTIN); goto success; fail: STAT_INC(LOAD_GLOBAL, failure); @@ -1245,7 +1241,7 @@ _Py_Specialize_BinarySubscr( PyTypeObject *container_type = Py_TYPE(container); if (container_type == &PyList_Type) { if (PyLong_CheckExact(sub)) { - *instr = _Py_MAKECODEUNIT(BINARY_SUBSCR_LIST_INT, _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, BINARY_SUBSCR_LIST_INT); goto success; } SPECIALIZATION_FAIL(BINARY_SUBSCR, @@ -1254,7 +1250,7 @@ _Py_Specialize_BinarySubscr( } if (container_type == &PyTuple_Type) { if (PyLong_CheckExact(sub)) { - *instr = _Py_MAKECODEUNIT(BINARY_SUBSCR_TUPLE_INT, _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, BINARY_SUBSCR_TUPLE_INT); goto success; } SPECIALIZATION_FAIL(BINARY_SUBSCR, @@ -1262,7 +1258,7 @@ _Py_Specialize_BinarySubscr( goto fail; } if (container_type == &PyDict_Type) { - *instr = _Py_MAKECODEUNIT(BINARY_SUBSCR_DICT, _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, BINARY_SUBSCR_DICT); goto success; } PyTypeObject *cls = Py_TYPE(container); @@ -1292,7 +1288,7 @@ _Py_Specialize_BinarySubscr( } cache->func_version = version; ((PyHeapTypeObject *)container_type)->_spec_cache.getitem = descriptor; - *instr = _Py_MAKECODEUNIT(BINARY_SUBSCR_GETITEM, _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, BINARY_SUBSCR_GETITEM); goto success; } SPECIALIZATION_FAIL(BINARY_SUBSCR, @@ -1319,8 +1315,7 @@ _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *ins if ((Py_SIZE(sub) == 0 || Py_SIZE(sub) == 1) && ((PyLongObject *)sub)->ob_digit[0] < (size_t)PyList_GET_SIZE(container)) { - *instr = _Py_MAKECODEUNIT(STORE_SUBSCR_LIST_INT, - _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, STORE_SUBSCR_LIST_INT); goto success; } else { @@ -1338,7 +1333,7 @@ _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *ins } } if (container_type == &PyDict_Type) { - *instr = _Py_MAKECODEUNIT(STORE_SUBSCR_DICT, _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, STORE_SUBSCR_DICT); goto success; } #ifdef Py_STATS @@ -1427,20 +1422,20 @@ specialize_class_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, if (tp->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) { if (nargs == 1 && kwnames == NULL && oparg == 1) { if (tp == &PyUnicode_Type) { - *instr = _Py_MAKECODEUNIT(PRECALL_NO_KW_STR_1, _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, PRECALL_NO_KW_STR_1); return 0; } else if (tp == &PyType_Type) { - *instr = _Py_MAKECODEUNIT(PRECALL_NO_KW_TYPE_1, _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, PRECALL_NO_KW_TYPE_1); return 0; } else if (tp == &PyTuple_Type) { - *instr = _Py_MAKECODEUNIT(PRECALL_NO_KW_TUPLE_1, _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, PRECALL_NO_KW_TUPLE_1); return 0; } } if (tp->tp_vectorcall != NULL) { - *instr = _Py_MAKECODEUNIT(PRECALL_BUILTIN_CLASS, _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, PRECALL_BUILTIN_CLASS); return 0; } SPECIALIZATION_FAIL(PRECALL, tp == &PyUnicode_Type ? @@ -1493,8 +1488,7 @@ specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr, SPECIALIZATION_FAIL(PRECALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); return -1; } - *instr = _Py_MAKECODEUNIT(PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS, - _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS); return 0; } case METH_O: { @@ -1505,17 +1499,14 @@ specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr, PyInterpreterState *interp = _PyInterpreterState_GET(); PyObject *list_append = interp->callable_cache.list_append; if ((PyObject *)descr == list_append && oparg == 1) { - *instr = _Py_MAKECODEUNIT(PRECALL_NO_KW_LIST_APPEND, - _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, PRECALL_NO_KW_LIST_APPEND); return 0; } - *instr = _Py_MAKECODEUNIT(PRECALL_NO_KW_METHOD_DESCRIPTOR_O, - _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, PRECALL_NO_KW_METHOD_DESCRIPTOR_O); return 0; } case METH_FASTCALL: { - *instr = _Py_MAKECODEUNIT(PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST, - _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST); return 0; } } @@ -1562,10 +1553,10 @@ specialize_py_call(PyFunctionObject *func, _Py_CODEUNIT *instr, int nargs, write_u32(cache->func_version, version); cache->min_args = min_args; if (argcount == nargs) { - *instr = _Py_MAKECODEUNIT(CALL_PY_EXACT_ARGS, _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, CALL_PY_EXACT_ARGS); } else { - *instr = _Py_MAKECODEUNIT(CALL_PY_WITH_DEFAULTS, _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, CALL_PY_WITH_DEFAULTS); } return 0; } @@ -1593,12 +1584,10 @@ specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, /* len(o) */ PyInterpreterState *interp = _PyInterpreterState_GET(); if (callable == interp->callable_cache.len) { - *instr = _Py_MAKECODEUNIT(PRECALL_NO_KW_LEN, - _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, PRECALL_NO_KW_LEN); return 0; } - *instr = _Py_MAKECODEUNIT(PRECALL_NO_KW_BUILTIN_O, - _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, PRECALL_NO_KW_BUILTIN_O); return 0; } case METH_FASTCALL: { @@ -1610,18 +1599,15 @@ specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, /* isinstance(o1, o2) */ PyInterpreterState *interp = _PyInterpreterState_GET(); if (callable == interp->callable_cache.isinstance) { - *instr = _Py_MAKECODEUNIT(PRECALL_NO_KW_ISINSTANCE, - _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, PRECALL_NO_KW_ISINSTANCE); return 0; } } - *instr = _Py_MAKECODEUNIT(PRECALL_NO_KW_BUILTIN_FAST, - _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, PRECALL_NO_KW_BUILTIN_FAST); return 0; } case METH_FASTCALL | METH_KEYWORDS: { - *instr = _Py_MAKECODEUNIT(PRECALL_BUILTIN_FAST_WITH_KEYWORDS, - _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, PRECALL_BUILTIN_FAST_WITH_KEYWORDS); return 0; } default: @@ -1685,7 +1671,7 @@ _Py_Specialize_Precall(PyObject *callable, _Py_CODEUNIT *instr, int nargs, fail = specialize_c_call(callable, instr, nargs, kwnames); } else if (PyFunction_Check(callable)) { - *instr = _Py_MAKECODEUNIT(PRECALL_PYFUNC, _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, PRECALL_PYFUNC); fail = 0; } else if (PyType_Check(callable)) { @@ -1696,7 +1682,7 @@ _Py_Specialize_Precall(PyObject *callable, _Py_CODEUNIT *instr, int nargs, instr, nargs, kwnames, oparg); } else if (Py_TYPE(callable) == &PyMethod_Type) { - *instr = _Py_MAKECODEUNIT(PRECALL_BOUND_METHOD, _Py_OPARG(*instr)); + _Py_SET_OPCODE(*instr, PRECALL_BOUND_METHOD); fail = 0; } else { @@ -1834,19 +1820,18 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, if (PyUnicode_CheckExact(lhs)) { _Py_CODEUNIT next = instr[INLINE_CACHE_ENTRIES_BINARY_OP + 1]; if (_Py_OPCODE(next) == STORE_FAST && Py_REFCNT(lhs) == 2) { - *instr = _Py_MAKECODEUNIT(BINARY_OP_INPLACE_ADD_UNICODE, - oparg); + _Py_SET_OPCODE(*instr, BINARY_OP_INPLACE_ADD_UNICODE); goto success; } - *instr = _Py_MAKECODEUNIT(BINARY_OP_ADD_UNICODE, oparg); + _Py_SET_OPCODE(*instr, BINARY_OP_ADD_UNICODE); goto success; } if (PyLong_CheckExact(lhs)) { - *instr = _Py_MAKECODEUNIT(BINARY_OP_ADD_INT, oparg); + _Py_SET_OPCODE(*instr, BINARY_OP_ADD_INT); goto success; } if (PyFloat_CheckExact(lhs)) { - *instr = _Py_MAKECODEUNIT(BINARY_OP_ADD_FLOAT, oparg); + _Py_SET_OPCODE(*instr, BINARY_OP_ADD_FLOAT); goto success; } break; @@ -1856,11 +1841,11 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, break; } if (PyLong_CheckExact(lhs)) { - *instr = _Py_MAKECODEUNIT(BINARY_OP_MULTIPLY_INT, oparg); + _Py_SET_OPCODE(*instr, BINARY_OP_MULTIPLY_INT); goto success; } if (PyFloat_CheckExact(lhs)) { - *instr = _Py_MAKECODEUNIT(BINARY_OP_MULTIPLY_FLOAT, oparg); + _Py_SET_OPCODE(*instr, BINARY_OP_MULTIPLY_FLOAT); goto success; } break; @@ -1870,11 +1855,11 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, break; } if (PyLong_CheckExact(lhs)) { - *instr = _Py_MAKECODEUNIT(BINARY_OP_SUBTRACT_INT, oparg); + _Py_SET_OPCODE(*instr, BINARY_OP_SUBTRACT_INT); goto success; } if (PyFloat_CheckExact(lhs)) { - *instr = _Py_MAKECODEUNIT(BINARY_OP_SUBTRACT_FLOAT, oparg); + _Py_SET_OPCODE(*instr, BINARY_OP_SUBTRACT_FLOAT); goto success; } break; @@ -1885,7 +1870,7 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, // back to BINARY_OP (unless we're collecting stats, where it's more // important to get accurate hit counts for the unadaptive version // and each of the different failure types): - *instr = _Py_MAKECODEUNIT(BINARY_OP, oparg); + _Py_SET_OPCODE(*instr, BINARY_OP); return; #endif } @@ -1961,7 +1946,7 @@ _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, // counts for the unadaptive version and each of the different failure // types): #ifndef Py_STATS - *instr = _Py_MAKECODEUNIT(COMPARE_OP, oparg); + _Py_SET_OPCODE(*instr, COMPARE_OP); return; #endif if (next_opcode == EXTENDED_ARG) { @@ -1981,13 +1966,13 @@ _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, goto failure; } if (PyFloat_CheckExact(lhs)) { - *instr = _Py_MAKECODEUNIT(COMPARE_OP_FLOAT_JUMP, oparg); + _Py_SET_OPCODE(*instr, COMPARE_OP_FLOAT_JUMP); cache->mask = when_to_jump_mask; goto success; } if (PyLong_CheckExact(lhs)) { if (Py_ABS(Py_SIZE(lhs)) <= 1 && Py_ABS(Py_SIZE(rhs)) <= 1) { - *instr = _Py_MAKECODEUNIT(COMPARE_OP_INT_JUMP, oparg); + _Py_SET_OPCODE(*instr, COMPARE_OP_INT_JUMP); cache->mask = when_to_jump_mask; goto success; } @@ -2002,7 +1987,7 @@ _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, goto failure; } else { - *instr = _Py_MAKECODEUNIT(COMPARE_OP_STR_JUMP, oparg); + _Py_SET_OPCODE(*instr, COMPARE_OP_STR_JUMP); cache->mask = (when_to_jump_mask & 2) == 0; goto success; } @@ -2043,10 +2028,10 @@ _Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr, int oparg) goto failure; } if (PyTuple_GET_SIZE(seq) == 2) { - *instr = _Py_MAKECODEUNIT(UNPACK_SEQUENCE_TWO_TUPLE, oparg); + _Py_SET_OPCODE(*instr, UNPACK_SEQUENCE_TWO_TUPLE); goto success; } - *instr = _Py_MAKECODEUNIT(UNPACK_SEQUENCE_TUPLE, oparg); + _Py_SET_OPCODE(*instr, UNPACK_SEQUENCE_TUPLE); goto success; } if (PyList_CheckExact(seq)) { @@ -2054,7 +2039,7 @@ _Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr, int oparg) SPECIALIZATION_FAIL(UNPACK_SEQUENCE, SPEC_FAIL_EXPECTED_ERROR); goto failure; } - *instr = _Py_MAKECODEUNIT(UNPACK_SEQUENCE_LIST, oparg); + _Py_SET_OPCODE(*instr, UNPACK_SEQUENCE_LIST); goto success; } SPECIALIZATION_FAIL(UNPACK_SEQUENCE, unpack_sequence_fail_kind(seq)); From webhook-mailer at python.org Fri Mar 11 20:04:01 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Sat, 12 Mar 2022 01:04:01 -0000 Subject: [Python-checkins] [3.10] bpo-46677: Add examples of inheritance and attributes to `TypedDict` docs (GH-31349) (GH-31815) Message-ID: https://github.com/python/cpython/commit/28f20a6613b9d9287848bb78369b881a72941a39 commit: 28f20a6613b9d9287848bb78369b881a72941a39 branch: 3.10 author: Charlie Zhao committer: JelleZijlstra date: 2022-03-11T17:03:52-08:00 summary: [3.10] bpo-46677: Add examples of inheritance and attributes to `TypedDict` docs (GH-31349) (GH-31815) Co-authored-by: Jelle Zijlstra (cherry picked from commit 8a207e0321db75f3342692905e342f1d5e1add54) Co-authored-by: Charlie Zhao <68189100+CharlieZhao95 at users.noreply.github.com> files: M Doc/library/typing.rst diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index e7402affdadee..6fa3eeeaf0119 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1388,9 +1388,6 @@ These are not used in annotations. They are building blocks for declaring types. assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first') - The type info for introspection can be accessed via ``Point2D.__annotations__``, - ``Point2D.__total__``, ``Point2D.__required_keys__``, and - ``Point2D.__optional_keys__``. To allow using this feature with older versions of Python that do not support :pep:`526`, ``TypedDict`` supports two additional equivalent syntactic forms:: @@ -1398,6 +1395,18 @@ These are not used in annotations. They are building blocks for declaring types. Point2D = TypedDict('Point2D', x=int, y=int, label=str) Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str}) + The functional syntax should also be used when any of the keys are not valid + :ref:`identifiers`, for example because they are keywords or contain hyphens. + Example:: + + # raises SyntaxError + class Point2D(TypedDict): + in: int # 'in' is a keyword + x-y: int # name with hyphens + + # OK, functional syntax + Point2D = TypedDict('Point2D', {'in': int, 'x-y': int}) + By default, all keys must be present in a ``TypedDict``. It is possible to override this by specifying totality. Usage:: @@ -1411,6 +1420,82 @@ These are not used in annotations. They are building blocks for declaring types. ``True`` as the value of the ``total`` argument. ``True`` is the default, and makes all items defined in the class body required. + It is possible for a ``TypedDict`` type to inherit from one or more other ``TypedDict`` types + using the class-based syntax. + Usage:: + + class Point3D(Point2D): + z: int + + ``Point3D`` has three items: ``x``, ``y`` and ``z``. It is equivalent to this + definition:: + + class Point3D(TypedDict): + x: int + y: int + z: int + + A ``TypedDict`` cannot inherit from a non-TypedDict class, + notably including :class:`Generic`. For example:: + + class X(TypedDict): + x: int + + class Y(TypedDict): + y: int + + class Z(object): pass # A non-TypedDict class + + class XY(X, Y): pass # OK + + class XZ(X, Z): pass # raises TypeError + + T = TypeVar('T') + class XT(X, Generic[T]): pass # raises TypeError + + A ``TypedDict`` can be introspected via annotations dicts + (see :ref:`annotations-howto` for more information on annotations best practices), + :attr:`__total__`, :attr:`__required_keys__`, and :attr:`__optional_keys__`. + + .. attribute:: __total__ + + ``Point2D.__total__`` gives the value of the ``total`` argument. + Example:: + + >>> from typing import TypedDict + >>> class Point2D(TypedDict): pass + >>> Point2D.__total__ + True + >>> class Point2D(TypedDict, total=False): pass + >>> Point2D.__total__ + False + >>> class Point3D(Point2D): pass + >>> Point3D.__total__ + True + + .. attribute:: __required_keys__ + .. attribute:: __optional_keys__ + + ``Point2D.__required_keys__`` and ``Point2D.__optional_keys__`` return + :class:`frozenset` objects containing required and non-required keys, respectively. + Currently the only way to declare both required and non-required keys in the + same ``TypedDict`` is mixed inheritance, declaring a ``TypedDict`` with one value + for the ``total`` argument and then inheriting it from another ``TypedDict`` with + a different value for ``total``. + Usage:: + + >>> class Point2D(TypedDict, total=False): + ... x: int + ... y: int + ... + >>> class Point3D(Point2D): + ... z: int + ... + >>> Point3D.__required_keys__ == frozenset({'z'}) + True + >>> Point3D.__optional_keys__ == frozenset({'x', 'y'}) + True + See :pep:`589` for more examples and detailed rules of using ``TypedDict``. .. versionadded:: 3.8 From webhook-mailer at python.org Fri Mar 11 20:11:11 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Sat, 12 Mar 2022 01:11:11 -0000 Subject: [Python-checkins] [3.9] sqlite3: normalise pre-acronym determiners (GH-31772) (GH-31807) Message-ID: https://github.com/python/cpython/commit/49ff5eddfe8ae082816fb66079fc76369d6f3651 commit: 49ff5eddfe8ae082816fb66079fc76369d6f3651 branch: 3.9 author: Jelle Zijlstra committer: JelleZijlstra date: 2022-03-11T17:10:39-08:00 summary: [3.9] sqlite3: normalise pre-acronym determiners (GH-31772) (GH-31807) For consistency, replace "a SQL" with "an SQL".. (cherry picked from commit 2d5835a019a46573d5b1b614c8ef88d6b564d8d4) Co-authored-by: Erlend Egeberg Aasland files: M Doc/library/sqlite3.rst M Modules/_sqlite/cursor.c diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index c68386ff0cd3f..9e6950652ebc2 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -17,7 +17,7 @@ SQLite for internal data storage. It's also possible to prototype an application using SQLite and then port the code to a larger database such as PostgreSQL or Oracle. -The sqlite3 module was written by Gerhard H?ring. It provides a SQL interface +The sqlite3 module was written by Gerhard H?ring. It provides an SQL interface compliant with the DB-API 2.0 specification described by :pep:`249`. To use the module, start by creating a :class:`Connection` object that @@ -332,7 +332,7 @@ Connection Objects .. class:: Connection - A SQLite database connection has the following attributes and methods: + An SQLite database connection has the following attributes and methods: .. attribute:: isolation_level @@ -534,7 +534,7 @@ Connection Objects .. method:: load_extension(path) - This routine loads a SQLite extension from a shared library. You have to + This routine loads an SQLite extension from a shared library. You have to enable extension loading with :meth:`enable_load_extension` before you can use this routine. @@ -605,7 +605,7 @@ Connection Objects .. method:: backup(target, *, pages=-1, progress=None, name="main", sleep=0.250) - This method makes a backup of a SQLite database even while it's being accessed + This method makes a backup of an SQLite database even while it's being accessed by other clients, or concurrently by the same connection. The copy will be written into the mandatory argument *target*, that must be another :class:`Connection` instance. @@ -965,7 +965,7 @@ This is how SQLite types are converted to Python types by default: +-------------+----------------------------------------------+ The type system of the :mod:`sqlite3` module is extensible in two ways: you can -store additional Python types in a SQLite database via object adaptation, and +store additional Python types in an SQLite database via object adaptation, and you can let the :mod:`sqlite3` module convert SQLite types to different Python types via converters. diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index ad7e702c88c32..e2635e18c738e 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -878,9 +878,9 @@ PyObject* pysqlite_cursor_close(pysqlite_Cursor* self, PyObject* args) static PyMethodDef cursor_methods[] = { {"execute", (PyCFunction)pysqlite_cursor_execute, METH_VARARGS, - PyDoc_STR("Executes a SQL statement.")}, + PyDoc_STR("Executes an SQL statement.")}, {"executemany", (PyCFunction)pysqlite_cursor_executemany, METH_VARARGS, - PyDoc_STR("Repeatedly executes a SQL statement.")}, + PyDoc_STR("Repeatedly executes an SQL statement.")}, {"executescript", (PyCFunction)pysqlite_cursor_executescript, METH_VARARGS, PyDoc_STR("Executes multiple SQL statements at once.")}, {"fetchone", (PyCFunction)pysqlite_cursor_fetchone, METH_NOARGS, From webhook-mailer at python.org Fri Mar 11 20:11:11 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Sat, 12 Mar 2022 01:11:11 -0000 Subject: [Python-checkins] [3.10] sqlite3: normalise pre-acronym determiners (GH-31772) (GH-31806) Message-ID: https://github.com/python/cpython/commit/d8ba5c102c54a5f0944638df4b6cda689faba7fa commit: d8ba5c102c54a5f0944638df4b6cda689faba7fa branch: 3.10 author: Jelle Zijlstra committer: JelleZijlstra date: 2022-03-11T17:10:55-08:00 summary: [3.10] sqlite3: normalise pre-acronym determiners (GH-31772) (GH-31806) For consistency, replace "a SQL" with "an SQL".. (cherry picked from commit 2d5835a019a46573d5b1b614c8ef88d6b564d8d4) Co-authored-by: Erlend Egeberg Aasland files: M Doc/library/sqlite3.rst M Modules/_sqlite/clinic/cursor.c.h M Modules/_sqlite/cursor.c diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 1c5d6ac2b1bc8..e7c191b9f61e9 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -17,7 +17,7 @@ SQLite for internal data storage. It's also possible to prototype an application using SQLite and then port the code to a larger database such as PostgreSQL or Oracle. -The sqlite3 module was written by Gerhard H?ring. It provides a SQL interface +The sqlite3 module was written by Gerhard H?ring. It provides an SQL interface compliant with the DB-API 2.0 specification described by :pep:`249`, and requires SQLite 3.7.15 or newer. @@ -337,7 +337,7 @@ Connection Objects .. class:: Connection - A SQLite database connection has the following attributes and methods: + An SQLite database connection has the following attributes and methods: .. attribute:: isolation_level @@ -544,7 +544,7 @@ Connection Objects .. method:: load_extension(path) - This routine loads a SQLite extension from a shared library. You have to + This routine loads an SQLite extension from a shared library. You have to enable extension loading with :meth:`enable_load_extension` before you can use this routine. @@ -620,7 +620,7 @@ Connection Objects .. method:: backup(target, *, pages=-1, progress=None, name="main", sleep=0.250) - This method makes a backup of a SQLite database even while it's being accessed + This method makes a backup of an SQLite database even while it's being accessed by other clients, or concurrently by the same connection. The copy will be written into the mandatory argument *target*, that must be another :class:`Connection` instance. @@ -975,7 +975,7 @@ This is how SQLite types are converted to Python types by default: +-------------+----------------------------------------------+ The type system of the :mod:`sqlite3` module is extensible in two ways: you can -store additional Python types in a SQLite database via object adaptation, and +store additional Python types in an SQLite database via object adaptation, and you can let the :mod:`sqlite3` module convert SQLite types to different Python types via converters. diff --git a/Modules/_sqlite/clinic/cursor.c.h b/Modules/_sqlite/clinic/cursor.c.h index fc7d92b466947..c6e35a23d656a 100644 --- a/Modules/_sqlite/clinic/cursor.c.h +++ b/Modules/_sqlite/clinic/cursor.c.h @@ -34,7 +34,7 @@ PyDoc_STRVAR(pysqlite_cursor_execute__doc__, "execute($self, sql, parameters=(), /)\n" "--\n" "\n" -"Executes a SQL statement."); +"Executes an SQL statement."); #define PYSQLITE_CURSOR_EXECUTE_METHODDEF \ {"execute", (PyCFunction)(void(*)(void))pysqlite_cursor_execute, METH_FASTCALL, pysqlite_cursor_execute__doc__}, @@ -76,7 +76,7 @@ PyDoc_STRVAR(pysqlite_cursor_executemany__doc__, "executemany($self, sql, seq_of_parameters, /)\n" "--\n" "\n" -"Repeatedly executes a SQL statement."); +"Repeatedly executes an SQL statement."); #define PYSQLITE_CURSOR_EXECUTEMANY_METHODDEF \ {"executemany", (PyCFunction)(void(*)(void))pysqlite_cursor_executemany, METH_FASTCALL, pysqlite_cursor_executemany__doc__}, @@ -259,4 +259,4 @@ pysqlite_cursor_close(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) { return pysqlite_cursor_close_impl(self); } -/*[clinic end generated code: output=98aa7b44c6834d0c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9879e3a5d4ee3847 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 390830f68a9b6..85267cc9e7700 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -650,13 +650,13 @@ _sqlite3.Cursor.execute as pysqlite_cursor_execute parameters: object(c_default = 'NULL') = () / -Executes a SQL statement. +Executes an SQL statement. [clinic start generated code]*/ static PyObject * pysqlite_cursor_execute_impl(pysqlite_Cursor *self, PyObject *sql, PyObject *parameters) -/*[clinic end generated code: output=d81b4655c7c0bbad input=91d7bb36f127f597]*/ +/*[clinic end generated code: output=d81b4655c7c0bbad input=a8e0200a11627f94]*/ { return _pysqlite_query_execute(self, 0, sql, parameters); } @@ -668,13 +668,13 @@ _sqlite3.Cursor.executemany as pysqlite_cursor_executemany seq_of_parameters: object / -Repeatedly executes a SQL statement. +Repeatedly executes an SQL statement. [clinic start generated code]*/ static PyObject * pysqlite_cursor_executemany_impl(pysqlite_Cursor *self, PyObject *sql, PyObject *seq_of_parameters) -/*[clinic end generated code: output=2c65a3c4733fb5d8 input=440707b7af87fba8]*/ +/*[clinic end generated code: output=2c65a3c4733fb5d8 input=0d0a52e5eb7ccd35]*/ { return _pysqlite_query_execute(self, 1, sql, seq_of_parameters); } From webhook-mailer at python.org Fri Mar 11 20:12:26 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Sat, 12 Mar 2022 01:12:26 -0000 Subject: [Python-checkins] bpo-46644: Remove callable() requirement from typing._type_check (GH-31151) Message-ID: https://github.com/python/cpython/commit/870b22b9c442d035190d2b8fb82256cd9a03da48 commit: 870b22b9c442d035190d2b8fb82256cd9a03da48 branch: main author: Gregory Beauregard committer: JelleZijlstra date: 2022-03-11T17:12:17-08:00 summary: bpo-46644: Remove callable() requirement from typing._type_check (GH-31151) We also remove all the tests that check for integer literals. files: A Misc/NEWS.d/next/Library/2022-02-05-22-14-44.bpo-46644.P--1Cz.rst M Lib/test/test_types.py M Lib/test/test_typing.py M Lib/typing.py diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index b8b1ce96f93c3..f8b239117f513 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -875,7 +875,7 @@ def test_union_parameter_substitution_errors(self): T = typing.TypeVar("T") x = int | T with self.assertRaises(TypeError): - x[42] + x[int, str] def test_or_type_operator_with_forward(self): T = typing.TypeVar('T') diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index a6936653bc566..c619042928bbd 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -345,7 +345,7 @@ def test_cannot_instantiate_vars(self): def test_bound_errors(self): with self.assertRaises(TypeError): - TypeVar('X', bound=42) + TypeVar('X', bound=Union) with self.assertRaises(TypeError): TypeVar('X', str, float, bound=Employee) @@ -2591,9 +2591,6 @@ def test_extended_generic_rules_eq(self): class Base: ... class Derived(Base): ... self.assertEqual(Union[T, Base][Union[Base, Derived]], Union[Base, Derived]) - with self.assertRaises(TypeError): - Union[T, int][1] - self.assertEqual(Callable[[T], T][KT], Callable[[KT], KT]) self.assertEqual(Callable[..., List[T]][int], Callable[..., List[int]]) @@ -3136,8 +3133,6 @@ class Foo(obj): class ClassVarTests(BaseTestCase): def test_basics(self): - with self.assertRaises(TypeError): - ClassVar[1] with self.assertRaises(TypeError): ClassVar[int, str] with self.assertRaises(TypeError): @@ -3176,8 +3171,6 @@ class FinalTests(BaseTestCase): def test_basics(self): Final[int] # OK - with self.assertRaises(TypeError): - Final[1] with self.assertRaises(TypeError): Final[int, str] with self.assertRaises(TypeError): @@ -3591,14 +3584,6 @@ def foo(a: 'Node[T'): with self.assertRaises(SyntaxError): get_type_hints(foo) - def test_type_error(self): - - def foo(a: Tuple['42']): - pass - - with self.assertRaises(TypeError): - get_type_hints(foo) - def test_name_error(self): def foo(a: 'Noode[T]'): @@ -5011,8 +4996,6 @@ def test_namedtuple_keyword_usage(self): self.assertEqual(LocalEmployee.__annotations__, dict(name=str, age=int)) with self.assertRaises(TypeError): NamedTuple('Name', [('x', int)], y=str) - with self.assertRaises(TypeError): - NamedTuple('Name', x=1, y='a') def test_namedtuple_special_keyword_names(self): NT = NamedTuple("NT", cls=type, self=object, typename=str, fields=list) @@ -5048,8 +5031,6 @@ def test_namedtuple_errors(self): NamedTuple('Emp', [('_name', str)]) with self.assertRaises(TypeError): NamedTuple(typename='Emp', name=str, id=int) - with self.assertRaises(TypeError): - NamedTuple('Emp', fields=[('name', str), ('id', int)]) def test_copy_and_pickle(self): global Emp # pickle wants to reference the class by name @@ -5124,7 +5105,6 @@ def test_typeddict_create_errors(self): TypedDict() with self.assertRaises(TypeError): TypedDict('Emp', [('name', str)], None) - with self.assertRaises(TypeError): TypedDict(_typename='Emp', name=str, id=int) @@ -5138,13 +5118,6 @@ def test_typeddict_errors(self): isinstance(jim, Emp) with self.assertRaises(TypeError): issubclass(dict, Emp) - # We raise a DeprecationWarning for the keyword syntax - # before the TypeError. - with self.assertWarns(DeprecationWarning): - with self.assertRaises(TypeError): - TypedDict('Hi', x=1) - with self.assertRaises(TypeError): - TypedDict('Hi', [('x', int), ('y', 1)]) with self.assertRaises(TypeError): TypedDict('Hi', [('x', int)], y=int) @@ -5916,6 +5889,9 @@ def test_basics(self): def foo(arg) -> TypeGuard[int]: ... self.assertEqual(gth(foo), {'return': TypeGuard[int]}) + with self.assertRaises(TypeError): + TypeGuard[int, str] + def test_repr(self): self.assertEqual(repr(TypeGuard), 'typing.TypeGuard') cv = TypeGuard[int] diff --git a/Lib/typing.py b/Lib/typing.py index 842554f193ca7..dd68e71db1558 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -185,10 +185,7 @@ def _type_check(arg, msg, is_argument=True, module=None, *, allow_special_forms= return arg if isinstance(arg, _SpecialForm) or arg in (Generic, Protocol): raise TypeError(f"Plain {arg} is not valid as type argument") - if isinstance(arg, (type, TypeVar, ForwardRef, types.UnionType, ParamSpec, - ParamSpecArgs, ParamSpecKwargs, TypeVarTuple)): - return arg - if not callable(arg): + if type(arg) is tuple: raise TypeError(f"{msg} Got {arg!r:.100}.") return arg diff --git a/Misc/NEWS.d/next/Library/2022-02-05-22-14-44.bpo-46644.P--1Cz.rst b/Misc/NEWS.d/next/Library/2022-02-05-22-14-44.bpo-46644.P--1Cz.rst new file mode 100644 index 0000000000000..25a999fac8d37 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-02-05-22-14-44.bpo-46644.P--1Cz.rst @@ -0,0 +1 @@ +No longer require valid typeforms to be callable. This allows :data:`typing.Annotated` to wrap :data:`typing.ParamSpecArgs` and :data:`dataclasses.InitVar`. Patch by Gregory Beauregard. From webhook-mailer at python.org Fri Mar 11 20:14:31 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Sat, 12 Mar 2022 01:14:31 -0000 Subject: [Python-checkins] [3.9] bpo-46677: Add examples of inheritance and attributes to `TypedDict` docs. (GH-31349) (GH-31808) Message-ID: https://github.com/python/cpython/commit/b5140a5811aa35f4b488849fb55d84504732d135 commit: b5140a5811aa35f4b488849fb55d84504732d135 branch: 3.9 author: Charlie Zhao committer: JelleZijlstra date: 2022-03-11T17:14:23-08:00 summary: [3.9] bpo-46677: Add examples of inheritance and attributes to `TypedDict` docs. (GH-31349) (GH-31808) * bpo-46677: Add examples of inheritance and attributes to `TypedDict` docs (GH-31349) Co-authored-by: Jelle Zijlstra (cherry picked from commit 8a207e0321db75f3342692905e342f1d5e1add54) files: M Doc/library/typing.rst diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 9e6ef6a642866..13fc418e9274b 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1056,26 +1056,120 @@ These are not used in annotations. They are building blocks for declaring types. assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first') - The type info for introspection can be accessed via ``Point2D.__annotations__`` - and ``Point2D.__total__``. To allow using this feature with older versions - of Python that do not support :pep:`526`, ``TypedDict`` supports two additional - equivalent syntactic forms:: + To allow using this feature with older versions of Python that do not + support :pep:`526`, ``TypedDict`` supports two additional equivalent + syntactic forms: + + * Using a literal :class:`dict` as the second argument:: - Point2D = TypedDict('Point2D', x=int, y=int, label=str) Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str}) - By default, all keys must be present in a TypedDict. It is possible - to override this by specifying totality. + * Using keyword arguments:: + + Point2D = TypedDict('Point2D', x=int, y=int, label=str) + + The functional syntax should also be used when any of the keys are not valid + :ref:`identifiers`, for example because they are keywords or contain hyphens. + Example:: + + # raises SyntaxError + class Point2D(TypedDict): + in: int # 'in' is a keyword + x-y: int # name with hyphens + + # OK, functional syntax + Point2D = TypedDict('Point2D', {'in': int, 'x-y': int}) + + By default, all keys must be present in a ``TypedDict``. It is possible to + override this by specifying totality. Usage:: - class point2D(TypedDict, total=False): + class Point2D(TypedDict, total=False): x: int y: int - This means that a point2D TypedDict can have any of the keys omitted. A type - checker is only expected to support a literal False or True as the value of - the total argument. True is the default, and makes all items defined in the - class body be required. + # Alternative syntax + Point2D = TypedDict('Point2D', {'x': int, 'y': int}, total=False) + + This means that a ``Point2D`` ``TypedDict`` can have any of the keys + omitted. A type checker is only expected to support a literal ``False`` or + ``True`` as the value of the ``total`` argument. ``True`` is the default, + and makes all items defined in the class body required. + + It is possible for a ``TypedDict`` type to inherit from one or more other ``TypedDict`` types + using the class-based syntax. + Usage:: + + class Point3D(Point2D): + z: int + + ``Point3D`` has three items: ``x``, ``y`` and ``z``. It is equivalent to this + definition:: + + class Point3D(TypedDict): + x: int + y: int + z: int + + A ``TypedDict`` cannot inherit from a non-TypedDict class, + notably including :class:`Generic`. For example:: + + class X(TypedDict): + x: int + + class Y(TypedDict): + y: int + + class Z(object): pass # A non-TypedDict class + + class XY(X, Y): pass # OK + + class XZ(X, Z): pass # raises TypeError + + T = TypeVar('T') + class XT(X, Generic[T]): pass # raises TypeError + + A ``TypedDict`` can be introspected via :attr:`__annotations__`, + :attr:`__total__`, :attr:`__required_keys__`, and :attr:`__optional_keys__`. + + .. attribute:: __total__ + + ``Point2D.__total__`` gives the value of the ``total`` argument. + Example:: + + >>> from typing import TypedDict + >>> class Point2D(TypedDict): pass + >>> Point2D.__total__ + True + >>> class Point2D(TypedDict, total=False): pass + >>> Point2D.__total__ + False + >>> class Point3D(Point2D): pass + >>> Point3D.__total__ + True + + .. attribute:: __required_keys__ + .. attribute:: __optional_keys__ + + ``Point2D.__required_keys__`` and ``Point2D.__optional_keys__`` return + :class:`frozenset` objects containing required and non-required keys, respectively. + Currently the only way to declare both required and non-required keys in the + same ``TypedDict`` is mixed inheritance, declaring a ``TypedDict`` with one value + for the ``total`` argument and then inheriting it from another ``TypedDict`` with + a different value for ``total``. + Usage:: + + >>> class Point2D(TypedDict, total=False): + ... x: int + ... y: int + ... + >>> class Point3D(Point2D): + ... z: int + ... + >>> Point3D.__required_keys__ == frozenset({'z'}) + True + >>> Point3D.__optional_keys__ == frozenset({'x', 'y'}) + True See :pep:`589` for more examples and detailed rules of using ``TypedDict``. From webhook-mailer at python.org Fri Mar 11 21:17:54 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Sat, 12 Mar 2022 02:17:54 -0000 Subject: [Python-checkins] bpo-46644: Fix test_typing test broken by GH-31151 due to a merge race (GH-31833) Message-ID: https://github.com/python/cpython/commit/75174371e6cac935b598a68c1113f6db1e0d6ed8 commit: 75174371e6cac935b598a68c1113f6db1e0d6ed8 branch: main author: Jelle Zijlstra committer: JelleZijlstra date: 2022-03-11T18:17:45-08:00 summary: bpo-46644: Fix test_typing test broken by GH-31151 due to a merge race (GH-31833) files: M Lib/test/test_typing.py diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index c619042928bbd..b212b52304880 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -377,7 +377,7 @@ def test_bad_var_substitution(self): T = TypeVar('T') P = ParamSpec("P") bad_args = ( - 42, ..., [int], (), (int, str), Union, + (), (int, str), Union, Generic, Generic[T], Protocol, Protocol[T], Final, Final[int], ClassVar, ClassVar[int], ) From webhook-mailer at python.org Sat Mar 12 07:20:17 2022 From: webhook-mailer at python.org (Fidget-Spinner) Date: Sat, 12 Mar 2022 12:20:17 -0000 Subject: [Python-checkins] bpo-43224: Implement PEP 646 changes to genericaliasobject.c (GH-31019) Message-ID: https://github.com/python/cpython/commit/af2277e461aee4eb96affd06b4af25aad31c81ea commit: af2277e461aee4eb96affd06b4af25aad31c81ea branch: main author: Matthew Rahtz committer: Fidget-Spinner date: 2022-03-12T20:20:12+08:00 summary: bpo-43224: Implement PEP 646 changes to genericaliasobject.c (GH-31019) Specifically, prepare for starring of tuples via a new genericalias iter type. GenericAlias also partially supports the iterator protocol after this change. Co-authored-by: Jelle Zijlstra Co-authored-by: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> Co-authored-by: Ken Jin <28750310+Fidget-Spinner at users.noreply.github.com> files: A Misc/NEWS.d/next/Library/2022-01-30-20-32-40.bpo-43224.zqrQsj.rst M Lib/test/test_genericalias.py M Objects/genericaliasobject.c diff --git a/Lib/test/test_genericalias.py b/Lib/test/test_genericalias.py index 1407657c9bb20..39c56f2290bd3 100644 --- a/Lib/test/test_genericalias.py +++ b/Lib/test/test_genericalias.py @@ -169,6 +169,24 @@ class MyList(list): self.assertEqual(repr(list[str]), 'list[str]') self.assertEqual(repr(list[()]), 'list[()]') self.assertEqual(repr(tuple[int, ...]), 'tuple[int, ...]') + x1 = tuple[ + tuple( # Effectively the same as starring; TODO + tuple[int] + ) + ] + self.assertEqual(repr(x1), 'tuple[*tuple[int]]') + x2 = tuple[ + tuple( # Ditto TODO + tuple[int, str] + ) + ] + self.assertEqual(repr(x2), 'tuple[*tuple[int, str]]') + x3 = tuple[ + tuple( # Ditto TODO + tuple[int, ...] + ) + ] + self.assertEqual(repr(x3), 'tuple[*tuple[int, ...]]') self.assertTrue(repr(MyList[int]).endswith('.BaseTest.test_repr..MyList[int]')) self.assertEqual(repr(list[str]()), '[]') # instances should keep their normal repr @@ -182,6 +200,7 @@ def test_exposed_type(self): def test_parameters(self): from typing import List, Dict, Callable + D0 = dict[str, int] self.assertEqual(D0.__args__, (str, int)) self.assertEqual(D0.__parameters__, ()) @@ -197,6 +216,7 @@ def test_parameters(self): D2b = dict[T, T] self.assertEqual(D2b.__args__, (T, T)) self.assertEqual(D2b.__parameters__, (T,)) + L0 = list[str] self.assertEqual(L0.__args__, (str,)) self.assertEqual(L0.__parameters__, ()) @@ -219,6 +239,45 @@ def test_parameters(self): self.assertEqual(L5.__args__, (Callable[[K, V], K],)) self.assertEqual(L5.__parameters__, (K, V)) + T1 = tuple[ + tuple( # Ditto TODO + tuple[int] + ) + ] + self.assertEqual( + T1.__args__, + tuple( # Ditto TODO + tuple[int] + ) + ) + self.assertEqual(T1.__parameters__, ()) + + T2 = tuple[ + tuple( # Ditto TODO + tuple[T] + ) + ] + self.assertEqual( + T2.__args__, + tuple( # Ditto TODO + tuple[T] + ) + ) + self.assertEqual(T2.__parameters__, (T,)) + + T4 = tuple[ + tuple( # Ditto TODO + tuple[int, str] + ) + ] + self.assertEqual( + T4.__args__, + tuple( # Ditto TODO + tuple[int, str] + ) + ) + self.assertEqual(T4.__parameters__, ()) + def test_parameter_chaining(self): from typing import List, Dict, Union, Callable self.assertEqual(list[T][int], list[int]) @@ -249,6 +308,19 @@ def test_parameter_chaining(self): def test_equality(self): self.assertEqual(list[int], list[int]) self.assertEqual(dict[str, int], dict[str, int]) + self.assertEqual((*tuple[int],)[0], (*tuple[int],)[0]) + self.assertEqual( + tuple[ + tuple( # Effectively the same as starring; TODO + tuple[int] + ) + ], + tuple[ + tuple( # Ditto TODO + tuple[int] + ) + ] + ) self.assertNotEqual(dict[str, int], dict[str, str]) self.assertNotEqual(list, list[int]) self.assertNotEqual(list[int], list) @@ -346,6 +418,24 @@ def __new__(cls, *args, **kwargs): with self.assertRaises(TypeError): Bad(list, int, bad=int) + def test_iter_creates_starred_tuple(self): + t = tuple[int, str] + iter_t = iter(t) + x = next(iter_t) + self.assertEqual(repr(x), '*tuple[int, str]') + + def test_calling_next_twice_raises_stopiteration(self): + t = tuple[int, str] + iter_t = iter(t) + next(iter_t) + with self.assertRaises(StopIteration): + next(iter_t) + + def test_del_iter(self): + t = tuple[int, str] + iter_x = iter(t) + del iter_x + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2022-01-30-20-32-40.bpo-43224.zqrQsj.rst b/Misc/NEWS.d/next/Library/2022-01-30-20-32-40.bpo-43224.zqrQsj.rst new file mode 100644 index 0000000000000..55e9412671058 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-01-30-20-32-40.bpo-43224.zqrQsj.rst @@ -0,0 +1 @@ +Allow unpacking types.GenericAlias objects, e.g. ``*tuple[int, str]``. diff --git a/Objects/genericaliasobject.c b/Objects/genericaliasobject.c index 45caf2e2ee7db..224a2e9acb748 100644 --- a/Objects/genericaliasobject.c +++ b/Objects/genericaliasobject.c @@ -5,14 +5,23 @@ #include "pycore_unionobject.h" // _Py_union_type_or, _PyGenericAlias_Check #include "structmember.h" // PyMemberDef +#include + typedef struct { PyObject_HEAD PyObject *origin; PyObject *args; PyObject *parameters; PyObject* weakreflist; + // Whether we're a starred type, e.g. *tuple[int]. + bool starred; } gaobject; +typedef struct { + PyObject_HEAD + PyObject *obj; /* Set to NULL when iterator is exhausted */ +} gaiterobject; + static void ga_dealloc(PyObject *self) { @@ -120,6 +129,11 @@ ga_repr(PyObject *self) _PyUnicodeWriter writer; _PyUnicodeWriter_Init(&writer); + if (alias->starred) { + if (_PyUnicodeWriter_WriteASCIIString(&writer, "*", 1) < 0) { + goto error; + } + } if (ga_repr_item(&writer, alias->origin) < 0) { goto error; } @@ -603,6 +617,66 @@ static PyNumberMethods ga_as_number = { .nb_or = _Py_union_type_or, // Add __or__ function }; +static PyObject * +ga_iternext(gaiterobject *gi) { + if (gi->obj == NULL) { + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + gaobject *alias = (gaobject *)gi->obj; + PyObject *starred_alias = Py_GenericAlias(alias->origin, alias->args); + if (starred_alias == NULL) { + return NULL; + } + ((gaobject *)starred_alias)->starred = true; + Py_SETREF(gi->obj, NULL); + return starred_alias; +} + +static void +ga_iter_dealloc(gaiterobject *gi) { + PyObject_GC_UnTrack(gi); + Py_XDECREF(gi->obj); + PyObject_GC_Del(gi); +} + +static int +ga_iter_traverse(gaiterobject *gi, visitproc visit, void *arg) +{ + Py_VISIT(gi->obj); + return 0; +} + +static int +ga_iter_clear(PyObject *self) { + gaiterobject *gi = (gaiterobject *)self; + Py_CLEAR(gi->obj); + return 0; +} + +static PyTypeObject Py_GenericAliasIterType = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + .tp_name = "generic_alias_iterator", + .tp_basicsize = sizeof(gaiterobject), + .tp_iter = PyObject_SelfIter, + .tp_iternext = (iternextfunc)ga_iternext, + .tp_traverse = (traverseproc)ga_iter_traverse, + .tp_dealloc = (destructor)ga_iter_dealloc, + .tp_clear = (inquiry)ga_iter_clear, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, +}; + +static PyObject * +ga_iter(PyObject *self) { + gaiterobject *gi = PyObject_GC_New(gaiterobject, &Py_GenericAliasIterType); + if (gi == NULL) { + return NULL; + } + gi->obj = Py_NewRef(self); + PyObject_GC_Track(gi); + return (PyObject *)gi; +} + // TODO: // - argument clinic? // - __doc__? @@ -631,6 +705,7 @@ PyTypeObject Py_GenericAliasType = { .tp_new = ga_new, .tp_free = PyObject_GC_Del, .tp_getset = ga_properties, + .tp_iter = (getiterfunc)ga_iter, }; PyObject * From webhook-mailer at python.org Sat Mar 12 12:26:28 2022 From: webhook-mailer at python.org (asvetlov) Date: Sat, 12 Mar 2022 17:26:28 -0000 Subject: [Python-checkins] bpo-37529: Add test for guessing extensions (GH-28243) Message-ID: https://github.com/python/cpython/commit/d9db07a3100105768ba83ffd67991e78452bb22e commit: d9db07a3100105768ba83ffd67991e78452bb22e branch: main author: andrei kulakov committer: asvetlov date: 2022-03-12T19:26:17+02:00 summary: bpo-37529: Add test for guessing extensions (GH-28243) Co-authored-by: Andrew Svetlov files: M Lib/test/test_mimetypes.py diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 4098a22644092..392ddd2d5eee9 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -159,6 +159,15 @@ def test_init_reinitializes(self): # Poison should be gone. self.assertEqual(mimetypes.guess_extension('foo/bar'), None) + @unittest.skipIf(sys.platform.startswith("win"), "Non-Windows only") + def test_guess_known_extensions(self): + # Issue 37529 + # The test fails on Windows because Windows adds mime types from the Registry + # and that creates some duplicates. + from mimetypes import types_map + for v in types_map.values(): + self.assertIsNotNone(mimetypes.guess_extension(v)) + def test_preferred_extension(self): def check_extensions(): self.assertEqual(mimetypes.guess_extension('application/octet-stream'), '.bin') From webhook-mailer at python.org Sat Mar 12 18:55:09 2022 From: webhook-mailer at python.org (asvetlov) Date: Sat, 12 Mar 2022 23:55:09 -0000 Subject: [Python-checkins] bpo-43215: Document Happy Eyeballs args of asyncio.open_connection (GH-24525) Message-ID: https://github.com/python/cpython/commit/3543ddb4c4ebc26fb2d6c67a97e66f5267876f72 commit: 3543ddb4c4ebc26fb2d6c67a97e66f5267876f72 branch: main author: Illia Volochii committer: asvetlov date: 2022-03-13T01:54:59+02:00 summary: bpo-43215: Document Happy Eyeballs args of asyncio.open_connection (GH-24525) Co-authored-by: Andrew Svetlov files: M Doc/library/asyncio-stream.rst diff --git a/Doc/library/asyncio-stream.rst b/Doc/library/asyncio-stream.rst index cf4a645f5f94e..ba534f9903fb4 100644 --- a/Doc/library/asyncio-stream.rst +++ b/Doc/library/asyncio-stream.rst @@ -51,7 +51,8 @@ and work with streams: .. coroutinefunction:: open_connection(host=None, port=None, *, \ limit=None, ssl=None, family=0, proto=0, \ flags=0, sock=None, local_addr=None, \ - server_hostname=None, ssl_handshake_timeout=None) + server_hostname=None, ssl_handshake_timeout=None, \ + happy_eyeballs_delay=None, interleave=None) Establish a network connection and return a pair of ``(reader, writer)`` objects. @@ -69,6 +70,9 @@ and work with streams: .. versionchanged:: 3.7 Added the *ssl_handshake_timeout* parameter. + .. versionadded:: 3.8 + Added *happy_eyeballs_delay* and *interleave* parameters. + .. versionchanged:: 3.10 Removed the *loop* parameter. From webhook-mailer at python.org Sun Mar 13 12:34:58 2022 From: webhook-mailer at python.org (asvetlov) Date: Sun, 13 Mar 2022 16:34:58 -0000 Subject: [Python-checkins] bpo-46995: Deprecate missing asyncio.Task.set_name() for third-party task implementations (GH-31838) Message-ID: https://github.com/python/cpython/commit/7e473e94a52024ac821dd2f206290423e4987ead commit: 7e473e94a52024ac821dd2f206290423e4987ead branch: main author: Andrew Svetlov committer: asvetlov date: 2022-03-13T18:34:46+02:00 summary: bpo-46995: Deprecate missing asyncio.Task.set_name() for third-party task implementations (GH-31838) Co-authored-by: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> files: A Misc/NEWS.d/next/Library/2022-03-12-13-50-42.bpo-46995.2kdNDg.rst M Lib/asyncio/tasks.py M Lib/test/test_asyncio/test_tasks.py diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index 059143fb9086f..e604298e5efc0 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -67,7 +67,10 @@ def _set_task_name(task, name): try: set_name = task.set_name except AttributeError: - pass + warnings.warn("Task.set_name() was added in Python 3.8, " + "the method support will be mandatory for third-party " + "task implementations since 3.13.", + DeprecationWarning, stacklevel=3) else: set_name(name) diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 950879204e703..95fabf728818b 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -12,7 +12,6 @@ import textwrap import traceback import unittest -import weakref from unittest import mock from types import GenericAlias diff --git a/Misc/NEWS.d/next/Library/2022-03-12-13-50-42.bpo-46995.2kdNDg.rst b/Misc/NEWS.d/next/Library/2022-03-12-13-50-42.bpo-46995.2kdNDg.rst new file mode 100644 index 0000000000000..021923f5889a7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-12-13-50-42.bpo-46995.2kdNDg.rst @@ -0,0 +1,2 @@ +Deprecate missing :meth:`asyncio.Task.set_name` for third-party task +implementations, schedule making it mandatory in Python 3.13. From webhook-mailer at python.org Sun Mar 13 12:42:41 2022 From: webhook-mailer at python.org (asvetlov) Date: Sun, 13 Mar 2022 16:42:41 -0000 Subject: [Python-checkins] bpo-46805: Add low level UDP socket functions to asyncio (GH-31455) Message-ID: https://github.com/python/cpython/commit/9f04ee569cebb8b4c6f04bea95d91a19c5403806 commit: 9f04ee569cebb8b4c6f04bea95d91a19c5403806 branch: main author: Alex Gr?nholm committer: asvetlov date: 2022-03-13T18:42:29+02:00 summary: bpo-46805: Add low level UDP socket functions to asyncio (GH-31455) files: A Misc/NEWS.d/next/Library/2022-02-20-23-03-32.bpo-46805.HZ8xWG.rst M Doc/library/asyncio-eventloop.rst M Doc/library/asyncio-llapi-index.rst M Doc/whatsnew/3.11.rst M Lib/asyncio/events.py M Lib/asyncio/proactor_events.py M Lib/asyncio/selector_events.py M Lib/asyncio/windows_events.py M Lib/test/test_asyncio/test_sock_lowlevel.py M Lib/test/test_asyncio/utils.py M Modules/clinic/overlapped.c.h M Modules/overlapped.c diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index 1b762a75aed0a..4776853b5a56d 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -922,6 +922,29 @@ convenient. .. versionadded:: 3.7 +.. coroutinemethod:: loop.sock_recvfrom(sock, bufsize) + + Receive a datagram of up to *bufsize* from *sock*. Asynchronous version of + :meth:`socket.recvfrom() `. + + Return a tuple of (received data, remote address). + + *sock* must be a non-blocking socket. + + .. versionadded:: 3.11 + +.. coroutinemethod:: loop.sock_recvfrom_into(sock, buf, nbytes=0) + + Receive a datagram of up to *nbytes* from *sock* into *buf*. + Asynchronous version of + :meth:`socket.recvfrom_into() `. + + Return a tuple of (number of bytes received, remote address). + + *sock* must be a non-blocking socket. + + .. versionadded:: 3.11 + .. coroutinemethod:: loop.sock_sendall(sock, data) Send *data* to the *sock* socket. Asynchronous version of @@ -940,6 +963,18 @@ convenient. method, before Python 3.7 it returned a :class:`Future`. Since Python 3.7, this is an ``async def`` method. +.. coroutinemethod:: loop.sock_sendto(sock, data, address) + + Send a datagram from *sock* to *address*. + Asynchronous version of + :meth:`socket.sendto() `. + + Return the number of bytes sent. + + *sock* must be a non-blocking socket. + + .. versionadded:: 3.11 + .. coroutinemethod:: loop.sock_connect(sock, address) Connect *sock* to a remote socket at *address*. diff --git a/Doc/library/asyncio-llapi-index.rst b/Doc/library/asyncio-llapi-index.rst index 0ab322af6dc72..69b550e43f5aa 100644 --- a/Doc/library/asyncio-llapi-index.rst +++ b/Doc/library/asyncio-llapi-index.rst @@ -189,9 +189,18 @@ See also the main documentation section about the * - ``await`` :meth:`loop.sock_recv_into` - Receive data from the :class:`~socket.socket` into a buffer. + * - ``await`` :meth:`loop.sock_recvfrom` + - Receive a datagram from the :class:`~socket.socket`. + + * - ``await`` :meth:`loop.sock_recvfrom_into` + - Receive a datagram from the :class:`~socket.socket` into a buffer. + * - ``await`` :meth:`loop.sock_sendall` - Send data to the :class:`~socket.socket`. + * - ``await`` :meth:`loop.sock_sendto` + - Send a datagram via the :class:`~socket.socket` to the given address. + * - ``await`` :meth:`loop.sock_connect` - Connect the :class:`~socket.socket`. diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 8ab6854663030..9fbf46791c27d 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -226,6 +226,15 @@ New Modules Improved Modules ================ +asyncio +------- + +* Add raw datagram socket functions to the event loop: + :meth:`~asyncio.AbstractEventLoop.sock_sendto`, + :meth:`~asyncio.AbstractEventLoop.sock_recvfrom` and + :meth:`~asyncio.AbstractEventLoop.sock_recvfrom_into`. + (Contributed by Alex Gr?nholm in :issue:`46805`.) + fractions --------- diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py index 1d305e3ddff1c..e682a192a887f 100644 --- a/Lib/asyncio/events.py +++ b/Lib/asyncio/events.py @@ -546,9 +546,18 @@ async def sock_recv(self, sock, nbytes): async def sock_recv_into(self, sock, buf): raise NotImplementedError + async def sock_recvfrom(self, sock, bufsize): + raise NotImplementedError + + async def sock_recvfrom_into(self, sock, buf, nbytes=0): + raise NotImplementedError + async def sock_sendall(self, sock, data): raise NotImplementedError + async def sock_sendto(self, sock, data, address): + raise NotImplementedError + async def sock_connect(self, sock, address): raise NotImplementedError diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index 43d5e70b79cac..087f0950d118b 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -700,9 +700,21 @@ async def sock_recv(self, sock, n): async def sock_recv_into(self, sock, buf): return await self._proactor.recv_into(sock, buf) + async def sock_recvfrom(self, sock, bufsize): + return await self._proactor.recvfrom(sock, bufsize) + + async def sock_recvfrom_into(self, sock, buf, nbytes=0): + if not nbytes: + nbytes = len(buf) + + return await self._proactor.recvfrom_into(sock, buf, nbytes) + async def sock_sendall(self, sock, data): return await self._proactor.send(sock, data) + async def sock_sendto(self, sock, data, address): + return await self._proactor.sendto(sock, data, 0, address) + async def sock_connect(self, sock, address): return await self._proactor.connect(sock, address) diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index c3c2ec12a7787..bfd8019da606e 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -434,6 +434,88 @@ def _sock_recv_into(self, fut, sock, buf): else: fut.set_result(nbytes) + async def sock_recvfrom(self, sock, bufsize): + """Receive a datagram from a datagram socket. + + The return value is a tuple of (bytes, address) representing the + datagram received and the address it came from. + The maximum amount of data to be received at once is specified by + nbytes. + """ + base_events._check_ssl_socket(sock) + if self._debug and sock.gettimeout() != 0: + raise ValueError("the socket must be non-blocking") + try: + return sock.recvfrom(bufsize) + except (BlockingIOError, InterruptedError): + pass + fut = self.create_future() + fd = sock.fileno() + self._ensure_fd_no_transport(fd) + handle = self._add_reader(fd, self._sock_recvfrom, fut, sock, bufsize) + fut.add_done_callback( + functools.partial(self._sock_read_done, fd, handle=handle)) + return await fut + + def _sock_recvfrom(self, fut, sock, bufsize): + # _sock_recvfrom() can add itself as an I/O callback if the operation + # can't be done immediately. Don't use it directly, call + # sock_recvfrom(). + if fut.done(): + return + try: + result = sock.recvfrom(bufsize) + except (BlockingIOError, InterruptedError): + return # try again next time + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: + fut.set_exception(exc) + else: + fut.set_result(result) + + async def sock_recvfrom_into(self, sock, buf, nbytes=0): + """Receive data from the socket. + + The received data is written into *buf* (a writable buffer). + The return value is a tuple of (number of bytes written, address). + """ + base_events._check_ssl_socket(sock) + if self._debug and sock.gettimeout() != 0: + raise ValueError("the socket must be non-blocking") + if not nbytes: + nbytes = len(buf) + + try: + return sock.recvfrom_into(buf, nbytes) + except (BlockingIOError, InterruptedError): + pass + fut = self.create_future() + fd = sock.fileno() + self._ensure_fd_no_transport(fd) + handle = self._add_reader(fd, self._sock_recvfrom_into, fut, sock, buf, + nbytes) + fut.add_done_callback( + functools.partial(self._sock_read_done, fd, handle=handle)) + return await fut + + def _sock_recvfrom_into(self, fut, sock, buf, bufsize): + # _sock_recv_into() can add itself as an I/O callback if the operation + # can't be done immediately. Don't use it directly, call + # sock_recv_into(). + if fut.done(): + return + try: + result = sock.recvfrom_into(buf, bufsize) + except (BlockingIOError, InterruptedError): + return # try again next time + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: + fut.set_exception(exc) + else: + fut.set_result(result) + async def sock_sendall(self, sock, data): """Send data to the socket. @@ -487,6 +569,48 @@ def _sock_sendall(self, fut, sock, view, pos): else: pos[0] = start + async def sock_sendto(self, sock, data, address): + """Send data to the socket. + + The socket must be connected to a remote socket. This method continues + to send data from data until either all data has been sent or an + error occurs. None is returned on success. On error, an exception is + raised, and there is no way to determine how much data, if any, was + successfully processed by the receiving end of the connection. + """ + base_events._check_ssl_socket(sock) + if self._debug and sock.gettimeout() != 0: + raise ValueError("the socket must be non-blocking") + try: + return sock.sendto(data, address) + except (BlockingIOError, InterruptedError): + pass + + fut = self.create_future() + fd = sock.fileno() + self._ensure_fd_no_transport(fd) + # use a trick with a list in closure to store a mutable state + handle = self._add_writer(fd, self._sock_sendto, fut, sock, data, + address) + fut.add_done_callback( + functools.partial(self._sock_write_done, fd, handle=handle)) + return await fut + + def _sock_sendto(self, fut, sock, data, address): + if fut.done(): + # Future cancellation can be scheduled on previous loop iteration + return + try: + n = sock.sendto(data, 0, address) + except (BlockingIOError, InterruptedError): + return + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: + fut.set_exception(exc) + else: + fut.set_result(n) + async def sock_connect(self, sock, address): """Connect to a remote socket at address. diff --git a/Lib/asyncio/windows_events.py b/Lib/asyncio/windows_events.py index 0d9a07ef4772e..90b259cbafead 100644 --- a/Lib/asyncio/windows_events.py +++ b/Lib/asyncio/windows_events.py @@ -512,6 +512,26 @@ def finish_recv(trans, key, ov): return self._register(ov, conn, finish_recv) + def recvfrom_into(self, conn, buf, flags=0): + self._register_with_iocp(conn) + ov = _overlapped.Overlapped(NULL) + try: + ov.WSARecvFromInto(conn.fileno(), buf, flags) + except BrokenPipeError: + return self._result((0, None)) + + def finish_recv(trans, key, ov): + try: + return ov.getresult() + except OSError as exc: + if exc.winerror in (_overlapped.ERROR_NETNAME_DELETED, + _overlapped.ERROR_OPERATION_ABORTED): + raise ConnectionResetError(*exc.args) + else: + raise + + return self._register(ov, conn, finish_recv) + def sendto(self, conn, buf, flags=0, addr=None): self._register_with_iocp(conn) ov = _overlapped.Overlapped(NULL) diff --git a/Lib/test/test_asyncio/test_sock_lowlevel.py b/Lib/test/test_asyncio/test_sock_lowlevel.py index 14001a4a5001f..db47616d18343 100644 --- a/Lib/test/test_asyncio/test_sock_lowlevel.py +++ b/Lib/test/test_asyncio/test_sock_lowlevel.py @@ -5,11 +5,11 @@ from asyncio import proactor_events from itertools import cycle, islice +from unittest.mock import patch, Mock from test.test_asyncio import utils as test_utils from test import support from test.support import socket_helper - def tearDownModule(): asyncio.set_event_loop_policy(None) @@ -380,6 +380,79 @@ def test_huge_content_recvinto(self): self.loop.run_until_complete( self._basetest_huge_content_recvinto(httpd.address)) + async def _basetest_datagram_recvfrom(self, server_address): + # Happy path, sock.sendto() returns immediately + data = b'\x01' * 4096 + with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock: + sock.setblocking(False) + await self.loop.sock_sendto(sock, data, server_address) + received_data, from_addr = await self.loop.sock_recvfrom( + sock, 4096) + self.assertEqual(received_data, data) + self.assertEqual(from_addr, server_address) + + def test_recvfrom(self): + with test_utils.run_udp_echo_server() as server_address: + self.loop.run_until_complete( + self._basetest_datagram_recvfrom(server_address)) + + async def _basetest_datagram_recvfrom_into(self, server_address): + # Happy path, sock.sendto() returns immediately + with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock: + sock.setblocking(False) + + buf = bytearray(4096) + data = b'\x01' * 4096 + await self.loop.sock_sendto(sock, data, server_address) + num_bytes, from_addr = await self.loop.sock_recvfrom_into( + sock, buf) + self.assertEqual(num_bytes, 4096) + self.assertEqual(buf, data) + self.assertEqual(from_addr, server_address) + + buf = bytearray(8192) + await self.loop.sock_sendto(sock, data, server_address) + num_bytes, from_addr = await self.loop.sock_recvfrom_into( + sock, buf, 4096) + self.assertEqual(num_bytes, 4096) + self.assertEqual(buf[:4096], data[:4096]) + self.assertEqual(from_addr, server_address) + + def test_recvfrom_into(self): + with test_utils.run_udp_echo_server() as server_address: + self.loop.run_until_complete( + self._basetest_datagram_recvfrom_into(server_address)) + + async def _basetest_datagram_sendto_blocking(self, server_address): + # Sad path, sock.sendto() raises BlockingIOError + # This involves patching sock.sendto() to raise BlockingIOError but + # sendto() is not used by the proactor event loop + data = b'\x01' * 4096 + with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock: + sock.setblocking(False) + mock_sock = Mock(sock) + mock_sock.gettimeout = sock.gettimeout + mock_sock.sendto.configure_mock(side_effect=BlockingIOError) + mock_sock.fileno = sock.fileno + self.loop.call_soon( + lambda: setattr(mock_sock, 'sendto', sock.sendto) + ) + await self.loop.sock_sendto(mock_sock, data, server_address) + + received_data, from_addr = await self.loop.sock_recvfrom( + sock, 4096) + self.assertEqual(received_data, data) + self.assertEqual(from_addr, server_address) + + def test_sendto_blocking(self): + if sys.platform == 'win32': + if isinstance(self.loop, asyncio.ProactorEventLoop): + raise unittest.SkipTest('Not relevant to ProactorEventLoop') + + with test_utils.run_udp_echo_server() as server_address: + self.loop.run_until_complete( + self._basetest_datagram_sendto_blocking(server_address)) + @socket_helper.skip_unless_bind_unix_socket def test_unix_sock_client_ops(self): with test_utils.run_test_unix_server() as httpd: diff --git a/Lib/test/test_asyncio/utils.py b/Lib/test/test_asyncio/utils.py index 0b9cde6878f37..c32494d40ccea 100644 --- a/Lib/test/test_asyncio/utils.py +++ b/Lib/test/test_asyncio/utils.py @@ -281,6 +281,31 @@ def run_test_server(*, host='127.0.0.1', port=0, use_ssl=False): server_ssl_cls=SSLWSGIServer) +def echo_datagrams(sock): + while True: + data, addr = sock.recvfrom(4096) + if data == b'STOP': + sock.close() + break + else: + sock.sendto(data, addr) + + + at contextlib.contextmanager +def run_udp_echo_server(*, host='127.0.0.1', port=0): + addr_info = socket.getaddrinfo(host, port, type=socket.SOCK_DGRAM) + family, type, proto, _, sockaddr = addr_info[0] + sock = socket.socket(family, type, proto) + sock.bind((host, port)) + thread = threading.Thread(target=lambda: echo_datagrams(sock)) + thread.start() + try: + yield sock.getsockname() + finally: + sock.sendto(b'STOP', sock.getsockname()) + thread.join() + + def make_test_protocol(base): dct = {} for name in dir(base): diff --git a/Misc/NEWS.d/next/Library/2022-02-20-23-03-32.bpo-46805.HZ8xWG.rst b/Misc/NEWS.d/next/Library/2022-02-20-23-03-32.bpo-46805.HZ8xWG.rst new file mode 100644 index 0000000000000..3c877d5498cd6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-02-20-23-03-32.bpo-46805.HZ8xWG.rst @@ -0,0 +1,4 @@ +Added raw datagram socket functions for asyncio: +:meth:`~asyncio.AbstractEventLoop.sock_sendto`, +:meth:`~asyncio.AbstractEventLoop.sock_recvfrom` and +:meth:`~asyncio.AbstractEventLoop.sock_recvfrom_into`. diff --git a/Modules/clinic/overlapped.c.h b/Modules/clinic/overlapped.c.h index efecd9028b776..16d6013ef2f2e 100644 --- a/Modules/clinic/overlapped.c.h +++ b/Modules/clinic/overlapped.c.h @@ -905,4 +905,42 @@ _overlapped_Overlapped_WSARecvFrom(OverlappedObject *self, PyObject *const *args exit: return return_value; } -/*[clinic end generated code: output=ee2ec2f93c8d334b input=a9049054013a1b77]*/ + +PyDoc_STRVAR(_overlapped_Overlapped_WSARecvFromInto__doc__, +"WSARecvFromInto($self, handle, buf, size, flags=0, /)\n" +"--\n" +"\n" +"Start overlapped receive."); + +#define _OVERLAPPED_OVERLAPPED_WSARECVFROMINTO_METHODDEF \ + {"WSARecvFromInto", (PyCFunction)(void(*)(void))_overlapped_Overlapped_WSARecvFromInto, METH_FASTCALL, _overlapped_Overlapped_WSARecvFromInto__doc__}, + +static PyObject * +_overlapped_Overlapped_WSARecvFromInto_impl(OverlappedObject *self, + HANDLE handle, Py_buffer *bufobj, + DWORD size, DWORD flags); + +static PyObject * +_overlapped_Overlapped_WSARecvFromInto(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + HANDLE handle; + Py_buffer bufobj = {NULL, NULL}; + DWORD size; + DWORD flags = 0; + + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*k|k:WSARecvFromInto", + &handle, &bufobj, &size, &flags)) { + goto exit; + } + return_value = _overlapped_Overlapped_WSARecvFromInto_impl(self, handle, &bufobj, size, flags); + +exit: + /* Cleanup for bufobj */ + if (bufobj.obj) { + PyBuffer_Release(&bufobj); + } + + return return_value; +} +/*[clinic end generated code: output=5c9b17890ef29d52 input=a9049054013a1b77]*/ diff --git a/Modules/overlapped.c b/Modules/overlapped.c index 2ba48c8b845f5..ab9a2f0ce26f6 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -64,7 +64,7 @@ class _overlapped.Overlapped "OverlappedObject *" "&OverlappedType" enum {TYPE_NONE, TYPE_NOT_STARTED, TYPE_READ, TYPE_READINTO, TYPE_WRITE, TYPE_ACCEPT, TYPE_CONNECT, TYPE_DISCONNECT, TYPE_CONNECT_NAMED_PIPE, TYPE_WAIT_NAMED_PIPE_AND_CONNECT, TYPE_TRANSMIT_FILE, TYPE_READ_FROM, - TYPE_WRITE_TO}; + TYPE_WRITE_TO, TYPE_READ_FROM_INTO}; typedef struct { PyObject_HEAD @@ -91,6 +91,17 @@ typedef struct { struct sockaddr_in6 address; int address_length; } read_from; + + /* Data used for reading from a connectionless socket: + TYPE_READ_FROM_INTO */ + struct { + // A (number of bytes read, (host, port)) tuple + PyObject* result; + /* Buffer passed by the user */ + Py_buffer *user_buffer; + struct sockaddr_in6 address; + int address_length; + } read_from_into; }; } OverlappedObject; @@ -662,6 +673,13 @@ Overlapped_clear(OverlappedObject *self) } break; } + case TYPE_READ_FROM_INTO: { + if (self->read_from_into.result) { + // We've received a message, free the result tuple. + Py_CLEAR(self->read_from_into.result); + } + break; + } case TYPE_WRITE: case TYPE_WRITE_TO: case TYPE_READINTO: { @@ -866,6 +884,11 @@ _overlapped_Overlapped_getresult_impl(OverlappedObject *self, BOOL wait) { break; } + else if (self->type == TYPE_READ_FROM_INTO && + self->read_from_into.result != NULL) + { + break; + } /* fall through */ default: return SetFromWindowsErr(err); @@ -914,6 +937,30 @@ _overlapped_Overlapped_getresult_impl(OverlappedObject *self, BOOL wait) Py_INCREF(self->read_from.result); return self->read_from.result; + case TYPE_READ_FROM_INTO: + // unparse the address + addr = unparse_address((SOCKADDR*)&self->read_from_into.address, + self->read_from_into.address_length); + + if (addr == NULL) { + return NULL; + } + + // The result is a two item tuple: (number of bytes read, address) + self->read_from_into.result = PyTuple_New(2); + if (self->read_from_into.result == NULL) { + Py_CLEAR(addr); + return NULL; + } + + // first item: number of bytes read + PyTuple_SET_ITEM(self->read_from_into.result, 0, + PyLong_FromUnsignedLong((unsigned long)transferred)); + // second item: address + PyTuple_SET_ITEM(self->read_from_into.result, 1, addr); + + Py_INCREF(self->read_from_into.result); + return self->read_from_into.result; default: return PyLong_FromUnsignedLong((unsigned long) transferred); } @@ -1053,6 +1100,7 @@ do_WSARecv(OverlappedObject *self, HANDLE handle, } } + /*[clinic input] _overlapped.Overlapped.WSARecv @@ -1617,6 +1665,13 @@ Overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg) case TYPE_READ_FROM: Py_VISIT(self->read_from.result); Py_VISIT(self->read_from.allocated_buffer); + break; + case TYPE_READ_FROM_INTO: + Py_VISIT(self->read_from_into.result); + if (self->read_from_into.user_buffer->obj) { + Py_VISIT(&self->read_from_into.user_buffer->obj); + } + break; } return 0; } @@ -1766,8 +1821,8 @@ _overlapped_Overlapped_WSARecvFrom_impl(OverlappedObject *self, DWORD flags) /*[clinic end generated code: output=13832a2025b86860 input=1b2663fa130e0286]*/ { - DWORD nread; PyObject *buf; + DWORD nread; WSABUF wsabuf; int ret; DWORD err; @@ -1785,8 +1840,8 @@ _overlapped_Overlapped_WSARecvFrom_impl(OverlappedObject *self, return NULL; } - wsabuf.len = size; wsabuf.buf = PyBytes_AS_STRING(buf); + wsabuf.len = size; self->type = TYPE_READ_FROM; self->handle = handle; @@ -1802,8 +1857,74 @@ _overlapped_Overlapped_WSARecvFrom_impl(OverlappedObject *self, Py_END_ALLOW_THREADS self->error = err = (ret < 0 ? WSAGetLastError() : ERROR_SUCCESS); + switch (err) { + case ERROR_BROKEN_PIPE: + mark_as_completed(&self->overlapped); + return SetFromWindowsErr(err); + case ERROR_SUCCESS: + case ERROR_MORE_DATA: + case ERROR_IO_PENDING: + Py_RETURN_NONE; + default: + self->type = TYPE_NOT_STARTED; + return SetFromWindowsErr(err); + } +} - switch(err) { + +/*[clinic input] +_overlapped.Overlapped.WSARecvFromInto + + handle: HANDLE + buf as bufobj: Py_buffer + size: DWORD + flags: DWORD = 0 + / + +Start overlapped receive. +[clinic start generated code]*/ + +static PyObject * +_overlapped_Overlapped_WSARecvFromInto_impl(OverlappedObject *self, + HANDLE handle, Py_buffer *bufobj, + DWORD size, DWORD flags) +/*[clinic end generated code: output=30c7ea171a691757 input=4be4b08d03531e76]*/ +{ + DWORD nread; + WSABUF wsabuf; + int ret; + DWORD err; + + if (self->type != TYPE_NONE) { + PyErr_SetString(PyExc_ValueError, "operation already attempted"); + return NULL; + } + +#if SIZEOF_SIZE_T > SIZEOF_LONG + if (bufobj->len > (Py_ssize_t)ULONG_MAX) { + PyErr_SetString(PyExc_ValueError, "buffer too large"); + return NULL; + } +#endif + + wsabuf.buf = bufobj->buf; + wsabuf.len = size; + + self->type = TYPE_READ_FROM_INTO; + self->handle = handle; + self->read_from_into.user_buffer = bufobj; + memset(&self->read_from_into.address, 0, sizeof(self->read_from_into.address)); + self->read_from_into.address_length = sizeof(self->read_from_into.address); + + Py_BEGIN_ALLOW_THREADS + ret = WSARecvFrom((SOCKET)handle, &wsabuf, 1, &nread, &flags, + (SOCKADDR*)&self->read_from_into.address, + &self->read_from_into.address_length, + &self->overlapped, NULL); + Py_END_ALLOW_THREADS + + self->error = err = (ret < 0 ? WSAGetLastError() : ERROR_SUCCESS); + switch (err) { case ERROR_BROKEN_PIPE: mark_as_completed(&self->overlapped); return SetFromWindowsErr(err); @@ -1817,6 +1938,7 @@ _overlapped_Overlapped_WSARecvFrom_impl(OverlappedObject *self, } } + #include "clinic/overlapped.c.h" static PyMethodDef Overlapped_methods[] = { @@ -1826,6 +1948,8 @@ static PyMethodDef Overlapped_methods[] = { _OVERLAPPED_OVERLAPPED_READFILEINTO_METHODDEF _OVERLAPPED_OVERLAPPED_WSARECV_METHODDEF _OVERLAPPED_OVERLAPPED_WSARECVINTO_METHODDEF + _OVERLAPPED_OVERLAPPED_WSARECVFROM_METHODDEF + _OVERLAPPED_OVERLAPPED_WSARECVFROMINTO_METHODDEF _OVERLAPPED_OVERLAPPED_WRITEFILE_METHODDEF _OVERLAPPED_OVERLAPPED_WSASEND_METHODDEF _OVERLAPPED_OVERLAPPED_ACCEPTEX_METHODDEF From webhook-mailer at python.org Sun Mar 13 14:14:29 2022 From: webhook-mailer at python.org (ned-deily) Date: Sun, 13 Mar 2022 18:14:29 -0000 Subject: [Python-checkins] bpo-46985: Upgrade bundled pip to 22.0.4 (GH-31819) Message-ID: https://github.com/python/cpython/commit/d87f1b787ed38dfd307d82452f2efe9dc5b93942 commit: d87f1b787ed38dfd307d82452f2efe9dc5b93942 branch: main author: Pradyun Gedam committer: ned-deily date: 2022-03-13T14:14:20-04:00 summary: bpo-46985: Upgrade bundled pip to 22.0.4 (GH-31819) files: A Lib/ensurepip/_bundled/pip-22.0.4-py3-none-any.whl A Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst D Lib/ensurepip/_bundled/pip-21.2.4-py3-none-any.whl M Lib/ensurepip/__init__.py diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index 94f1b6604cb7a..a198a86e1f9af 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -11,7 +11,7 @@ __all__ = ["version", "bootstrap"] _PACKAGE_NAMES = ('setuptools', 'pip') _SETUPTOOLS_VERSION = "58.1.0" -_PIP_VERSION = "21.2.4" +_PIP_VERSION = "22.0.4" _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION, "py3"), ("pip", _PIP_VERSION, "py3"), diff --git a/Lib/ensurepip/_bundled/pip-21.2.4-py3-none-any.whl b/Lib/ensurepip/_bundled/pip-21.2.4-py3-none-any.whl deleted file mode 100644 index 46d3012c59b17..0000000000000 Binary files a/Lib/ensurepip/_bundled/pip-21.2.4-py3-none-any.whl and /dev/null differ diff --git a/Lib/ensurepip/_bundled/pip-22.0.4-py3-none-any.whl b/Lib/ensurepip/_bundled/pip-22.0.4-py3-none-any.whl new file mode 100644 index 0000000000000..7ba048e245227 Binary files /dev/null and b/Lib/ensurepip/_bundled/pip-22.0.4-py3-none-any.whl differ diff --git a/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst b/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst new file mode 100644 index 0000000000000..2e08ee837f583 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst @@ -0,0 +1 @@ +Upgrade pip wheel bundled with ensurepip (pip 22.0.4) From webhook-mailer at python.org Sun Mar 13 14:49:36 2022 From: webhook-mailer at python.org (ned-deily) Date: Sun, 13 Mar 2022 18:49:36 -0000 Subject: [Python-checkins] bpo-46986: Upgrade bundled setuptools to 60.9.3 (GH-31820) Message-ID: https://github.com/python/cpython/commit/c99ac3c364ee21be72263791b71ee8b55f64de08 commit: c99ac3c364ee21be72263791b71ee8b55f64de08 branch: main author: Pradyun Gedam committer: ned-deily date: 2022-03-13T14:49:28-04:00 summary: bpo-46986: Upgrade bundled setuptools to 60.9.3 (GH-31820) files: A Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl A Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst D Lib/ensurepip/_bundled/setuptools-58.1.0-py3-none-any.whl M Lib/ensurepip/__init__.py diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index a198a86e1f9af..d23fcad139874 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -10,7 +10,7 @@ __all__ = ["version", "bootstrap"] _PACKAGE_NAMES = ('setuptools', 'pip') -_SETUPTOOLS_VERSION = "58.1.0" +_SETUPTOOLS_VERSION = "60.9.3" _PIP_VERSION = "22.0.4" _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION, "py3"), diff --git a/Lib/ensurepip/_bundled/setuptools-58.1.0-py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-58.1.0-py3-none-any.whl deleted file mode 100644 index 18c8c22958f1f..0000000000000 Binary files a/Lib/ensurepip/_bundled/setuptools-58.1.0-py3-none-any.whl and /dev/null differ diff --git a/Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl new file mode 100644 index 0000000000000..b88ddc659ee10 Binary files /dev/null and b/Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl differ diff --git a/Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst b/Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst new file mode 100644 index 0000000000000..06dd1271902d1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst @@ -0,0 +1 @@ +Upgrade setuptools wheel bundled with ensurepip (setuptools 60.9.3) From webhook-mailer at python.org Sun Mar 13 14:52:17 2022 From: webhook-mailer at python.org (miss-islington) Date: Sun, 13 Mar 2022 18:52:17 -0000 Subject: [Python-checkins] [3.10] bpo-46985: Upgrade bundled pip to 22.0.4 (GH-31819) (GH-31849) Message-ID: https://github.com/python/cpython/commit/1ceda9787f586e11ccd2a94171422a2d70622a27 commit: 1ceda9787f586e11ccd2a94171422a2d70622a27 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-13T11:52:04-07:00 summary: [3.10] bpo-46985: Upgrade bundled pip to 22.0.4 (GH-31819) (GH-31849) (cherry picked from commit d87f1b787ed38dfd307d82452f2efe9dc5b93942) Co-authored-by: Pradyun Gedam Automerge-Triggered-By: GH:ned-deily files: A Lib/ensurepip/_bundled/pip-22.0.4-py3-none-any.whl A Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst D Lib/ensurepip/_bundled/pip-21.2.4-py3-none-any.whl M Lib/ensurepip/__init__.py diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index 0a5730c00c359..3fbe8b2a5b136 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -12,7 +12,7 @@ __all__ = ["version", "bootstrap"] _PACKAGE_NAMES = ('setuptools', 'pip') _SETUPTOOLS_VERSION = "58.1.0" -_PIP_VERSION = "21.2.4" +_PIP_VERSION = "22.0.4" _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION, "py3"), ("pip", _PIP_VERSION, "py3"), diff --git a/Lib/ensurepip/_bundled/pip-21.2.4-py3-none-any.whl b/Lib/ensurepip/_bundled/pip-21.2.4-py3-none-any.whl deleted file mode 100644 index 46d3012c59b17..0000000000000 Binary files a/Lib/ensurepip/_bundled/pip-21.2.4-py3-none-any.whl and /dev/null differ diff --git a/Lib/ensurepip/_bundled/pip-22.0.4-py3-none-any.whl b/Lib/ensurepip/_bundled/pip-22.0.4-py3-none-any.whl new file mode 100644 index 0000000000000..7ba048e245227 Binary files /dev/null and b/Lib/ensurepip/_bundled/pip-22.0.4-py3-none-any.whl differ diff --git a/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst b/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst new file mode 100644 index 0000000000000..2e08ee837f583 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst @@ -0,0 +1 @@ +Upgrade pip wheel bundled with ensurepip (pip 22.0.4) From webhook-mailer at python.org Sun Mar 13 14:55:36 2022 From: webhook-mailer at python.org (miss-islington) Date: Sun, 13 Mar 2022 18:55:36 -0000 Subject: [Python-checkins] [3.9] bpo-46985: Upgrade bundled pip to 22.0.4 (GH-31819) (GH-31850) Message-ID: https://github.com/python/cpython/commit/4f340b07392dd50800f255ceee0ec1b7edd77dc9 commit: 4f340b07392dd50800f255ceee0ec1b7edd77dc9 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-13T11:55:32-07:00 summary: [3.9] bpo-46985: Upgrade bundled pip to 22.0.4 (GH-31819) (GH-31850) (cherry picked from commit d87f1b787ed38dfd307d82452f2efe9dc5b93942) Co-authored-by: Pradyun Gedam Automerge-Triggered-By: GH:ned-deily files: A Lib/ensurepip/_bundled/pip-22.0.4-py3-none-any.whl A Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst D Lib/ensurepip/_bundled/pip-21.2.4-py3-none-any.whl M Lib/ensurepip/__init__.py diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index 2a140a2624d46..e510cc7fb2baf 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -12,7 +12,7 @@ __all__ = ["version", "bootstrap"] _SETUPTOOLS_VERSION = "58.1.0" -_PIP_VERSION = "21.2.4" +_PIP_VERSION = "22.0.4" _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION, "py3"), ("pip", _PIP_VERSION, "py3"), diff --git a/Lib/ensurepip/_bundled/pip-21.2.4-py3-none-any.whl b/Lib/ensurepip/_bundled/pip-21.2.4-py3-none-any.whl deleted file mode 100644 index 46d3012c59b17..0000000000000 Binary files a/Lib/ensurepip/_bundled/pip-21.2.4-py3-none-any.whl and /dev/null differ diff --git a/Lib/ensurepip/_bundled/pip-22.0.4-py3-none-any.whl b/Lib/ensurepip/_bundled/pip-22.0.4-py3-none-any.whl new file mode 100644 index 0000000000000..7ba048e245227 Binary files /dev/null and b/Lib/ensurepip/_bundled/pip-22.0.4-py3-none-any.whl differ diff --git a/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst b/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst new file mode 100644 index 0000000000000..2e08ee837f583 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst @@ -0,0 +1 @@ +Upgrade pip wheel bundled with ensurepip (pip 22.0.4) From webhook-mailer at python.org Sun Mar 13 15:15:30 2022 From: webhook-mailer at python.org (miss-islington) Date: Sun, 13 Mar 2022 19:15:30 -0000 Subject: [Python-checkins] bpo-46986: Upgrade bundled setuptools to 60.9.3 (GH-31820) Message-ID: https://github.com/python/cpython/commit/25962e4e60235645f945d23281431b30b3c3d573 commit: 25962e4e60235645f945d23281431b30b3c3d573 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-13T12:15:20-07:00 summary: bpo-46986: Upgrade bundled setuptools to 60.9.3 (GH-31820) (cherry picked from commit c99ac3c364ee21be72263791b71ee8b55f64de08) Co-authored-by: Pradyun Gedam files: A Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl A Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst D Lib/ensurepip/_bundled/setuptools-58.1.0-py3-none-any.whl M Lib/ensurepip/__init__.py diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index 3fbe8b2a5b136..20a40456d5fe0 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -11,7 +11,7 @@ __all__ = ["version", "bootstrap"] _PACKAGE_NAMES = ('setuptools', 'pip') -_SETUPTOOLS_VERSION = "58.1.0" +_SETUPTOOLS_VERSION = "60.9.3" _PIP_VERSION = "22.0.4" _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION, "py3"), diff --git a/Lib/ensurepip/_bundled/setuptools-58.1.0-py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-58.1.0-py3-none-any.whl deleted file mode 100644 index 18c8c22958f1f..0000000000000 Binary files a/Lib/ensurepip/_bundled/setuptools-58.1.0-py3-none-any.whl and /dev/null differ diff --git a/Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl new file mode 100644 index 0000000000000..b88ddc659ee10 Binary files /dev/null and b/Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl differ diff --git a/Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst b/Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst new file mode 100644 index 0000000000000..06dd1271902d1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst @@ -0,0 +1 @@ +Upgrade setuptools wheel bundled with ensurepip (setuptools 60.9.3) From webhook-mailer at python.org Sun Mar 13 15:53:37 2022 From: webhook-mailer at python.org (jaraco) Date: Sun, 13 Mar 2022 19:53:37 -0000 Subject: [Python-checkins] bpo-47004: Sync with importlib_metadata 4.11.3. (#31854) Message-ID: https://github.com/python/cpython/commit/b1e286860742e7ba6fadc75e3ddb6c2899a56919 commit: b1e286860742e7ba6fadc75e3ddb6c2899a56919 branch: main author: Jason R. Coombs committer: jaraco date: 2022-03-13T15:53:29-04:00 summary: bpo-47004: Sync with importlib_metadata 4.11.3. (#31854) files: A Misc/NEWS.d/next/Library/2022-03-13-15-04-05.bpo-47004.SyYpxd.rst M Doc/library/importlib.metadata.rst M Lib/importlib/metadata/__init__.py M Lib/test/test_importlib/test_metadata_api.py diff --git a/Doc/library/importlib.metadata.rst b/Doc/library/importlib.metadata.rst index 50fc904535b09..a6caa994497ba 100644 --- a/Doc/library/importlib.metadata.rst +++ b/Doc/library/importlib.metadata.rst @@ -264,6 +264,7 @@ Python packages or modules:: .. versionadded:: 3.10 +.. _distributions: Distributions ============= diff --git a/Lib/importlib/metadata/__init__.py b/Lib/importlib/metadata/__init__.py index 9fd6e04ae9abf..9ceae8a0e04b5 100644 --- a/Lib/importlib/metadata/__init__.py +++ b/Lib/importlib/metadata/__init__.py @@ -152,6 +152,15 @@ class EntryPoint(DeprecatedTuple): See `the packaging docs on entry points `_ for more information. + + >>> ep = EntryPoint( + ... name=None, group=None, value='package.module:attr [extra1, extra2]') + >>> ep.module + 'package.module' + >>> ep.attr + 'attr' + >>> ep.extras + ['extra1', 'extra2'] """ pattern = re.compile( @@ -203,7 +212,7 @@ def attr(self): @property def extras(self): match = self.pattern.match(self.value) - return list(re.finditer(r'\w+', match.group('extras') or '')) + return re.findall(r'\w+', match.group('extras') or '') def _for(self, dist): vars(self).update(dist=dist) @@ -221,6 +230,25 @@ def __iter__(self): return iter((self.name, self)) def matches(self, **params): + """ + EntryPoint matches the given parameters. + + >>> ep = EntryPoint(group='foo', name='bar', value='bing:bong [extra1, extra2]') + >>> ep.matches(group='foo') + True + >>> ep.matches(name='bar', value='bing:bong [extra1, extra2]') + True + >>> ep.matches(group='foo', name='other') + False + >>> ep.matches() + True + >>> ep.matches(extras=['extra1', 'extra2']) + True + >>> ep.matches(module='bing') + True + >>> ep.matches(attr='bong') + True + """ attrs = (getattr(self, param) for param in params) return all(map(operator.eq, params.values(), attrs)) @@ -292,21 +320,15 @@ def wrapped(self, *args, **kwargs): self._warn() return getattr(super(), method_name)(*args, **kwargs) - return wrapped - - for method_name in [ - '__setitem__', - '__delitem__', - 'append', - 'reverse', - 'extend', - 'pop', - 'remove', - '__iadd__', - 'insert', - 'sort', - ]: - locals()[method_name] = _wrap_deprecated_method(method_name) + return method_name, wrapped + + locals().update( + map( + _wrap_deprecated_method, + '__setitem__ __delitem__ append reverse extend pop remove ' + '__iadd__ insert sort'.split(), + ) + ) def __add__(self, other): if not isinstance(other, tuple): @@ -660,7 +682,7 @@ def _read_dist_info_reqs(self): def _read_egg_info_reqs(self): source = self.read_text('requires.txt') - return source and self._deps_from_requires_text(source) + return pass_none(self._deps_from_requires_text)(source) @classmethod def _deps_from_requires_text(cls, source): @@ -765,7 +787,6 @@ def __new__(cls, root): def __init__(self, root): self.root = root - self.base = os.path.basename(self.root).lower() def joinpath(self, child): return pathlib.Path(self.root, child) diff --git a/Lib/test/test_importlib/test_metadata_api.py b/Lib/test/test_importlib/test_metadata_api.py index 78287c314ced7..b3627cbb75bd7 100644 --- a/Lib/test/test_importlib/test_metadata_api.py +++ b/Lib/test/test_importlib/test_metadata_api.py @@ -220,6 +220,16 @@ def test_requires_egg_info(self): assert len(deps) == 2 assert any(dep == 'wheel >= 1.0; python_version >= "2.7"' for dep in deps) + def test_requires_egg_info_empty(self): + fixtures.build_files( + { + 'requires.txt': '', + }, + self.site_dir.joinpath('egginfo_pkg.egg-info'), + ) + deps = requires('egginfo-pkg') + assert deps == [] + def test_requires_dist_info(self): deps = requires('distinfo-pkg') assert len(deps) == 2 diff --git a/Misc/NEWS.d/next/Library/2022-03-13-15-04-05.bpo-47004.SyYpxd.rst b/Misc/NEWS.d/next/Library/2022-03-13-15-04-05.bpo-47004.SyYpxd.rst new file mode 100644 index 0000000000000..3cb3b212d89e9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-13-15-04-05.bpo-47004.SyYpxd.rst @@ -0,0 +1,3 @@ +Apply bugfixes from importlib_metadata 4.11.3, including bugfix for +EntryPoint.extras, which was returning match objects and not the extras +strings. From webhook-mailer at python.org Sun Mar 13 15:58:07 2022 From: webhook-mailer at python.org (ned-deily) Date: Sun, 13 Mar 2022 19:58:07 -0000 Subject: [Python-checkins] bpo-46985: Upgrade bundled pip to 22.0.4 (GH-31819) (GH-31852) Message-ID: https://github.com/python/cpython/commit/5a8e968c38cc239c07eba15ded439a12818a852f commit: 5a8e968c38cc239c07eba15ded439a12818a852f branch: 3.7 author: Ned Deily committer: ned-deily date: 2022-03-13T15:58:02-04:00 summary: bpo-46985: Upgrade bundled pip to 22.0.4 (GH-31819) (GH-31852) (cherry picked from commit d87f1b787ed38dfd307d82452f2efe9dc5b93942) Co-authored-by: Pradyun Gedam files: A Lib/ensurepip/_bundled/pip-22.0.4-py3-none-any.whl A Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst D Lib/ensurepip/_bundled/pip-20.1.1-py2.py3-none-any.whl M Lib/ensurepip/__init__.py diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index 94d40b0c8d010..8289c495d3689 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -7,15 +7,12 @@ __all__ = ["version", "bootstrap"] - - +_PACKAGE_NAMES = ('setuptools', 'pip') _SETUPTOOLS_VERSION = "47.1.0" - -_PIP_VERSION = "20.1.1" - +_PIP_VERSION = "22.0.4" _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION, "py3"), - ("pip", _PIP_VERSION, "py2.py3"), + ("pip", _PIP_VERSION, "py3"), ] diff --git a/Lib/ensurepip/_bundled/pip-20.1.1-py2.py3-none-any.whl b/Lib/ensurepip/_bundled/pip-20.1.1-py2.py3-none-any.whl deleted file mode 100644 index ea1d0f7c8604a..0000000000000 Binary files a/Lib/ensurepip/_bundled/pip-20.1.1-py2.py3-none-any.whl and /dev/null differ diff --git a/Lib/ensurepip/_bundled/pip-22.0.4-py3-none-any.whl b/Lib/ensurepip/_bundled/pip-22.0.4-py3-none-any.whl new file mode 100644 index 0000000000000..7ba048e245227 Binary files /dev/null and b/Lib/ensurepip/_bundled/pip-22.0.4-py3-none-any.whl differ diff --git a/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst b/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst new file mode 100644 index 0000000000000..2e08ee837f583 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst @@ -0,0 +1 @@ +Upgrade pip wheel bundled with ensurepip (pip 22.0.4) From webhook-mailer at python.org Sun Mar 13 16:02:14 2022 From: webhook-mailer at python.org (ned-deily) Date: Sun, 13 Mar 2022 20:02:14 -0000 Subject: [Python-checkins] bpo-46986: Upgrade bundled setuptools to 60.9.3 (GH-31820) (GH-31855) Message-ID: https://github.com/python/cpython/commit/bda64b3c0c4e45de4c82ba1b8722f56db5ac88ba commit: bda64b3c0c4e45de4c82ba1b8722f56db5ac88ba branch: 3.9 author: Ned Deily committer: ned-deily date: 2022-03-13T16:02:10-04:00 summary: bpo-46986: Upgrade bundled setuptools to 60.9.3 (GH-31820) (GH-31855) (cherry picked from commit c99ac3c364ee21be72263791b71ee8b55f64de08) Co-authored-by: Pradyun Gedam files: A Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl A Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst D Lib/ensurepip/_bundled/setuptools-58.1.0-py3-none-any.whl M Lib/ensurepip/__init__.py diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index e510cc7fb2baf..0d76fc9b4aac2 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -11,7 +11,8 @@ __all__ = ["version", "bootstrap"] -_SETUPTOOLS_VERSION = "58.1.0" +_PACKAGE_NAMES = ('setuptools', 'pip') +_SETUPTOOLS_VERSION = "60.9.3" _PIP_VERSION = "22.0.4" _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION, "py3"), diff --git a/Lib/ensurepip/_bundled/setuptools-58.1.0-py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-58.1.0-py3-none-any.whl deleted file mode 100644 index 18c8c22958f1f..0000000000000 Binary files a/Lib/ensurepip/_bundled/setuptools-58.1.0-py3-none-any.whl and /dev/null differ diff --git a/Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl new file mode 100644 index 0000000000000..b88ddc659ee10 Binary files /dev/null and b/Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl differ diff --git a/Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst b/Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst new file mode 100644 index 0000000000000..06dd1271902d1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst @@ -0,0 +1 @@ +Upgrade setuptools wheel bundled with ensurepip (setuptools 60.9.3) From webhook-mailer at python.org Sun Mar 13 17:29:06 2022 From: webhook-mailer at python.org (asvetlov) Date: Sun, 13 Mar 2022 21:29:06 -0000 Subject: [Python-checkins] bpo-47003: Cleanup _overlapped module (GH-31848) Message-ID: https://github.com/python/cpython/commit/690490e4de9f2baf07171b3d63fc440239928fb4 commit: 690490e4de9f2baf07171b3d63fc440239928fb4 branch: main author: Andrew Svetlov committer: asvetlov date: 2022-03-13T23:28:45+02:00 summary: bpo-47003: Cleanup _overlapped module (GH-31848) files: M Modules/clinic/overlapped.c.h M Modules/overlapped.c diff --git a/Modules/clinic/overlapped.c.h b/Modules/clinic/overlapped.c.h index 16d6013ef2f2e..7e81fc8f97104 100644 --- a/Modules/clinic/overlapped.c.h +++ b/Modules/clinic/overlapped.c.h @@ -466,22 +466,27 @@ PyDoc_STRVAR(_overlapped_Overlapped_ReadFileInto__doc__, static PyObject * _overlapped_Overlapped_ReadFileInto_impl(OverlappedObject *self, - HANDLE handle, PyObject *bufobj); + HANDLE handle, Py_buffer *bufobj); static PyObject * _overlapped_Overlapped_ReadFileInto(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HANDLE handle; - PyObject *bufobj; + Py_buffer bufobj = {NULL, NULL}; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"O:ReadFileInto", + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*:ReadFileInto", &handle, &bufobj)) { goto exit; } - return_value = _overlapped_Overlapped_ReadFileInto_impl(self, handle, bufobj); + return_value = _overlapped_Overlapped_ReadFileInto_impl(self, handle, &bufobj); exit: + /* Cleanup for bufobj */ + if (bufobj.obj) { + PyBuffer_Release(&bufobj); + } + return return_value; } @@ -527,7 +532,7 @@ PyDoc_STRVAR(_overlapped_Overlapped_WSARecvInto__doc__, static PyObject * _overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self, - HANDLE handle, PyObject *bufobj, + HANDLE handle, Py_buffer *bufobj, DWORD flags); static PyObject * @@ -535,16 +540,21 @@ _overlapped_Overlapped_WSARecvInto(OverlappedObject *self, PyObject *const *args { PyObject *return_value = NULL; HANDLE handle; - PyObject *bufobj; + Py_buffer bufobj = {NULL, NULL}; DWORD flags; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"Ok:WSARecvInto", + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*k:WSARecvInto", &handle, &bufobj, &flags)) { goto exit; } - return_value = _overlapped_Overlapped_WSARecvInto_impl(self, handle, bufobj, flags); + return_value = _overlapped_Overlapped_WSARecvInto_impl(self, handle, &bufobj, flags); exit: + /* Cleanup for bufobj */ + if (bufobj.obj) { + PyBuffer_Release(&bufobj); + } + return return_value; } @@ -559,22 +569,27 @@ PyDoc_STRVAR(_overlapped_Overlapped_WriteFile__doc__, static PyObject * _overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle, - PyObject *bufobj); + Py_buffer *bufobj); static PyObject * _overlapped_Overlapped_WriteFile(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HANDLE handle; - PyObject *bufobj; + Py_buffer bufobj = {NULL, NULL}; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"O:WriteFile", + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*:WriteFile", &handle, &bufobj)) { goto exit; } - return_value = _overlapped_Overlapped_WriteFile_impl(self, handle, bufobj); + return_value = _overlapped_Overlapped_WriteFile_impl(self, handle, &bufobj); exit: + /* Cleanup for bufobj */ + if (bufobj.obj) { + PyBuffer_Release(&bufobj); + } + return return_value; } @@ -589,23 +604,28 @@ PyDoc_STRVAR(_overlapped_Overlapped_WSASend__doc__, static PyObject * _overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle, - PyObject *bufobj, DWORD flags); + Py_buffer *bufobj, DWORD flags); static PyObject * _overlapped_Overlapped_WSASend(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HANDLE handle; - PyObject *bufobj; + Py_buffer bufobj = {NULL, NULL}; DWORD flags; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"Ok:WSASend", + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*k:WSASend", &handle, &bufobj, &flags)) { goto exit; } - return_value = _overlapped_Overlapped_WSASend_impl(self, handle, bufobj, flags); + return_value = _overlapped_Overlapped_WSASend_impl(self, handle, &bufobj, flags); exit: + /* Cleanup for bufobj */ + if (bufobj.obj) { + PyBuffer_Release(&bufobj); + } + return return_value; } @@ -852,7 +872,7 @@ PyDoc_STRVAR(_overlapped_Overlapped_WSASendTo__doc__, static PyObject * _overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle, - PyObject *bufobj, DWORD flags, + Py_buffer *bufobj, DWORD flags, PyObject *AddressObj); static PyObject * @@ -860,17 +880,22 @@ _overlapped_Overlapped_WSASendTo(OverlappedObject *self, PyObject *const *args, { PyObject *return_value = NULL; HANDLE handle; - PyObject *bufobj; + Py_buffer bufobj = {NULL, NULL}; DWORD flags; PyObject *AddressObj; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"OkO:WSASendTo", + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*kO:WSASendTo", &handle, &bufobj, &flags, &AddressObj)) { goto exit; } - return_value = _overlapped_Overlapped_WSASendTo_impl(self, handle, bufobj, flags, AddressObj); + return_value = _overlapped_Overlapped_WSASendTo_impl(self, handle, &bufobj, flags, AddressObj); exit: + /* Cleanup for bufobj */ + if (bufobj.obj) { + PyBuffer_Release(&bufobj); + } + return return_value; } @@ -943,4 +968,4 @@ _overlapped_Overlapped_WSARecvFromInto(OverlappedObject *self, PyObject *const * return return_value; } -/*[clinic end generated code: output=5c9b17890ef29d52 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d19a061ea7398d23 input=a9049054013a1b77]*/ diff --git a/Modules/overlapped.c b/Modules/overlapped.c index ab9a2f0ce26f6..74fba8346c2e1 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -98,7 +98,7 @@ typedef struct { // A (number of bytes read, (host, port)) tuple PyObject* result; /* Buffer passed by the user */ - Py_buffer *user_buffer; + Py_buffer user_buffer; struct sockaddr_in6 address; int address_length; } read_from_into; @@ -118,6 +118,13 @@ overlapped_get_state(PyObject *module) } +static inline void +steal_buffer(Py_buffer * dst, Py_buffer * src) +{ + memcpy(dst, src, sizeof(Py_buffer)); + memset(src, 0, sizeof(Py_buffer)); +} + /* * Map Windows error codes to subclasses of OSError */ @@ -150,7 +157,6 @@ static LPFN_ACCEPTEX Py_AcceptEx = NULL; static LPFN_CONNECTEX Py_ConnectEx = NULL; static LPFN_DISCONNECTEX Py_DisconnectEx = NULL; static LPFN_TRANSMITFILE Py_TransmitFile = NULL; -static BOOL (CALLBACK *Py_CancelIoEx)(HANDLE, LPOVERLAPPED) = NULL; #define GET_WSA_POINTER(s, x) \ (SOCKET_ERROR != WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, \ @@ -164,10 +170,19 @@ initialize_function_pointers(void) GUID GuidConnectEx = WSAID_CONNECTEX; GUID GuidDisconnectEx = WSAID_DISCONNECTEX; GUID GuidTransmitFile = WSAID_TRANSMITFILE; - HINSTANCE hKernel32; SOCKET s; DWORD dwBytes; + if (Py_AcceptEx != NULL && + Py_ConnectEx != NULL && + Py_DisconnectEx != NULL && + Py_TransmitFile != NULL) + { + // All function pointers are initialized already + // by previous module import + return 0; + } + s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (s == INVALID_SOCKET) { SetFromWindowsErr(WSAGetLastError()); @@ -185,12 +200,6 @@ initialize_function_pointers(void) } closesocket(s); - - /* On WinXP we will have Py_CancelIoEx == NULL */ - Py_BEGIN_ALLOW_THREADS - hKernel32 = GetModuleHandle("KERNEL32"); - *(FARPROC *)&Py_CancelIoEx = GetProcAddress(hKernel32, "CancelIoEx"); - Py_END_ALLOW_THREADS return 0; } @@ -596,7 +605,7 @@ _overlapped_FormatMessage_impl(PyObject *module, DWORD code) * Mark operation as completed - used when reading produces ERROR_BROKEN_PIPE */ -static void +static inline void mark_as_completed(OVERLAPPED *ov) { ov->Internal = 0; @@ -678,6 +687,9 @@ Overlapped_clear(OverlappedObject *self) // We've received a message, free the result tuple. Py_CLEAR(self->read_from_into.result); } + if (self->read_from_into.user_buffer.obj) { + PyBuffer_Release(&self->read_from_into.user_buffer); + } break; } case TYPE_WRITE: @@ -704,10 +716,10 @@ Overlapped_dealloc(OverlappedObject *self) if (!HasOverlappedIoCompleted(&self->overlapped) && self->type != TYPE_NOT_STARTED) { - if (Py_CancelIoEx && Py_CancelIoEx(self->handle, &self->overlapped)) + Py_BEGIN_ALLOW_THREADS + if (CancelIoEx(self->handle, &self->overlapped)) wait = TRUE; - Py_BEGIN_ALLOW_THREADS ret = GetOverlappedResult(self->handle, &self->overlapped, &bytes, wait); Py_END_ALLOW_THREADS @@ -820,10 +832,7 @@ _overlapped_Overlapped_cancel_impl(OverlappedObject *self) if (!HasOverlappedIoCompleted(&self->overlapped)) { Py_BEGIN_ALLOW_THREADS - if (Py_CancelIoEx) - ret = Py_CancelIoEx(self->handle, &self->overlapped); - else - ret = CancelIo(self->handle); + ret = CancelIoEx(self->handle, &self->overlapped); Py_END_ALLOW_THREADS } @@ -1034,7 +1043,7 @@ _overlapped_Overlapped_ReadFile_impl(OverlappedObject *self, HANDLE handle, _overlapped.Overlapped.ReadFileInto handle: HANDLE - buf as bufobj: object + buf as bufobj: Py_buffer / Start overlapped receive. @@ -1042,24 +1051,21 @@ Start overlapped receive. static PyObject * _overlapped_Overlapped_ReadFileInto_impl(OverlappedObject *self, - HANDLE handle, PyObject *bufobj) -/*[clinic end generated code: output=1e9e712e742e5b2a input=16f6cc268d1d0387]*/ + HANDLE handle, Py_buffer *bufobj) +/*[clinic end generated code: output=8754744506023071 input=4f037ba09939e32d]*/ { if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; } - if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) - return NULL; - #if SIZEOF_SIZE_T > SIZEOF_LONG - if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { - PyBuffer_Release(&self->user_buffer); + if (bufobj->len > (Py_ssize_t)ULONG_MAX) { PyErr_SetString(PyExc_ValueError, "buffer too large"); return NULL; } #endif + steal_buffer(&self->user_buffer, bufobj); self->type = TYPE_READINTO; self->handle = handle; @@ -1142,7 +1148,7 @@ _overlapped_Overlapped_WSARecv_impl(OverlappedObject *self, HANDLE handle, _overlapped.Overlapped.WSARecvInto handle: HANDLE - buf as bufobj: object + buf as bufobj: Py_buffer flags: DWORD / @@ -1151,25 +1157,22 @@ Start overlapped receive. static PyObject * _overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self, - HANDLE handle, PyObject *bufobj, + HANDLE handle, Py_buffer *bufobj, DWORD flags) -/*[clinic end generated code: output=9a438abc436fe87c input=4f87c38fc381d525]*/ +/*[clinic end generated code: output=59ae7688786cf86b input=73e7fa00db633edd]*/ { if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; } - if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) - return NULL; - #if SIZEOF_SIZE_T > SIZEOF_LONG - if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { - PyBuffer_Release(&self->user_buffer); + if (bufobj->len > (Py_ssize_t)ULONG_MAX) { PyErr_SetString(PyExc_ValueError, "buffer too large"); return NULL; } #endif + steal_buffer(&self->user_buffer, bufobj); self->type = TYPE_READINTO; self->handle = handle; @@ -1182,7 +1185,7 @@ _overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self, _overlapped.Overlapped.WriteFile handle: HANDLE - buf as bufobj: object + buf as bufobj: Py_buffer / Start overlapped write. @@ -1190,8 +1193,8 @@ Start overlapped write. static PyObject * _overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle, - PyObject *bufobj) -/*[clinic end generated code: output=c376230b6120d877 input=b8d9a7608d8a1e72]*/ + Py_buffer *bufobj) +/*[clinic end generated code: output=fa5d5880a1bf04b1 input=ac54424c362abfc1]*/ { DWORD written; BOOL ret; @@ -1202,16 +1205,13 @@ _overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle, return NULL; } - if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) - return NULL; - #if SIZEOF_SIZE_T > SIZEOF_LONG - if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { - PyBuffer_Release(&self->user_buffer); + if (bufobj->len > (Py_ssize_t)ULONG_MAX) { PyErr_SetString(PyExc_ValueError, "buffer too large"); return NULL; } #endif + steal_buffer(&self->user_buffer, bufobj); self->type = TYPE_WRITE; self->handle = handle; @@ -1237,7 +1237,7 @@ _overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle, _overlapped.Overlapped.WSASend handle: HANDLE - buf as bufobj: object + buf as bufobj: Py_buffer flags: DWORD / @@ -1246,8 +1246,8 @@ Start overlapped send. static PyObject * _overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle, - PyObject *bufobj, DWORD flags) -/*[clinic end generated code: output=316031c7467040cc input=932e7cba6d18f708]*/ + Py_buffer *bufobj, DWORD flags) +/*[clinic end generated code: output=3baaa6e1f7fe229e input=c4167420ba2f93d8]*/ { DWORD written; WSABUF wsabuf; @@ -1259,16 +1259,13 @@ _overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle, return NULL; } - if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) - return NULL; - #if SIZEOF_SIZE_T > SIZEOF_LONG - if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { - PyBuffer_Release(&self->user_buffer); + if (bufobj->len > (Py_ssize_t)ULONG_MAX) { PyErr_SetString(PyExc_ValueError, "buffer too large"); return NULL; } #endif + steal_buffer(&self->user_buffer, bufobj); self->type = TYPE_WRITE; self->handle = handle; @@ -1668,8 +1665,8 @@ Overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg) break; case TYPE_READ_FROM_INTO: Py_VISIT(self->read_from_into.result); - if (self->read_from_into.user_buffer->obj) { - Py_VISIT(&self->read_from_into.user_buffer->obj); + if (self->read_from_into.user_buffer.obj) { + Py_VISIT(&self->read_from_into.user_buffer.obj); } break; } @@ -1728,7 +1725,7 @@ _overlapped_WSAConnect_impl(PyObject *module, HANDLE ConnectSocket, _overlapped.Overlapped.WSASendTo handle: HANDLE - buf as bufobj: object + buf as bufobj: Py_buffer flags: DWORD address_as_bytes as AddressObj: object / @@ -1738,9 +1735,9 @@ Start overlapped sendto over a connectionless (UDP) socket. static PyObject * _overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle, - PyObject *bufobj, DWORD flags, + Py_buffer *bufobj, DWORD flags, PyObject *AddressObj) -/*[clinic end generated code: output=fe0ff55eb60d65e1 input=f709e6ecebd9bc18]*/ +/*[clinic end generated code: output=3cdedc4cfaeb70cd input=b7c1749a62e2e374]*/ { char AddressBuf[sizeof(struct sockaddr_in6)]; SOCKADDR *Address = (SOCKADDR*)AddressBuf; @@ -1762,17 +1759,13 @@ _overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle, return NULL; } - if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) { - return NULL; - } - #if SIZEOF_SIZE_T > SIZEOF_LONG - if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { - PyBuffer_Release(&self->user_buffer); + if (bufobj->len > (Py_ssize_t)ULONG_MAX) { PyErr_SetString(PyExc_ValueError, "buffer too large"); return NULL; } #endif + steal_buffer(&self->user_buffer, bufobj); self->type = TYPE_WRITE_TO; self->handle = handle; @@ -1912,7 +1905,7 @@ _overlapped_Overlapped_WSARecvFromInto_impl(OverlappedObject *self, self->type = TYPE_READ_FROM_INTO; self->handle = handle; - self->read_from_into.user_buffer = bufobj; + steal_buffer(&self->read_from_into.user_buffer, bufobj); memset(&self->read_from_into.address, 0, sizeof(self->read_from_into.address)); self->read_from_into.address_length = sizeof(self->read_from_into.address); From webhook-mailer at python.org Sun Mar 13 17:29:54 2022 From: webhook-mailer at python.org (jaraco) Date: Sun, 13 Mar 2022 21:29:54 -0000 Subject: [Python-checkins] [3.10] bpo-47004: Sync with importlib_metadata 4.11.3. (GH-31854). (GH-31857) Message-ID: https://github.com/python/cpython/commit/d929aa70e2a324ea48fed221c3257f929be05115 commit: d929aa70e2a324ea48fed221c3257f929be05115 branch: 3.10 author: Jason R. Coombs committer: jaraco date: 2022-03-13T17:29:50-04:00 summary: [3.10] bpo-47004: Sync with importlib_metadata 4.11.3. (GH-31854). (GH-31857) (cherry picked from commit b1e286860742e7ba6fadc75e3ddb6c2899a56919) Co-authored-by: Jason R. Coombs files: A Misc/NEWS.d/next/Library/2022-03-13-15-04-05.bpo-47004.SyYpxd.rst M Doc/library/importlib.metadata.rst M Lib/importlib/metadata/__init__.py M Lib/test/test_importlib/test_metadata_api.py diff --git a/Doc/library/importlib.metadata.rst b/Doc/library/importlib.metadata.rst index 50fc904535b09..a6caa994497ba 100644 --- a/Doc/library/importlib.metadata.rst +++ b/Doc/library/importlib.metadata.rst @@ -264,6 +264,7 @@ Python packages or modules:: .. versionadded:: 3.10 +.. _distributions: Distributions ============= diff --git a/Lib/importlib/metadata/__init__.py b/Lib/importlib/metadata/__init__.py index c7462f31c7a0f..b3063cd991556 100644 --- a/Lib/importlib/metadata/__init__.py +++ b/Lib/importlib/metadata/__init__.py @@ -128,6 +128,15 @@ class EntryPoint( See `the packaging docs on entry points `_ for more information. + + >>> ep = EntryPoint( + ... name=None, group=None, value='package.module:attr [extra1, extra2]') + >>> ep.module + 'package.module' + >>> ep.attr + 'attr' + >>> ep.extras + ['extra1', 'extra2'] """ pattern = re.compile( @@ -176,7 +185,7 @@ def attr(self): @property def extras(self): match = self.pattern.match(self.value) - return list(re.finditer(r'\w+', match.group('extras') or '')) + return re.findall(r'\w+', match.group('extras') or '') def _for(self, dist): self.dist = dist @@ -200,6 +209,25 @@ def __reduce__(self): ) def matches(self, **params): + """ + EntryPoint matches the given parameters. + + >>> ep = EntryPoint(group='foo', name='bar', value='bing:bong [extra1, extra2]') + >>> ep.matches(group='foo') + True + >>> ep.matches(name='bar', value='bing:bong [extra1, extra2]') + True + >>> ep.matches(group='foo', name='other') + False + >>> ep.matches() + True + >>> ep.matches(extras=['extra1', 'extra2']) + True + >>> ep.matches(module='bing') + True + >>> ep.matches(attr='bong') + True + """ attrs = (getattr(self, param) for param in params) return all(map(operator.eq, params.values(), attrs)) @@ -650,7 +678,7 @@ def _read_dist_info_reqs(self): def _read_egg_info_reqs(self): source = self.read_text('requires.txt') - return source and self._deps_from_requires_text(source) + return None if source is None else self._deps_from_requires_text(source) @classmethod def _deps_from_requires_text(cls, source): @@ -752,7 +780,6 @@ def __new__(cls, root): def __init__(self, root): self.root = root - self.base = os.path.basename(self.root).lower() def joinpath(self, child): return pathlib.Path(self.root, child) diff --git a/Lib/test/test_importlib/test_metadata_api.py b/Lib/test/test_importlib/test_metadata_api.py index 0890d6cb72e88..799f007081fc5 100644 --- a/Lib/test/test_importlib/test_metadata_api.py +++ b/Lib/test/test_importlib/test_metadata_api.py @@ -222,6 +222,16 @@ def test_requires_egg_info(self): assert len(deps) == 2 assert any(dep == 'wheel >= 1.0; python_version >= "2.7"' for dep in deps) + def test_requires_egg_info_empty(self): + fixtures.build_files( + { + 'requires.txt': '', + }, + self.site_dir.joinpath('egginfo_pkg.egg-info'), + ) + deps = requires('egginfo-pkg') + assert deps == [] + def test_requires_dist_info(self): deps = requires('distinfo-pkg') assert len(deps) == 2 diff --git a/Misc/NEWS.d/next/Library/2022-03-13-15-04-05.bpo-47004.SyYpxd.rst b/Misc/NEWS.d/next/Library/2022-03-13-15-04-05.bpo-47004.SyYpxd.rst new file mode 100644 index 0000000000000..3cb3b212d89e9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-13-15-04-05.bpo-47004.SyYpxd.rst @@ -0,0 +1,3 @@ +Apply bugfixes from importlib_metadata 4.11.3, including bugfix for +EntryPoint.extras, which was returning match objects and not the extras +strings. From webhook-mailer at python.org Sun Mar 13 17:30:12 2022 From: webhook-mailer at python.org (jaraco) Date: Sun, 13 Mar 2022 21:30:12 -0000 Subject: [Python-checkins] [3.9] bpo-47004: Sync with importlib_metadata 4.11.3. (GH-31854). (GH-31859) Message-ID: https://github.com/python/cpython/commit/177be52517da9a876a3f9e670f88c4731b906986 commit: 177be52517da9a876a3f9e670f88c4731b906986 branch: 3.9 author: Jason R. Coombs committer: jaraco date: 2022-03-13T17:30:07-04:00 summary: [3.9] bpo-47004: Sync with importlib_metadata 4.11.3. (GH-31854). (GH-31859) (cherry picked from commit b1e286860742e7ba6fadc75e3ddb6c2899a56919) Co-authored-by: Jason R. Coombs files: A Misc/NEWS.d/next/Library/2022-03-13-15-04-05.bpo-47004.SyYpxd.rst M Doc/library/importlib.metadata.rst M Lib/importlib/metadata.py M Lib/test/test_importlib/test_metadata_api.py diff --git a/Doc/library/importlib.metadata.rst b/Doc/library/importlib.metadata.rst index 1f73017e05ced..7652d501d9d91 100644 --- a/Doc/library/importlib.metadata.rst +++ b/Doc/library/importlib.metadata.rst @@ -199,6 +199,8 @@ function:: ["pytest (>=3.0.0) ; extra == 'test'", "pytest-cov ; extra == 'test'"] +.. _distributions: + Distributions ============= diff --git a/Lib/importlib/metadata.py b/Lib/importlib/metadata.py index 7b8038fd63a84..647fd3e4dbf8b 100644 --- a/Lib/importlib/metadata.py +++ b/Lib/importlib/metadata.py @@ -45,6 +45,15 @@ class EntryPoint( See `the packaging docs on entry points `_ for more information. + + >>> ep = EntryPoint( + ... name=None, group=None, value='package.module:attr [extra1, extra2]') + >>> ep.module + 'package.module' + >>> ep.attr + 'attr' + >>> ep.extras + ['extra1', 'extra2'] """ pattern = re.compile( @@ -91,7 +100,7 @@ def attr(self): @property def extras(self): match = self.pattern.match(self.value) - return list(re.finditer(r'\w+', match.group('extras') or '')) + return re.findall(r'\w+', match.group('extras') or '') @classmethod def _from_config(cls, config): @@ -308,7 +317,7 @@ def _read_dist_info_reqs(self): def _read_egg_info_reqs(self): source = self.read_text('requires.txt') - return source and self._deps_from_requires_text(source) + return None if source is None else self._deps_from_requires_text(source) @classmethod def _deps_from_requires_text(cls, source): diff --git a/Lib/test/test_importlib/test_metadata_api.py b/Lib/test/test_importlib/test_metadata_api.py index 420fbfeb3a704..cba920ab02c87 100644 --- a/Lib/test/test_importlib/test_metadata_api.py +++ b/Lib/test/test_importlib/test_metadata_api.py @@ -104,6 +104,16 @@ def test_requires_egg_info(self): for dep in deps ) + def test_requires_egg_info_empty(self): + fixtures.build_files( + { + 'requires.txt': '', + }, + self.site_dir.joinpath('egginfo_pkg.egg-info'), + ) + deps = requires('egginfo-pkg') + assert deps == [] + def test_requires_dist_info(self): deps = requires('distinfo-pkg') assert len(deps) == 2 diff --git a/Misc/NEWS.d/next/Library/2022-03-13-15-04-05.bpo-47004.SyYpxd.rst b/Misc/NEWS.d/next/Library/2022-03-13-15-04-05.bpo-47004.SyYpxd.rst new file mode 100644 index 0000000000000..3cb3b212d89e9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-13-15-04-05.bpo-47004.SyYpxd.rst @@ -0,0 +1,3 @@ +Apply bugfixes from importlib_metadata 4.11.3, including bugfix for +EntryPoint.extras, which was returning match objects and not the extras +strings. From webhook-mailer at python.org Sun Mar 13 17:40:04 2022 From: webhook-mailer at python.org (ned-deily) Date: Sun, 13 Mar 2022 21:40:04 -0000 Subject: [Python-checkins] bpo-46986: Upgrade bundled setuptools to 60.9.3 (GH-31820) (GH-31861) Message-ID: https://github.com/python/cpython/commit/0fbab8a593dcd94cfc788700dd9bf67a73f85920 commit: 0fbab8a593dcd94cfc788700dd9bf67a73f85920 branch: 3.7 author: Ned Deily committer: ned-deily date: 2022-03-13T17:39:58-04:00 summary: bpo-46986: Upgrade bundled setuptools to 60.9.3 (GH-31820) (GH-31861) (cherry picked from commit c99ac3c364ee21be72263791b71ee8b55f64de08) Co-authored-by: Pradyun Gedam files: A Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl A Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst D Lib/ensurepip/_bundled/setuptools-47.1.0-py3-none-any.whl M Lib/ensurepip/__init__.py diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index 8289c495d3689..3d88dec2cdf4b 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -8,7 +8,7 @@ __all__ = ["version", "bootstrap"] _PACKAGE_NAMES = ('setuptools', 'pip') -_SETUPTOOLS_VERSION = "47.1.0" +_SETUPTOOLS_VERSION = "60.9.3" _PIP_VERSION = "22.0.4" _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION, "py3"), diff --git a/Lib/ensurepip/_bundled/setuptools-47.1.0-py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-47.1.0-py3-none-any.whl deleted file mode 100644 index f87867ff98254..0000000000000 Binary files a/Lib/ensurepip/_bundled/setuptools-47.1.0-py3-none-any.whl and /dev/null differ diff --git a/Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl new file mode 100644 index 0000000000000..b88ddc659ee10 Binary files /dev/null and b/Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl differ diff --git a/Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst b/Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst new file mode 100644 index 0000000000000..06dd1271902d1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst @@ -0,0 +1 @@ +Upgrade setuptools wheel bundled with ensurepip (setuptools 60.9.3) From webhook-mailer at python.org Sun Mar 13 21:24:07 2022 From: webhook-mailer at python.org (methane) Date: Mon, 14 Mar 2022 01:24:07 -0000 Subject: [Python-checkins] bpo-39829: Fix `__len__()` is called twice in list() constructor (GH-31816) Message-ID: https://github.com/python/cpython/commit/2153daf0a02a598ed5df93f2f224c1ab2a2cca0d commit: 2153daf0a02a598ed5df93f2f224c1ab2a2cca0d branch: main author: Crowthebird <78076854+thatbirdguythatuknownot at users.noreply.github.com> committer: methane date: 2022-03-14T10:23:59+09:00 summary: bpo-39829: Fix `__len__()` is called twice in list() constructor (GH-31816) files: A Misc/NEWS.d/next/Core and Builtins/2022-03-11-09-39-01.bpo-39829.mlW3Su.rst M Misc/ACKS M Objects/listobject.c diff --git a/Misc/ACKS b/Misc/ACKS index 84fcb322d4086..00194f40f074a 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1336,6 +1336,7 @@ William Park Claude Paroz Heikki Partanen Harri Pasanen +Jeremiah Gabriel Pascual Ga?l Pasgrimaud Feanil Patel Ashish Nitin Patil @@ -1864,7 +1865,6 @@ Kurt Vile Norman Vine Pauli Virtanen Frank Visser -Jeremiah Vivian (Pascual) Johannes Vogel Michael Vogt Radu Voicilas diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-11-09-39-01.bpo-39829.mlW3Su.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-11-09-39-01.bpo-39829.mlW3Su.rst new file mode 100644 index 0000000000000..1f3d945188a32 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-11-09-39-01.bpo-39829.mlW3Su.rst @@ -0,0 +1 @@ +Removed the ``__len__()`` call when initializing a list and moved initializing to ``list_extend``. Patch by Jeremiah Pascual. diff --git a/Objects/listobject.c b/Objects/listobject.c index 783ae88a17f3b..d50633d2b3132 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -865,7 +865,6 @@ list_extend(PyListObject *self, PyObject *iterable) PyObject *it; /* iter(v) */ Py_ssize_t m; /* size of self */ Py_ssize_t n; /* guess for size of iterable */ - Py_ssize_t mn; /* m + n */ Py_ssize_t i; PyObject *(*iternext)(PyObject *); @@ -889,7 +888,13 @@ list_extend(PyListObject *self, PyObject *iterable) /* It should not be possible to allocate a list large enough to cause an overflow on any relevant platform */ assert(m < PY_SSIZE_T_MAX - n); - if (list_resize(self, m + n) < 0) { + if (self->ob_item == NULL) { + if (list_preallocate_exact(self, n) < 0) { + return NULL; + } + Py_SET_SIZE(self, n); + } + else if (list_resize(self, m + n) < 0) { Py_DECREF(iterable); return NULL; } @@ -928,10 +933,13 @@ list_extend(PyListObject *self, PyObject *iterable) * eventually run out of memory during the loop. */ } + else if (self->ob_item == NULL) { + if (n && list_preallocate_exact(self, n) < 0) + goto error; + } else { - mn = m + n; /* Make room. */ - if (list_resize(self, mn) < 0) + if (list_resize(self, m + n) < 0) goto error; /* Make the list sane again. */ Py_SET_SIZE(self, m); @@ -2814,19 +2822,6 @@ list___init___impl(PyListObject *self, PyObject *iterable) (void)_list_clear(self); } if (iterable != NULL) { - if (_PyObject_HasLen(iterable)) { - Py_ssize_t iter_len = PyObject_Size(iterable); - if (iter_len == -1) { - if (!PyErr_ExceptionMatches(PyExc_TypeError)) { - return -1; - } - PyErr_Clear(); - } - if (iter_len > 0 && self->ob_item == NULL - && list_preallocate_exact(self, iter_len)) { - return -1; - } - } PyObject *rv = list_extend(self, iterable); if (rv == NULL) return -1; From webhook-mailer at python.org Mon Mar 14 07:54:34 2022 From: webhook-mailer at python.org (asvetlov) Date: Mon, 14 Mar 2022 11:54:34 -0000 Subject: [Python-checkins] bpo-46994: Accept explicit contextvars.Context in asyncio create_task() API (GH-31837) Message-ID: https://github.com/python/cpython/commit/9523c0d84f351a610dc651b234461eb015fa3b82 commit: 9523c0d84f351a610dc651b234461eb015fa3b82 branch: main author: Andrew Svetlov committer: asvetlov date: 2022-03-14T13:54:13+02:00 summary: bpo-46994: Accept explicit contextvars.Context in asyncio create_task() API (GH-31837) files: A Misc/NEWS.d/next/Library/2022-03-12-12-34-13.bpo-46994.d7hPdz.rst M Doc/library/asyncio-eventloop.rst M Doc/library/asyncio-task.rst M Lib/asyncio/base_events.py M Lib/asyncio/events.py M Lib/asyncio/taskgroups.py M Lib/asyncio/tasks.py M Lib/test/test_asyncio/test_taskgroups.py M Lib/test/test_asyncio/test_tasks.py M Lib/unittest/async_case.py M Lib/unittest/test/test_async_case.py M Modules/_asynciomodule.c M Modules/clinic/_asynciomodule.c.h diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index 4776853b5a56d..4f0f8c06fee78 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -330,7 +330,7 @@ Creating Futures and Tasks .. versionadded:: 3.5.2 -.. method:: loop.create_task(coro, *, name=None) +.. method:: loop.create_task(coro, *, name=None, context=None) Schedule the execution of a :ref:`coroutine`. Return a :class:`Task` object. @@ -342,9 +342,16 @@ Creating Futures and Tasks If the *name* argument is provided and not ``None``, it is set as the name of the task using :meth:`Task.set_name`. + An optional keyword-only *context* argument allows specifying a + custom :class:`contextvars.Context` for the *coro* to run in. + The current context copy is created when no *context* is provided. + .. versionchanged:: 3.8 Added the *name* parameter. + .. versionchanged:: 3.11 + Added the *context* parameter. + .. method:: loop.set_task_factory(factory) Set a task factory that will be used by @@ -352,7 +359,7 @@ Creating Futures and Tasks If *factory* is ``None`` the default task factory will be set. Otherwise, *factory* must be a *callable* with the signature matching - ``(loop, coro)``, where *loop* is a reference to the active + ``(loop, coro, context=None)``, where *loop* is a reference to the active event loop, and *coro* is a coroutine object. The callable must return a :class:`asyncio.Future`-compatible object. diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index b30b2894277a2..faf5910124f9b 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -244,7 +244,7 @@ Running an asyncio Program Creating Tasks ============== -.. function:: create_task(coro, *, name=None) +.. function:: create_task(coro, *, name=None, context=None) Wrap the *coro* :ref:`coroutine ` into a :class:`Task` and schedule its execution. Return the Task object. @@ -252,6 +252,10 @@ Creating Tasks If *name* is not ``None``, it is set as the name of the task using :meth:`Task.set_name`. + An optional keyword-only *context* argument allows specifying a + custom :class:`contextvars.Context` for the *coro* to run in. + The current context copy is created when no *context* is provided. + The task is executed in the loop returned by :func:`get_running_loop`, :exc:`RuntimeError` is raised if there is no running loop in current thread. @@ -281,6 +285,9 @@ Creating Tasks .. versionchanged:: 3.8 Added the *name* parameter. + .. versionchanged:: 3.11 + Added the *context* parameter. + Sleeping ======== diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 51c4e664d74e9..5eea1658df8f6 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -426,18 +426,23 @@ def create_future(self): """Create a Future object attached to the loop.""" return futures.Future(loop=self) - def create_task(self, coro, *, name=None): + def create_task(self, coro, *, name=None, context=None): """Schedule a coroutine object. Return a task object. """ self._check_closed() if self._task_factory is None: - task = tasks.Task(coro, loop=self, name=name) + task = tasks.Task(coro, loop=self, name=name, context=context) if task._source_traceback: del task._source_traceback[-1] else: - task = self._task_factory(self, coro) + if context is None: + # Use legacy API if context is not needed + task = self._task_factory(self, coro) + else: + task = self._task_factory(self, coro, context=context) + tasks._set_task_name(task, name) return task diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py index e682a192a887f..0d26ea545baa5 100644 --- a/Lib/asyncio/events.py +++ b/Lib/asyncio/events.py @@ -274,7 +274,7 @@ def create_future(self): # Method scheduling a coroutine object: create a task. - def create_task(self, coro, *, name=None): + def create_task(self, coro, *, name=None, context=None): raise NotImplementedError # Methods for interacting with threads. diff --git a/Lib/asyncio/taskgroups.py b/Lib/asyncio/taskgroups.py index c3ce94a4dd0a9..6af21f3a15d93 100644 --- a/Lib/asyncio/taskgroups.py +++ b/Lib/asyncio/taskgroups.py @@ -138,12 +138,15 @@ async def __aexit__(self, et, exc, tb): me = BaseExceptionGroup('unhandled errors in a TaskGroup', errors) raise me from None - def create_task(self, coro, *, name=None): + def create_task(self, coro, *, name=None, context=None): if not self._entered: raise RuntimeError(f"TaskGroup {self!r} has not been entered") if self._exiting and self._unfinished_tasks == 0: raise RuntimeError(f"TaskGroup {self!r} is finished") - task = self._loop.create_task(coro) + if context is None: + task = self._loop.create_task(coro) + else: + task = self._loop.create_task(coro, context=context) tasks._set_task_name(task, name) task.add_done_callback(self._on_task_done) self._unfinished_tasks += 1 diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index e604298e5efc0..b4f1eed91a932 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -93,7 +93,7 @@ class Task(futures._PyFuture): # Inherit Python Task implementation # status is still pending _log_destroy_pending = True - def __init__(self, coro, *, loop=None, name=None): + def __init__(self, coro, *, loop=None, name=None, context=None): super().__init__(loop=loop) if self._source_traceback: del self._source_traceback[-1] @@ -112,7 +112,10 @@ def __init__(self, coro, *, loop=None, name=None): self._must_cancel = False self._fut_waiter = None self._coro = coro - self._context = contextvars.copy_context() + if context is None: + self._context = contextvars.copy_context() + else: + self._context = context self._loop.call_soon(self.__step, context=self._context) _register_task(self) @@ -360,13 +363,18 @@ def __wakeup(self, future): Task = _CTask = _asyncio.Task -def create_task(coro, *, name=None): +def create_task(coro, *, name=None, context=None): """Schedule the execution of a coroutine object in a spawn task. Return a Task object. """ loop = events.get_running_loop() - task = loop.create_task(coro) + if context is None: + # Use legacy API if context is not needed + task = loop.create_task(coro) + else: + task = loop.create_task(coro, context=context) + _set_task_name(task, name) return task diff --git a/Lib/test/test_asyncio/test_taskgroups.py b/Lib/test/test_asyncio/test_taskgroups.py index df51528e10793..dea5d6de52420 100644 --- a/Lib/test/test_asyncio/test_taskgroups.py +++ b/Lib/test/test_asyncio/test_taskgroups.py @@ -2,6 +2,7 @@ import asyncio +import contextvars from asyncio import taskgroups import unittest @@ -708,6 +709,23 @@ async def coro(): t = g.create_task(coro(), name="yolo") self.assertEqual(t.get_name(), "yolo") + async def test_taskgroup_task_context(self): + cvar = contextvars.ContextVar('cvar') + + async def coro(val): + await asyncio.sleep(0) + cvar.set(val) + + async with taskgroups.TaskGroup() as g: + ctx = contextvars.copy_context() + self.assertIsNone(ctx.get(cvar)) + t1 = g.create_task(coro(1), context=ctx) + await t1 + self.assertEqual(1, ctx.get(cvar)) + t2 = g.create_task(coro(2), context=ctx) + await t2 + self.assertEqual(2, ctx.get(cvar)) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 95fabf728818b..b6ef62725166d 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -95,8 +95,8 @@ class BaseTaskTests: Task = None Future = None - def new_task(self, loop, coro, name='TestTask'): - return self.__class__.Task(coro, loop=loop, name=name) + def new_task(self, loop, coro, name='TestTask', context=None): + return self.__class__.Task(coro, loop=loop, name=name, context=context) def new_future(self, loop): return self.__class__.Future(loop=loop) @@ -2527,6 +2527,90 @@ async def main(): self.assertEqual(cvar.get(), -1) + def test_context_4(self): + cvar = contextvars.ContextVar('cvar') + + async def coro(val): + await asyncio.sleep(0) + cvar.set(val) + + async def main(): + ret = [] + ctx = contextvars.copy_context() + ret.append(ctx.get(cvar)) + t1 = self.new_task(loop, coro(1), context=ctx) + await t1 + ret.append(ctx.get(cvar)) + t2 = self.new_task(loop, coro(2), context=ctx) + await t2 + ret.append(ctx.get(cvar)) + return ret + + loop = asyncio.new_event_loop() + try: + task = self.new_task(loop, main()) + ret = loop.run_until_complete(task) + finally: + loop.close() + + self.assertEqual([None, 1, 2], ret) + + def test_context_5(self): + cvar = contextvars.ContextVar('cvar') + + async def coro(val): + await asyncio.sleep(0) + cvar.set(val) + + async def main(): + ret = [] + ctx = contextvars.copy_context() + ret.append(ctx.get(cvar)) + t1 = asyncio.create_task(coro(1), context=ctx) + await t1 + ret.append(ctx.get(cvar)) + t2 = asyncio.create_task(coro(2), context=ctx) + await t2 + ret.append(ctx.get(cvar)) + return ret + + loop = asyncio.new_event_loop() + try: + task = self.new_task(loop, main()) + ret = loop.run_until_complete(task) + finally: + loop.close() + + self.assertEqual([None, 1, 2], ret) + + def test_context_6(self): + cvar = contextvars.ContextVar('cvar') + + async def coro(val): + await asyncio.sleep(0) + cvar.set(val) + + async def main(): + ret = [] + ctx = contextvars.copy_context() + ret.append(ctx.get(cvar)) + t1 = loop.create_task(coro(1), context=ctx) + await t1 + ret.append(ctx.get(cvar)) + t2 = loop.create_task(coro(2), context=ctx) + await t2 + ret.append(ctx.get(cvar)) + return ret + + loop = asyncio.new_event_loop() + try: + task = loop.create_task(main()) + ret = loop.run_until_complete(task) + finally: + loop.close() + + self.assertEqual([None, 1, 2], ret) + def test_get_coro(self): loop = asyncio.new_event_loop() coro = coroutine_function() diff --git a/Lib/unittest/async_case.py b/Lib/unittest/async_case.py index 3c57bb5cda2c0..25adc3deff63d 100644 --- a/Lib/unittest/async_case.py +++ b/Lib/unittest/async_case.py @@ -1,4 +1,5 @@ import asyncio +import contextvars import inspect import warnings @@ -34,7 +35,7 @@ class IsolatedAsyncioTestCase(TestCase): def __init__(self, methodName='runTest'): super().__init__(methodName) self._asyncioTestLoop = None - self._asyncioCallsQueue = None + self._asyncioTestContext = contextvars.copy_context() async def asyncSetUp(self): pass @@ -58,7 +59,7 @@ def addAsyncCleanup(self, func, /, *args, **kwargs): self.addCleanup(*(func, *args), **kwargs) def _callSetUp(self): - self.setUp() + self._asyncioTestContext.run(self.setUp) self._callAsync(self.asyncSetUp) def _callTestMethod(self, method): @@ -68,47 +69,30 @@ def _callTestMethod(self, method): def _callTearDown(self): self._callAsync(self.asyncTearDown) - self.tearDown() + self._asyncioTestContext.run(self.tearDown) def _callCleanup(self, function, *args, **kwargs): self._callMaybeAsync(function, *args, **kwargs) def _callAsync(self, func, /, *args, **kwargs): assert self._asyncioTestLoop is not None, 'asyncio test loop is not initialized' - ret = func(*args, **kwargs) - assert inspect.isawaitable(ret), f'{func!r} returned non-awaitable' - fut = self._asyncioTestLoop.create_future() - self._asyncioCallsQueue.put_nowait((fut, ret)) - return self._asyncioTestLoop.run_until_complete(fut) + assert inspect.iscoroutinefunction(func), f'{func!r} is not an async function' + task = self._asyncioTestLoop.create_task( + func(*args, **kwargs), + context=self._asyncioTestContext, + ) + return self._asyncioTestLoop.run_until_complete(task) def _callMaybeAsync(self, func, /, *args, **kwargs): assert self._asyncioTestLoop is not None, 'asyncio test loop is not initialized' - ret = func(*args, **kwargs) - if inspect.isawaitable(ret): - fut = self._asyncioTestLoop.create_future() - self._asyncioCallsQueue.put_nowait((fut, ret)) - return self._asyncioTestLoop.run_until_complete(fut) + if inspect.iscoroutinefunction(func): + task = self._asyncioTestLoop.create_task( + func(*args, **kwargs), + context=self._asyncioTestContext, + ) + return self._asyncioTestLoop.run_until_complete(task) else: - return ret - - async def _asyncioLoopRunner(self, fut): - self._asyncioCallsQueue = queue = asyncio.Queue() - fut.set_result(None) - while True: - query = await queue.get() - queue.task_done() - if query is None: - return - fut, awaitable = query - try: - ret = await awaitable - if not fut.cancelled(): - fut.set_result(ret) - except (SystemExit, KeyboardInterrupt): - raise - except (BaseException, asyncio.CancelledError) as ex: - if not fut.cancelled(): - fut.set_exception(ex) + return self._asyncioTestContext.run(func, *args, **kwargs) def _setupAsyncioLoop(self): assert self._asyncioTestLoop is None, 'asyncio test loop already initialized' @@ -116,16 +100,11 @@ def _setupAsyncioLoop(self): asyncio.set_event_loop(loop) loop.set_debug(True) self._asyncioTestLoop = loop - fut = loop.create_future() - self._asyncioCallsTask = loop.create_task(self._asyncioLoopRunner(fut)) - loop.run_until_complete(fut) def _tearDownAsyncioLoop(self): assert self._asyncioTestLoop is not None, 'asyncio test loop is not initialized' loop = self._asyncioTestLoop self._asyncioTestLoop = None - self._asyncioCallsQueue.put_nowait(None) - loop.run_until_complete(self._asyncioCallsQueue.join()) try: # cancel all tasks diff --git a/Lib/unittest/test/test_async_case.py b/Lib/unittest/test/test_async_case.py index 3717486b26563..7dc8a6bffa019 100644 --- a/Lib/unittest/test/test_async_case.py +++ b/Lib/unittest/test/test_async_case.py @@ -1,4 +1,5 @@ import asyncio +import contextvars import unittest from test import support @@ -11,6 +12,9 @@ def tearDownModule(): asyncio.set_event_loop_policy(None) +VAR = contextvars.ContextVar('VAR', default=()) + + class TestAsyncCase(unittest.TestCase): maxDiff = None @@ -24,22 +28,26 @@ class Test(unittest.IsolatedAsyncioTestCase): def setUp(self): self.assertEqual(events, []) events.append('setUp') + VAR.set(VAR.get() + ('setUp',)) async def asyncSetUp(self): self.assertEqual(events, ['setUp']) events.append('asyncSetUp') + VAR.set(VAR.get() + ('asyncSetUp',)) self.addAsyncCleanup(self.on_cleanup1) async def test_func(self): self.assertEqual(events, ['setUp', 'asyncSetUp']) events.append('test') + VAR.set(VAR.get() + ('test',)) self.addAsyncCleanup(self.on_cleanup2) async def asyncTearDown(self): self.assertEqual(events, ['setUp', 'asyncSetUp', 'test']) + VAR.set(VAR.get() + ('asyncTearDown',)) events.append('asyncTearDown') def tearDown(self): @@ -48,6 +56,7 @@ def tearDown(self): 'test', 'asyncTearDown']) events.append('tearDown') + VAR.set(VAR.get() + ('tearDown',)) async def on_cleanup1(self): self.assertEqual(events, ['setUp', @@ -57,6 +66,9 @@ async def on_cleanup1(self): 'tearDown', 'cleanup2']) events.append('cleanup1') + VAR.set(VAR.get() + ('cleanup1',)) + nonlocal cvar + cvar = VAR.get() async def on_cleanup2(self): self.assertEqual(events, ['setUp', @@ -65,8 +77,10 @@ async def on_cleanup2(self): 'asyncTearDown', 'tearDown']) events.append('cleanup2') + VAR.set(VAR.get() + ('cleanup2',)) events = [] + cvar = () test = Test("test_func") result = test.run() self.assertEqual(result.errors, []) @@ -74,13 +88,17 @@ async def on_cleanup2(self): expected = ['setUp', 'asyncSetUp', 'test', 'asyncTearDown', 'tearDown', 'cleanup2', 'cleanup1'] self.assertEqual(events, expected) + self.assertEqual(cvar, tuple(expected)) events = [] + cvar = () test = Test("test_func") test.debug() self.assertEqual(events, expected) + self.assertEqual(cvar, tuple(expected)) test.doCleanups() self.assertEqual(events, expected) + self.assertEqual(cvar, tuple(expected)) def test_exception_in_setup(self): class Test(unittest.IsolatedAsyncioTestCase): diff --git a/Misc/NEWS.d/next/Library/2022-03-12-12-34-13.bpo-46994.d7hPdz.rst b/Misc/NEWS.d/next/Library/2022-03-12-12-34-13.bpo-46994.d7hPdz.rst new file mode 100644 index 0000000000000..765936f1efb59 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-12-12-34-13.bpo-46994.d7hPdz.rst @@ -0,0 +1,2 @@ +Accept explicit contextvars.Context in :func:`asyncio.create_task` and +:meth:`asyncio.loop.create_task`. diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 2a6c0b335ccfb..4b12744e625e1 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -2003,14 +2003,16 @@ _asyncio.Task.__init__ * loop: object = None name: object = None + context: object = None A coroutine wrapped in a Future. [clinic start generated code]*/ static int _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop, - PyObject *name) -/*[clinic end generated code: output=88b12b83d570df50 input=352a3137fe60091d]*/ + PyObject *name, PyObject *context) +/*[clinic end generated code: output=49ac96fe33d0e5c7 input=924522490c8ce825]*/ + { if (future_init((FutureObj*)self, loop)) { return -1; @@ -2028,9 +2030,13 @@ _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop, return -1; } - Py_XSETREF(self->task_context, PyContext_CopyCurrent()); - if (self->task_context == NULL) { - return -1; + if (context == Py_None) { + Py_XSETREF(self->task_context, PyContext_CopyCurrent()); + if (self->task_context == NULL) { + return -1; + } + } else { + self->task_context = Py_NewRef(context); } Py_CLEAR(self->task_fut_waiter); diff --git a/Modules/clinic/_asynciomodule.c.h b/Modules/clinic/_asynciomodule.c.h index 2b84ef0a477c7..4a90dfa67c22b 100644 --- a/Modules/clinic/_asynciomodule.c.h +++ b/Modules/clinic/_asynciomodule.c.h @@ -310,28 +310,29 @@ _asyncio_Future__repr_info(FutureObj *self, PyObject *Py_UNUSED(ignored)) } PyDoc_STRVAR(_asyncio_Task___init____doc__, -"Task(coro, *, loop=None, name=None)\n" +"Task(coro, *, loop=None, name=None, context=None)\n" "--\n" "\n" "A coroutine wrapped in a Future."); static int _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop, - PyObject *name); + PyObject *name, PyObject *context); static int _asyncio_Task___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - static const char * const _keywords[] = {"coro", "loop", "name", NULL}; + static const char * const _keywords[] = {"coro", "loop", "name", "context", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "Task", 0}; - PyObject *argsbuf[3]; + PyObject *argsbuf[4]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1; PyObject *coro; PyObject *loop = Py_None; PyObject *name = Py_None; + PyObject *context = Py_None; fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); if (!fastargs) { @@ -347,9 +348,15 @@ _asyncio_Task___init__(PyObject *self, PyObject *args, PyObject *kwargs) goto skip_optional_kwonly; } } - name = fastargs[2]; + if (fastargs[2]) { + name = fastargs[2]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + context = fastargs[3]; skip_optional_kwonly: - return_value = _asyncio_Task___init___impl((TaskObj *)self, coro, loop, name); + return_value = _asyncio_Task___init___impl((TaskObj *)self, coro, loop, name, context); exit: return return_value; @@ -917,4 +924,4 @@ _asyncio__leave_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, exit: return return_value; } -/*[clinic end generated code: output=344927e9b6016ad7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=540ed3caf5a4d57d input=a9049054013a1b77]*/ From webhook-mailer at python.org Mon Mar 14 08:48:09 2022 From: webhook-mailer at python.org (corona10) Date: Mon, 14 Mar 2022 12:48:09 -0000 Subject: [Python-checkins] bpo-46987: Remove _PySys_GetObjectId / _PySys_GetObjectId (GH-31835) Message-ID: https://github.com/python/cpython/commit/bb1c543f4a183f5cfdf15aad59f59094d50b37fd commit: bb1c543f4a183f5cfdf15aad59f59094d50b37fd branch: main author: Dong-hee Na committer: corona10 date: 2022-03-14T21:48:00+09:00 summary: bpo-46987: Remove _PySys_GetObjectId / _PySys_GetObjectId (GH-31835) files: A Misc/NEWS.d/next/C API/2022-03-12-18-37-06.bpo-46987.LWcwyN.rst M Include/cpython/sysmodule.h M Python/sysmodule.c diff --git a/Include/cpython/sysmodule.h b/Include/cpython/sysmodule.h index 27dff7b2e3d93..19d9dddc344a4 100644 --- a/Include/cpython/sysmodule.h +++ b/Include/cpython/sysmodule.h @@ -4,8 +4,6 @@ PyAPI_FUNC(PyObject *) _PySys_GetAttr(PyThreadState *tstate, PyObject *name); -PyAPI_FUNC(PyObject *) _PySys_GetObjectId(_Py_Identifier *key); -PyAPI_FUNC(int) _PySys_SetObjectId(_Py_Identifier *key, PyObject *); PyAPI_FUNC(size_t) _PySys_GetSizeOf(PyObject *); diff --git a/Misc/NEWS.d/next/C API/2022-03-12-18-37-06.bpo-46987.LWcwyN.rst b/Misc/NEWS.d/next/C API/2022-03-12-18-37-06.bpo-46987.LWcwyN.rst new file mode 100644 index 0000000000000..2c858afdf1f47 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2022-03-12-18-37-06.bpo-46987.LWcwyN.rst @@ -0,0 +1,2 @@ +Remove private functions ``_PySys_GetObjectId()`` and ``_PySys_SetObjectId()``. +Patch by Dong-hee Na. diff --git a/Python/sysmodule.c b/Python/sysmodule.c index a97d0341ddcfd..99540b09c1f46 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -72,29 +72,6 @@ _PySys_GetAttr(PyThreadState *tstate, PyObject *name) return value; } -static PyObject * -sys_get_object_id(PyThreadState *tstate, _Py_Identifier *key) -{ - PyObject *sd = tstate->interp->sysdict; - if (sd == NULL) { - return NULL; - } - PyObject *exc_type, *exc_value, *exc_tb; - _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); - PyObject *value = _PyDict_GetItemIdWithError(sd, key); - /* XXX Suppress a new exception if it was raised and restore - * the old one. */ - _PyErr_Restore(tstate, exc_type, exc_value, exc_tb); - return value; -} - -PyObject * -_PySys_GetObjectId(_Py_Identifier *key) -{ - PyThreadState *tstate = _PyThreadState_GET(); - return sys_get_object_id(tstate, key); -} - static PyObject * _PySys_GetObject(PyInterpreterState *interp, const char *name) { @@ -139,19 +116,6 @@ sys_set_object(PyInterpreterState *interp, PyObject *key, PyObject *v) } } -static int -sys_set_object_id(PyInterpreterState *interp, _Py_Identifier *key, PyObject *v) -{ - return sys_set_object(interp, _PyUnicode_FromId(key), v); -} - -int -_PySys_SetObjectId(_Py_Identifier *key, PyObject *v) -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - return sys_set_object_id(interp, key, v); -} - int _PySys_SetAttr(PyObject *key, PyObject *v) { From webhook-mailer at python.org Mon Mar 14 09:15:56 2022 From: webhook-mailer at python.org (asvetlov) Date: Mon, 14 Mar 2022 13:15:56 -0000 Subject: [Python-checkins] [3.9] bpo-43215: Document Happy Eyeballs args of asyncio.open_connection (GH-24525) (GH-31868) Message-ID: https://github.com/python/cpython/commit/649cc9d688f79765cf052429683b708678c26fbd commit: 649cc9d688f79765cf052429683b708678c26fbd branch: 3.9 author: Illia Volochii committer: asvetlov date: 2022-03-14T15:15:49+02:00 summary: [3.9] bpo-43215: Document Happy Eyeballs args of asyncio.open_connection (GH-24525) (GH-31868) Co-authored-by: Andrew Svetlov . (cherry picked from commit 3543ddb4c4ebc26fb2d6c67a97e66f5267876f72) Co-authored-by: Illia Volochii files: M Doc/library/asyncio-stream.rst diff --git a/Doc/library/asyncio-stream.rst b/Doc/library/asyncio-stream.rst index bf431cfb8a410..a960b26c8d800 100644 --- a/Doc/library/asyncio-stream.rst +++ b/Doc/library/asyncio-stream.rst @@ -51,7 +51,8 @@ and work with streams: .. coroutinefunction:: open_connection(host=None, port=None, *, \ loop=None, limit=None, ssl=None, family=0, \ proto=0, flags=0, sock=None, local_addr=None, \ - server_hostname=None, ssl_handshake_timeout=None) + server_hostname=None, ssl_handshake_timeout=None, \ + happy_eyeballs_delay=None, interleave=None) Establish a network connection and return a pair of ``(reader, writer)`` objects. @@ -73,6 +74,10 @@ and work with streams: The *ssl_handshake_timeout* parameter. + .. versionadded:: 3.8 + + Added *happy_eyeballs_delay* and *interleave* parameters. + .. coroutinefunction:: start_server(client_connected_cb, host=None, \ port=None, *, loop=None, limit=None, \ family=socket.AF_UNSPEC, \ From webhook-mailer at python.org Mon Mar 14 09:16:34 2022 From: webhook-mailer at python.org (asvetlov) Date: Mon, 14 Mar 2022 13:16:34 -0000 Subject: [Python-checkins] [3.10] bpo-43215: Document Happy Eyeballs args of asyncio.open_connection (GH-24525) (GH-31869) Message-ID: https://github.com/python/cpython/commit/c6828408342cb1a2f8ba5038adccfbc1a95250cc commit: c6828408342cb1a2f8ba5038adccfbc1a95250cc branch: 3.10 author: Illia Volochii committer: asvetlov date: 2022-03-14T15:16:29+02:00 summary: [3.10] bpo-43215: Document Happy Eyeballs args of asyncio.open_connection (GH-24525) (GH-31869) Co-authored-by: Andrew Svetlov (cherry picked from commit 3543ddb4c4ebc26fb2d6c67a97e66f5267876f72) Co-authored-by: Illia Volochii files: M Doc/library/asyncio-stream.rst diff --git a/Doc/library/asyncio-stream.rst b/Doc/library/asyncio-stream.rst index 269c3dc80c471..3558277920c70 100644 --- a/Doc/library/asyncio-stream.rst +++ b/Doc/library/asyncio-stream.rst @@ -51,7 +51,8 @@ and work with streams: .. coroutinefunction:: open_connection(host=None, port=None, *, \ limit=None, ssl=None, family=0, proto=0, \ flags=0, sock=None, local_addr=None, \ - server_hostname=None, ssl_handshake_timeout=None) + server_hostname=None, ssl_handshake_timeout=None, \ + happy_eyeballs_delay=None, interleave=None) Establish a network connection and return a pair of ``(reader, writer)`` objects. @@ -69,6 +70,9 @@ and work with streams: .. versionchanged:: 3.7 Added the *ssl_handshake_timeout* parameter. + .. versionadded:: 3.8 + Added *happy_eyeballs_delay* and *interleave* parameters. + .. versionchanged:: 3.10 Removed the *loop* parameter. From webhook-mailer at python.org Mon Mar 14 09:29:25 2022 From: webhook-mailer at python.org (asvetlov) Date: Mon, 14 Mar 2022 13:29:25 -0000 Subject: [Python-checkins] CI: Fix patchcheck (GH-31708) Message-ID: https://github.com/python/cpython/commit/23abae621f579014eb29d5c6621f031c8a1a4057 commit: 23abae621f579014eb29d5c6621f031c8a1a4057 branch: main author: Hugo van Kemenade committer: asvetlov date: 2022-03-14T15:28:57+02:00 summary: CI: Fix patchcheck (GH-31708) files: M .azure-pipelines/posix-steps.yml M Tools/scripts/patchcheck.py diff --git a/.azure-pipelines/posix-steps.yml b/.azure-pipelines/posix-steps.yml index 2a3680897302e..29b43e0934472 100644 --- a/.azure-pipelines/posix-steps.yml +++ b/.azure-pipelines/posix-steps.yml @@ -66,7 +66,9 @@ steps: COMMAND: make - ${{ if eq(parameters.patchcheck, 'true') }}: - - script: ./python Tools/scripts/patchcheck.py --ci true + - script: | + git fetch origin + ./python Tools/scripts/patchcheck.py --ci true displayName: 'Run patchcheck.py' condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest')) diff --git a/Tools/scripts/patchcheck.py b/Tools/scripts/patchcheck.py index 4cab66c8e97be..a324eafc52b2a 100755 --- a/Tools/scripts/patchcheck.py +++ b/Tools/scripts/patchcheck.py @@ -130,6 +130,8 @@ def changed_files(base_branch=None): with subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, cwd=SRCDIR) as st: + if st.wait() != 0: + sys.exit(f'error running {cmd}') for line in st.stdout: line = line.decode().rstrip() status_text, filename = line.split(maxsplit=1) From webhook-mailer at python.org Mon Mar 14 09:40:43 2022 From: webhook-mailer at python.org (tiran) Date: Mon, 14 Mar 2022 13:40:43 -0000 Subject: [Python-checkins] bpo-40280: select: Use NULL for empty fdset (GH-31865) Message-ID: https://github.com/python/cpython/commit/f00ced8396f2d7683e58b9d5ebbf5797992bf477 commit: f00ced8396f2d7683e58b9d5ebbf5797992bf477 branch: main author: Christian Heimes committer: tiran date: 2022-03-14T14:40:28+01:00 summary: bpo-40280: select: Use NULL for empty fdset (GH-31865) wasm32-emscripten does not support exceptfds and requires NULL. Python now passes NULL instead of a fdset pointer when the input list is empty. This works fine on all platforms and might even be a tiny bit faster. files: A Misc/NEWS.d/next/Library/2022-03-14-09-26-42.bpo-40280.2-k8TV.rst M Lib/test/test_select.py M Modules/selectmodule.c diff --git a/Lib/test/test_select.py b/Lib/test/test_select.py index cf32cf2f6a6f8..69421fd77558d 100644 --- a/Lib/test/test_select.py +++ b/Lib/test/test_select.py @@ -46,7 +46,7 @@ def test_returned_list_identity(self): self.assertIsNot(r, x) self.assertIsNot(w, x) - @unittest.skipUnless(hasattr(os, 'popen'), "need os.popen()") + @support.requires_fork() def test_select(self): code = textwrap.dedent(''' import time diff --git a/Misc/NEWS.d/next/Library/2022-03-14-09-26-42.bpo-40280.2-k8TV.rst b/Misc/NEWS.d/next/Library/2022-03-14-09-26-42.bpo-40280.2-k8TV.rst new file mode 100644 index 0000000000000..f27c968623ff5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-14-09-26-42.bpo-40280.2-k8TV.rst @@ -0,0 +1 @@ +:func:`select.select` now passes ``NULL`` to ``select`` for each empty fdset. diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 1a5a63249c7b8..5c36eaaedeb70 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -330,7 +330,12 @@ select_select_impl(PyObject *module, PyObject *rlist, PyObject *wlist, do { Py_BEGIN_ALLOW_THREADS errno = 0; - n = select(max, &ifdset, &ofdset, &efdset, tvp); + n = select( + max, + imax ? &ifdset : NULL, + omax ? &ofdset : NULL, + emax ? &efdset : NULL, + tvp); Py_END_ALLOW_THREADS if (errno != EINTR) From webhook-mailer at python.org Mon Mar 14 11:51:58 2022 From: webhook-mailer at python.org (vstinner) Date: Mon, 14 Mar 2022 15:51:58 -0000 Subject: [Python-checkins] bpo-46906: Mention native endian in PyFloat_Pack8() doc (GH-31866) Message-ID: https://github.com/python/cpython/commit/11c25b87aeed162d422bc18530fe9699f311e586 commit: 11c25b87aeed162d422bc18530fe9699f311e586 branch: main author: Victor Stinner committer: vstinner date: 2022-03-14T16:51:51+01:00 summary: bpo-46906: Mention native endian in PyFloat_Pack8() doc (GH-31866) files: M Doc/c-api/float.rst diff --git a/Doc/c-api/float.rst b/Doc/c-api/float.rst index fd81683452db2..b306caf74b7c8 100644 --- a/Doc/c-api/float.rst +++ b/Doc/c-api/float.rst @@ -109,7 +109,9 @@ Pack functions The pack routines write 2, 4 or 8 bytes, starting at *p*. *le* is an :c:type:`int` argument, non-zero if you want the bytes string in little-endian format (exponent last, at ``p+1``, ``p+3``, or ``p+6`` ``p+7``), zero if you -want big-endian format (exponent first, at *p*). +want big-endian format (exponent first, at *p*). The :c:data:`PY_BIG_ENDIAN` +constant can be used to use the native endian: it is equal to ``1`` on big +endian processor, or ``0`` on little endian processor. Return value: ``0`` if all is OK, ``-1`` if error (and an exception is set, most likely :exc:`OverflowError`). @@ -138,7 +140,9 @@ Unpack functions The unpack routines read 2, 4 or 8 bytes, starting at *p*. *le* is an :c:type:`int` argument, non-zero if the bytes string is in little-endian format (exponent last, at ``p+1``, ``p+3`` or ``p+6`` and ``p+7``), zero if big-endian -(exponent first, at *p*). +(exponent first, at *p*). The :c:data:`PY_BIG_ENDIAN` constant can be used to +use the native endian: it is equal to ``1`` on big endian processor, or ``0`` +on little endian processor. Return value: The unpacked double. On error, this is ``-1.0`` and :c:func:`PyErr_Occurred` is true (and an exception is set, most likely From webhook-mailer at python.org Mon Mar 14 12:02:50 2022 From: webhook-mailer at python.org (vstinner) Date: Mon, 14 Mar 2022 16:02:50 -0000 Subject: [Python-checkins] bpo-46920: Remove code that has no explainer why it was disabled (GH-31814) Message-ID: https://github.com/python/cpython/commit/e885ac3d5f2fd83617ab75a098aab269b7a446c3 commit: e885ac3d5f2fd83617ab75a098aab269b7a446c3 branch: main author: Oleg Iarygin committer: vstinner date: 2022-03-14T17:02:32+01:00 summary: bpo-46920: Remove code that has no explainer why it was disabled (GH-31814) files: M Modules/_ctypes/_ctypes.c M Objects/classobject.c diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 481de85fde3ad..9177225f3f929 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -1418,49 +1418,12 @@ static PyGetSetDef WCharArray_getsets[] = { }; /* - The next three functions copied from Python's typeobject.c. + The next function is copied from Python's typeobject.c. - They are used to attach methods, members, or getsets to a type *after* it + It is used to attach getsets to a type *after* it has been created: Arrays of characters have additional getsets to treat them as strings. */ -/* -static int -add_methods(PyTypeObject *type, PyMethodDef *meth) -{ - PyObject *dict = type->tp_dict; - for (; meth->ml_name != NULL; meth++) { - PyObject *descr; - descr = PyDescr_NewMethod(type, meth); - if (descr == NULL) - return -1; - if (PyDict_SetItemString(dict, meth->ml_name, descr) < 0) { - Py_DECREF(descr); - return -1; - } - Py_DECREF(descr); - } - return 0; -} - -static int -add_members(PyTypeObject *type, PyMemberDef *memb) -{ - PyObject *dict = type->tp_dict; - for (; memb->name != NULL; memb++) { - PyObject *descr; - descr = PyDescr_NewMember(type, memb); - if (descr == NULL) - return -1; - if (PyDict_SetItemString(dict, memb->name, descr) < 0) { - Py_DECREF(descr); - return -1; - } - Py_DECREF(descr); - } - return 0; -} -*/ static int add_getset(PyTypeObject *type, PyGetSetDef *gsp) diff --git a/Objects/classobject.c b/Objects/classobject.c index 3b1c25394f152..c75ba572b9624 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -516,22 +516,6 @@ instancemethod_repr(PyObject *self) return result; } -/* -static long -instancemethod_hash(PyObject *self) -{ - long x, y; - x = (long)self; - y = PyObject_Hash(PyInstanceMethod_GET_FUNCTION(self)); - if (y == -1) - return -1; - x = x ^ y; - if (x == -1) - x = -2; - return x; -} -*/ - PyDoc_STRVAR(instancemethod_doc, "instancemethod(function)\n\ \n\ @@ -569,7 +553,7 @@ PyTypeObject PyInstanceMethod_Type = { 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ - 0, /*(hashfunc)instancemethod_hash, tp_hash */ + 0, /* tp_hash */ instancemethod_call, /* tp_call */ 0, /* tp_str */ instancemethod_getattro, /* tp_getattro */ From webhook-mailer at python.org Mon Mar 14 12:03:31 2022 From: webhook-mailer at python.org (vstinner) Date: Mon, 14 Mar 2022 16:03:31 -0000 Subject: [Python-checkins] bpo-46920: Remove disabled debug code added decades ago and likely unnecessary (GH-31812) Message-ID: https://github.com/python/cpython/commit/a52f82baf246e2fbbc58fe03ef7a51f3cc9514e1 commit: a52f82baf246e2fbbc58fe03ef7a51f3cc9514e1 branch: main author: Oleg Iarygin committer: vstinner date: 2022-03-14T17:03:21+01:00 summary: bpo-46920: Remove disabled debug code added decades ago and likely unnecessary (GH-31812) files: M Objects/unicodeobject.c M Parser/pegen.c M Python/formatter_unicode.c diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 2261b9a031625..5dfe6e1e93f9f 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -13623,14 +13623,6 @@ unicode_zfill_impl(PyObject *self, Py_ssize_t width) return u; } -#if 0 -static PyObject * -unicode__decimal2ascii(PyObject *self) -{ - return PyUnicode_TransformDecimalAndSpaceToASCII(self); -} -#endif - PyDoc_STRVAR(startswith__doc__, "S.startswith(prefix[, start[, end]]) -> bool\n\ \n\ @@ -14216,11 +14208,6 @@ static PyMethodDef unicode_methods[] = { UNICODE___FORMAT___METHODDEF UNICODE_MAKETRANS_METHODDEF UNICODE_SIZEOF_METHODDEF -#if 0 - /* These methods are just used for debugging the implementation. */ - {"_decimal2ascii", (PyCFunction) unicode__decimal2ascii, METH_NOARGS}, -#endif - {"__getnewargs__", unicode_getnewargs, METH_NOARGS}, {NULL, NULL} }; diff --git a/Parser/pegen.c b/Parser/pegen.c index 95dc54dd6040f..143461d44a1a4 100644 --- a/Parser/pegen.c +++ b/Parser/pegen.c @@ -37,17 +37,6 @@ _PyPegen_byte_offset_to_character_offset(PyObject *line, Py_ssize_t col_offset) return size; } -#if 0 -static const char * -token_name(int type) -{ - if (0 <= type && type <= N_TOKENS) { - return _PyParser_TokenNames[type]; - } - return ""; -} -#endif - // Here, mark is the start of the node, while p->mark is the end. // If node==NULL, they should be the same. int diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c index 0c21301fb9ed4..a1e50e20c9d8c 100644 --- a/Python/formatter_unicode.c +++ b/Python/formatter_unicode.c @@ -137,24 +137,6 @@ typedef struct { Py_UCS4 type; } InternalFormatSpec; -#if 0 -/* Occasionally useful for debugging. Should normally be commented out. */ -static void -DEBUG_PRINT_FORMAT_SPEC(InternalFormatSpec *format) -{ - printf("internal format spec: fill_char %d\n", format->fill_char); - printf("internal format spec: align %d\n", format->align); - printf("internal format spec: alternate %d\n", format->alternate); - printf("internal format spec: sign %d\n", format->sign); - printf("internal format spec: width %zd\n", format->width); - printf("internal format spec: thousands_separators %d\n", - format->thousands_separators); - printf("internal format spec: precision %zd\n", format->precision); - printf("internal format spec: type %c\n", format->type); - printf("\n"); -} -#endif - /* ptr points to the start of the format_spec, end points just past its end. From webhook-mailer at python.org Mon Mar 14 12:04:27 2022 From: webhook-mailer at python.org (vstinner) Date: Mon, 14 Mar 2022 16:04:27 -0000 Subject: [Python-checkins] bpo-46920: Remove code that has explainers why it was disabled (GH-31813) Message-ID: https://github.com/python/cpython/commit/13b041222399152acb555337572bd1d571734984 commit: 13b041222399152acb555337572bd1d571734984 branch: main author: Oleg Iarygin committer: vstinner date: 2022-03-14T17:04:22+01:00 summary: bpo-46920: Remove code that has explainers why it was disabled (GH-31813) files: M Modules/_tkinter.c M Modules/sre_lib.h M Parser/tokenizer.c M Python/ceval.c diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index cbef9ce0066db..cd167fd81250e 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -3440,11 +3440,5 @@ PyInit__tkinter(void) return NULL; } -#if 0 - /* This was not a good idea; through bindings, - Tcl_Finalize() may invoke Python code but at that point the - interpreter and thread state have already been destroyed! */ - Py_AtExit(Tcl_Finalize); -#endif return m; } diff --git a/Modules/sre_lib.h b/Modules/sre_lib.h index 322f66fb4da6c..32469cd161cf3 100644 --- a/Modules/sre_lib.h +++ b/Modules/sre_lib.h @@ -333,34 +333,6 @@ SRE(count)(SRE_STATE* state, const SRE_CODE* pattern, Py_ssize_t maxcount) return ptr - (SRE_CHAR*) state->ptr; } -#if 0 /* not used in this release */ -LOCAL(int) -SRE(info)(SRE_STATE* state, const SRE_CODE* pattern) -{ - /* check if an SRE_OP_INFO block matches at the current position. - returns the number of SRE_CODE objects to skip if successful, 0 - if no match */ - - const SRE_CHAR* end = (const SRE_CHAR*) state->end; - const SRE_CHAR* ptr = (const SRE_CHAR*) state->ptr; - Py_ssize_t i; - - /* check minimal length */ - if (pattern[3] && end - ptr < pattern[3]) - return 0; - - /* check known prefix */ - if (pattern[2] & SRE_INFO_PREFIX && pattern[5] > 1) { - /* */ - for (i = 0; i < pattern[5]; i++) - if ((SRE_CODE) ptr[i] != pattern[7 + i]) - return 0; - return pattern[0] + 2 * pattern[6]; - } - return pattern[0]; -} -#endif - /* The macros below should be used to protect recursive SRE(match)() * calls that *failed* and do *not* return immediately (IOW, those * that will backtrack). Explaining: diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c index 6698d35ea9427..90dc8a2e36971 100644 --- a/Parser/tokenizer.c +++ b/Parser/tokenizer.c @@ -282,30 +282,6 @@ check_bom(int get_char(struct tok_state *), unget_char(ch1, tok); return 1; } -#if 0 - /* Disable support for UTF-16 BOMs until a decision - is made whether this needs to be supported. */ - } else if (ch1 == 0xFE) { - ch2 = get_char(tok); - if (ch2 != 0xFF) { - unget_char(ch2, tok); - unget_char(ch1, tok); - return 1; - } - if (!set_readline(tok, "utf-16-be")) - return 0; - tok->decoding_state = STATE_NORMAL; - } else if (ch1 == 0xFF) { - ch2 = get_char(tok); - if (ch2 != 0xFE) { - unget_char(ch2, tok); - unget_char(ch1, tok); - return 1; - } - if (!set_readline(tok, "utf-16-le")) - return 0; - tok->decoding_state = STATE_NORMAL; -#endif } else { unget_char(ch1, tok); return 1; diff --git a/Python/ceval.c b/Python/ceval.c index f751479664219..adbf1f689d908 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -6997,12 +6997,6 @@ PyEval_MergeCompilerFlags(PyCompilerFlags *cf) result = 1; cf->cf_flags |= compilerflags; } -#if 0 /* future keyword */ - if (codeflags & CO_GENERATOR_ALLOWED) { - result = 1; - cf->cf_flags |= CO_GENERATOR_ALLOWED; - } -#endif } return result; } From webhook-mailer at python.org Mon Mar 14 13:40:00 2022 From: webhook-mailer at python.org (gvanrossum) Date: Mon, 14 Mar 2022 17:40:00 -0000 Subject: [Python-checkins] bpo-31415: importtime was made by Inada Naoki (GH-31875) Message-ID: https://github.com/python/cpython/commit/29624e769c5c3c1e59c6acc8b69383ead53e8a9f commit: 29624e769c5c3c1e59c6acc8b69383ead53e8a9f branch: main author: Victor Stinner committer: gvanrossum date: 2022-03-14T10:39:33-07:00 summary: bpo-31415: importtime was made by Inada Naoki (GH-31875) files: M Doc/whatsnew/3.7.rst diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index 1199535c84dca..dcbd0926bcada 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -538,7 +538,7 @@ Other Language Changes * The new :option:`-X` ``importtime`` option or the :envvar:`PYTHONPROFILEIMPORTTIME` environment variable can be used to show the timing of each module import. - (Contributed by Victor Stinner in :issue:`31415`.) + (Contributed by Inada Naoki in :issue:`31415`.) New Modules From webhook-mailer at python.org Mon Mar 14 14:53:51 2022 From: webhook-mailer at python.org (gvanrossum) Date: Mon, 14 Mar 2022 18:53:51 -0000 Subject: [Python-checkins] git ignore Lib/site-packages (GH-31862) Message-ID: https://github.com/python/cpython/commit/3dcc396219d8978e8e9b2c8821c286f87f1f92b1 commit: 3dcc396219d8978e8e9b2c8821c286f87f1f92b1 branch: main author: Dennis Sweeney <36520290+sweeneyde at users.noreply.github.com> committer: gvanrossum date: 2022-03-14T11:53:41-07:00 summary: git ignore Lib/site-packages (GH-31862) files: M .gitignore diff --git a/.gitignore b/.gitignore index 3c6adb4ab688c..b3b22f471c276 100644 --- a/.gitignore +++ b/.gitignore @@ -58,6 +58,8 @@ Doc/.env/ Include/pydtrace_probes.h Lib/distutils/command/*.pdb Lib/lib2to3/*.pickle +Lib/site-packages/* +!Lib/site-packages/README.txt Lib/test/data/* !Lib/test/data/README /_bootstrap_python From webhook-mailer at python.org Mon Mar 14 15:57:23 2022 From: webhook-mailer at python.org (iritkatriel) Date: Mon, 14 Mar 2022 19:57:23 -0000 Subject: [Python-checkins] bpo-30677: [doc] mention that os.mkdir() can raise FileNotFoundError (GH-31548) Message-ID: https://github.com/python/cpython/commit/879fbd9472753149b627f32add3ddca90ac47ab7 commit: 879fbd9472753149b627f32add3ddca90ac47ab7 branch: main author: slateny <46876382+slateny at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-03-14T19:57:10Z summary: bpo-30677: [doc] mention that os.mkdir() can raise FileNotFoundError (GH-31548) files: M Doc/library/os.rst diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 6dffc4513365e..05e0303614ed1 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -2050,7 +2050,8 @@ features: Create a directory named *path* with numeric mode *mode*. - If the directory already exists, :exc:`FileExistsError` is raised. + If the directory already exists, :exc:`FileExistsError` is raised. If a parent + directory in the path does not exist, :exc:`FileNotFoundError` is raised. .. _mkdir_modebits: From webhook-mailer at python.org Mon Mar 14 16:30:51 2022 From: webhook-mailer at python.org (ned-deily) Date: Mon, 14 Mar 2022 20:30:51 -0000 Subject: [Python-checkins] Revert "bpo-46986: Upgrade bundled setuptools to 60.9.3 (GH-31820)" (GH-31879) Message-ID: https://github.com/python/cpython/commit/19f69993ae97db0bbea3b845a33b060b73b658b3 commit: 19f69993ae97db0bbea3b845a33b060b73b658b3 branch: main author: Ned Deily committer: ned-deily date: 2022-03-14T16:30:46-04:00 summary: Revert "bpo-46986: Upgrade bundled setuptools to 60.9.3 (GH-31820)" (GH-31879) This reverts commit c99ac3c364ee21be72263791b71ee8b55f64de08 as it breaks test_bdb and test_distutils with installed Pythons. files: A Lib/ensurepip/_bundled/setuptools-58.1.0-py3-none-any.whl D Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl D Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst M Lib/ensurepip/__init__.py diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index d23fcad139874..a198a86e1f9af 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -10,7 +10,7 @@ __all__ = ["version", "bootstrap"] _PACKAGE_NAMES = ('setuptools', 'pip') -_SETUPTOOLS_VERSION = "60.9.3" +_SETUPTOOLS_VERSION = "58.1.0" _PIP_VERSION = "22.0.4" _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION, "py3"), diff --git a/Lib/ensurepip/_bundled/setuptools-58.1.0-py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-58.1.0-py3-none-any.whl new file mode 100644 index 0000000000000..18c8c22958f1f Binary files /dev/null and b/Lib/ensurepip/_bundled/setuptools-58.1.0-py3-none-any.whl differ diff --git a/Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl deleted file mode 100644 index b88ddc659ee10..0000000000000 Binary files a/Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl and /dev/null differ diff --git a/Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst b/Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst deleted file mode 100644 index 06dd1271902d1..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst +++ /dev/null @@ -1 +0,0 @@ -Upgrade setuptools wheel bundled with ensurepip (setuptools 60.9.3) From webhook-mailer at python.org Mon Mar 14 16:51:02 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 14 Mar 2022 20:51:02 -0000 Subject: [Python-checkins] [3.10] bpo-30677: [doc] mention that os.mkdir() can raise FileNotFoundError (GH-31548) (GH-31877) Message-ID: https://github.com/python/cpython/commit/efa72501599029d9ac3f8a2e5ce900302c7d8f56 commit: efa72501599029d9ac3f8a2e5ce900302c7d8f56 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-14T13:50:41-07:00 summary: [3.10] bpo-30677: [doc] mention that os.mkdir() can raise FileNotFoundError (GH-31548) (GH-31877) (cherry picked from commit 879fbd9472753149b627f32add3ddca90ac47ab7) Co-authored-by: slateny <46876382+slateny at users.noreply.github.com> Automerge-Triggered-By: GH:iritkatriel files: M Doc/library/os.rst diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 5b2c2e0d0f2d0..2a1ea05c5c833 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -2041,7 +2041,8 @@ features: Create a directory named *path* with numeric mode *mode*. - If the directory already exists, :exc:`FileExistsError` is raised. + If the directory already exists, :exc:`FileExistsError` is raised. If a parent + directory in the path does not exist, :exc:`FileNotFoundError` is raised. .. _mkdir_modebits: From webhook-mailer at python.org Mon Mar 14 16:52:17 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 14 Mar 2022 20:52:17 -0000 Subject: [Python-checkins] [3.9] bpo-30677: [doc] mention that os.mkdir() can raise FileNotFoundError (GH-31548) (GH-31878) Message-ID: https://github.com/python/cpython/commit/b4fd91b4d931dd97ceaf76750d227dd042c236f8 commit: b4fd91b4d931dd97ceaf76750d227dd042c236f8 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-14T13:52:07-07:00 summary: [3.9] bpo-30677: [doc] mention that os.mkdir() can raise FileNotFoundError (GH-31548) (GH-31878) (cherry picked from commit 879fbd9472753149b627f32add3ddca90ac47ab7) Co-authored-by: slateny <46876382+slateny at users.noreply.github.com> Automerge-Triggered-By: GH:iritkatriel files: M Doc/library/os.rst diff --git a/Doc/library/os.rst b/Doc/library/os.rst index d70f403e8cf1f..2f7b37019e4a4 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -1909,7 +1909,8 @@ features: Create a directory named *path* with numeric mode *mode*. - If the directory already exists, :exc:`FileExistsError` is raised. + If the directory already exists, :exc:`FileExistsError` is raised. If a parent + directory in the path does not exist, :exc:`FileNotFoundError` is raised. .. _mkdir_modebits: From webhook-mailer at python.org Mon Mar 14 17:01:21 2022 From: webhook-mailer at python.org (ned-deily) Date: Mon, 14 Mar 2022 21:01:21 -0000 Subject: [Python-checkins] Revert "bpo-46986: Upgrade bundled setuptools to 60.9.3 (GH-31820)" (GH-31882) Message-ID: https://github.com/python/cpython/commit/80cc10fa7d5f41daaf59ae9173022303f35a403c commit: 80cc10fa7d5f41daaf59ae9173022303f35a403c branch: 3.7 author: Ned Deily committer: ned-deily date: 2022-03-14T17:01:11-04:00 summary: Revert "bpo-46986: Upgrade bundled setuptools to 60.9.3 (GH-31820)" (GH-31882) This reverts commit 0fbab8a593dcd94cfc788700dd9bf67a73f85920 as it breaks test_bdb and test_distutils with installed Pythons. files: A Lib/ensurepip/_bundled/setuptools-47.1.0-py3-none-any.whl D Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl D Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst M Lib/ensurepip/__init__.py diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index 3d88dec2cdf4b..8289c495d3689 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -8,7 +8,7 @@ __all__ = ["version", "bootstrap"] _PACKAGE_NAMES = ('setuptools', 'pip') -_SETUPTOOLS_VERSION = "60.9.3" +_SETUPTOOLS_VERSION = "47.1.0" _PIP_VERSION = "22.0.4" _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION, "py3"), diff --git a/Lib/ensurepip/_bundled/setuptools-47.1.0-py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-47.1.0-py3-none-any.whl new file mode 100644 index 0000000000000..f87867ff98254 Binary files /dev/null and b/Lib/ensurepip/_bundled/setuptools-47.1.0-py3-none-any.whl differ diff --git a/Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl deleted file mode 100644 index b88ddc659ee10..0000000000000 Binary files a/Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl and /dev/null differ diff --git a/Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst b/Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst deleted file mode 100644 index 06dd1271902d1..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst +++ /dev/null @@ -1 +0,0 @@ -Upgrade setuptools wheel bundled with ensurepip (setuptools 60.9.3) From webhook-mailer at python.org Mon Mar 14 17:08:36 2022 From: webhook-mailer at python.org (ned-deily) Date: Mon, 14 Mar 2022 21:08:36 -0000 Subject: [Python-checkins] Revert "bpo-46986: Upgrade bundled setuptools to 60.9.3 (GH-31820)" (GH-31880) Message-ID: https://github.com/python/cpython/commit/0cfcc0cbee4a0d48c412169f46b7199728fb298a commit: 0cfcc0cbee4a0d48c412169f46b7199728fb298a branch: 3.10 author: Ned Deily committer: ned-deily date: 2022-03-14T17:08:28-04:00 summary: Revert "bpo-46986: Upgrade bundled setuptools to 60.9.3 (GH-31820)" (GH-31880) This reverts commit 25962e4e60235645f945d23281431b30b3c3d573 as it breaks test_bdb and test_distutils with installed Pythons. files: A Lib/ensurepip/_bundled/setuptools-58.1.0-py3-none-any.whl D Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl D Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst M Lib/ensurepip/__init__.py diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index 20a40456d5fe0..3fbe8b2a5b136 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -11,7 +11,7 @@ __all__ = ["version", "bootstrap"] _PACKAGE_NAMES = ('setuptools', 'pip') -_SETUPTOOLS_VERSION = "60.9.3" +_SETUPTOOLS_VERSION = "58.1.0" _PIP_VERSION = "22.0.4" _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION, "py3"), diff --git a/Lib/ensurepip/_bundled/setuptools-58.1.0-py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-58.1.0-py3-none-any.whl new file mode 100644 index 0000000000000..18c8c22958f1f Binary files /dev/null and b/Lib/ensurepip/_bundled/setuptools-58.1.0-py3-none-any.whl differ diff --git a/Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl deleted file mode 100644 index b88ddc659ee10..0000000000000 Binary files a/Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl and /dev/null differ diff --git a/Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst b/Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst deleted file mode 100644 index 06dd1271902d1..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst +++ /dev/null @@ -1 +0,0 @@ -Upgrade setuptools wheel bundled with ensurepip (setuptools 60.9.3) From webhook-mailer at python.org Mon Mar 14 17:10:25 2022 From: webhook-mailer at python.org (ned-deily) Date: Mon, 14 Mar 2022 21:10:25 -0000 Subject: [Python-checkins] Revert "bpo-46986: Upgrade bundled setuptools to 60.9.3 (GH-31820)" (GH-31881) Message-ID: https://github.com/python/cpython/commit/1b1239205d1b7ace1b054477c14fe77d54f471c4 commit: 1b1239205d1b7ace1b054477c14fe77d54f471c4 branch: 3.9 author: Ned Deily committer: ned-deily date: 2022-03-14T17:10:20-04:00 summary: Revert "bpo-46986: Upgrade bundled setuptools to 60.9.3 (GH-31820)" (GH-31881) This reverts commit bda64b3c0c4e45de4c82ba1b8722f56db5ac88ba as it breaks test_bdb and test_distutils with installed Pythons. files: A Lib/ensurepip/_bundled/setuptools-58.1.0-py3-none-any.whl D Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl D Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst M Lib/ensurepip/__init__.py diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index 0d76fc9b4aac2..e510cc7fb2baf 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -11,8 +11,7 @@ __all__ = ["version", "bootstrap"] -_PACKAGE_NAMES = ('setuptools', 'pip') -_SETUPTOOLS_VERSION = "60.9.3" +_SETUPTOOLS_VERSION = "58.1.0" _PIP_VERSION = "22.0.4" _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION, "py3"), diff --git a/Lib/ensurepip/_bundled/setuptools-58.1.0-py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-58.1.0-py3-none-any.whl new file mode 100644 index 0000000000000..18c8c22958f1f Binary files /dev/null and b/Lib/ensurepip/_bundled/setuptools-58.1.0-py3-none-any.whl differ diff --git a/Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl deleted file mode 100644 index b88ddc659ee10..0000000000000 Binary files a/Lib/ensurepip/_bundled/setuptools-60.9.3-py3-none-any.whl and /dev/null differ diff --git a/Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst b/Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst deleted file mode 100644 index 06dd1271902d1..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-11-13-54-27.bpo-46986.nF1meI.rst +++ /dev/null @@ -1 +0,0 @@ -Upgrade setuptools wheel bundled with ensurepip (setuptools 60.9.3) From webhook-mailer at python.org Mon Mar 14 17:24:54 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 14 Mar 2022 21:24:54 -0000 Subject: [Python-checkins] bpo-31415: importtime was made by Inada Naoki (GH-31875) Message-ID: https://github.com/python/cpython/commit/9f1587e8d3f18729a0982774c6c4409472cbd9e3 commit: 9f1587e8d3f18729a0982774c6c4409472cbd9e3 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-14T14:24:50-07:00 summary: bpo-31415: importtime was made by Inada Naoki (GH-31875) (cherry picked from commit 29624e769c5c3c1e59c6acc8b69383ead53e8a9f) Co-authored-by: Victor Stinner files: M Doc/whatsnew/3.7.rst diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index 1199535c84dca..dcbd0926bcada 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -538,7 +538,7 @@ Other Language Changes * The new :option:`-X` ``importtime`` option or the :envvar:`PYTHONPROFILEIMPORTTIME` environment variable can be used to show the timing of each module import. - (Contributed by Victor Stinner in :issue:`31415`.) + (Contributed by Inada Naoki in :issue:`31415`.) New Modules From webhook-mailer at python.org Mon Mar 14 17:30:23 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 14 Mar 2022 21:30:23 -0000 Subject: [Python-checkins] bpo-31415: importtime was made by Inada Naoki (GH-31875) Message-ID: https://github.com/python/cpython/commit/73943ce7d31595d152dc01bf0008b37c802c0d3b commit: 73943ce7d31595d152dc01bf0008b37c802c0d3b branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-14T14:30:15-07:00 summary: bpo-31415: importtime was made by Inada Naoki (GH-31875) (cherry picked from commit 29624e769c5c3c1e59c6acc8b69383ead53e8a9f) Co-authored-by: Victor Stinner files: M Doc/whatsnew/3.7.rst diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index 9204cc7fbf8c4..7a00e37624185 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -537,7 +537,7 @@ Other Language Changes * The new :option:`-X` ``importtime`` option or the :envvar:`PYTHONPROFILEIMPORTTIME` environment variable can be used to show the timing of each module import. - (Contributed by Victor Stinner in :issue:`31415`.) + (Contributed by Inada Naoki in :issue:`31415`.) New Modules From webhook-mailer at python.org Mon Mar 14 19:29:06 2022 From: webhook-mailer at python.org (iritkatriel) Date: Mon, 14 Mar 2022 23:29:06 -0000 Subject: [Python-checkins] bpo-43721: Fix docstrings for property.getter/setter/deleter (GH-31046) Message-ID: https://github.com/python/cpython/commit/e3d348a5252549708fd19338b675a2c23b60d677 commit: e3d348a5252549708fd19338b675a2c23b60d677 branch: main author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-03-14T23:28:54Z summary: bpo-43721: Fix docstrings for property.getter/setter/deleter (GH-31046) files: A Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst M Objects/descrobject.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst new file mode 100644 index 0000000000000..4e3ad02057ada --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst @@ -0,0 +1 @@ +Fix docstrings of :attr:`~property.getter`, :attr:`~property.setter`, and :attr:`~property.deleter` to clarify that they create a new copy of the property. \ No newline at end of file diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 2d4cfb5b7aeb8..e255d4ae5f86f 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -1501,7 +1501,7 @@ static PyMemberDef property_members[] = { PyDoc_STRVAR(getter_doc, - "Descriptor to change the getter on a property."); + "Descriptor to obtain a copy of the property with a different getter."); static PyObject * property_getter(PyObject *self, PyObject *getter) @@ -1511,7 +1511,7 @@ property_getter(PyObject *self, PyObject *getter) PyDoc_STRVAR(setter_doc, - "Descriptor to change the setter on a property."); + "Descriptor to obtain a copy of the property with a different setter."); static PyObject * property_setter(PyObject *self, PyObject *setter) @@ -1521,7 +1521,7 @@ property_setter(PyObject *self, PyObject *setter) PyDoc_STRVAR(deleter_doc, - "Descriptor to change the deleter on a property."); + "Descriptor to obtain a copy of the property with a different deleter."); static PyObject * property_deleter(PyObject *self, PyObject *deleter) From webhook-mailer at python.org Mon Mar 14 19:52:05 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 14 Mar 2022 23:52:05 -0000 Subject: [Python-checkins] bpo-43721: Fix docstrings for property.getter/setter/deleter (GH-31046) Message-ID: https://github.com/python/cpython/commit/cebdc325580b49f4c7eb3c61a24c9e7f41ca736b commit: cebdc325580b49f4c7eb3c61a24c9e7f41ca736b branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-14T16:51:55-07:00 summary: bpo-43721: Fix docstrings for property.getter/setter/deleter (GH-31046) (cherry picked from commit e3d348a5252549708fd19338b675a2c23b60d677) Co-authored-by: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> files: A Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst M Objects/descrobject.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst new file mode 100644 index 0000000000000..4e3ad02057ada --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst @@ -0,0 +1 @@ +Fix docstrings of :attr:`~property.getter`, :attr:`~property.setter`, and :attr:`~property.deleter` to clarify that they create a new copy of the property. \ No newline at end of file diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 26726cc0973df..09b0f82c69909 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -1510,7 +1510,7 @@ static PyMemberDef property_members[] = { PyDoc_STRVAR(getter_doc, - "Descriptor to change the getter on a property."); + "Descriptor to obtain a copy of the property with a different getter."); static PyObject * property_getter(PyObject *self, PyObject *getter) @@ -1520,7 +1520,7 @@ property_getter(PyObject *self, PyObject *getter) PyDoc_STRVAR(setter_doc, - "Descriptor to change the setter on a property."); + "Descriptor to obtain a copy of the property with a different setter."); static PyObject * property_setter(PyObject *self, PyObject *setter) @@ -1530,7 +1530,7 @@ property_setter(PyObject *self, PyObject *setter) PyDoc_STRVAR(deleter_doc, - "Descriptor to change the deleter on a property."); + "Descriptor to obtain a copy of the property with a different deleter."); static PyObject * property_deleter(PyObject *self, PyObject *deleter) From webhook-mailer at python.org Mon Mar 14 19:55:22 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 14 Mar 2022 23:55:22 -0000 Subject: [Python-checkins] bpo-43721: Fix docstrings for property.getter/setter/deleter (GH-31046) Message-ID: https://github.com/python/cpython/commit/f1a5e1b89a526da0d66c5b368c924298291abb1a commit: f1a5e1b89a526da0d66c5b368c924298291abb1a branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-14T16:55:12-07:00 summary: bpo-43721: Fix docstrings for property.getter/setter/deleter (GH-31046) (cherry picked from commit e3d348a5252549708fd19338b675a2c23b60d677) Co-authored-by: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> files: A Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst M Objects/descrobject.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst new file mode 100644 index 0000000000000..4e3ad02057ada --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst @@ -0,0 +1 @@ +Fix docstrings of :attr:`~property.getter`, :attr:`~property.setter`, and :attr:`~property.deleter` to clarify that they create a new copy of the property. \ No newline at end of file diff --git a/Objects/descrobject.c b/Objects/descrobject.c index ee40645955206..00349ab17912e 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -1508,7 +1508,7 @@ static PyMemberDef property_members[] = { PyDoc_STRVAR(getter_doc, - "Descriptor to change the getter on a property."); + "Descriptor to obtain a copy of the property with a different getter."); static PyObject * property_getter(PyObject *self, PyObject *getter) @@ -1518,7 +1518,7 @@ property_getter(PyObject *self, PyObject *getter) PyDoc_STRVAR(setter_doc, - "Descriptor to change the setter on a property."); + "Descriptor to obtain a copy of the property with a different setter."); static PyObject * property_setter(PyObject *self, PyObject *setter) @@ -1528,7 +1528,7 @@ property_setter(PyObject *self, PyObject *setter) PyDoc_STRVAR(deleter_doc, - "Descriptor to change the deleter on a property."); + "Descriptor to obtain a copy of the property with a different deleter."); static PyObject * property_deleter(PyObject *self, PyObject *deleter) From webhook-mailer at python.org Tue Mar 15 03:18:43 2022 From: webhook-mailer at python.org (ned-deily) Date: Tue, 15 Mar 2022 07:18:43 -0000 Subject: [Python-checkins] bpo-45405: Prevent internal configure error when running configure with recent versions of clang. (GH-28845) (GH-31890) Message-ID: https://github.com/python/cpython/commit/720bb456dc711b0776bae837d1f9a0b10c28ddf2 commit: 720bb456dc711b0776bae837d1f9a0b10c28ddf2 branch: 3.7 author: Ned Deily committer: ned-deily date: 2022-03-15T03:18:39-04:00 summary: bpo-45405: Prevent internal configure error when running configure with recent versions of clang. (GH-28845) (GH-31890) Change the configure logic to function properly on macOS when the compiler outputs a platform triplet for option --print-multiarch. The Apple Clang included with Xcode 13.3 now supports --print-multiarch causing configure to fail without this change. Co-authored-by: Ned Deily (cherry picked from commit 9c4766772cda67648184f8ddba546a5fc0167f91) Co-authored-by: David Bohman files: A Misc/NEWS.d/next/Build/2021-10-11-16-27-38.bpo-45405.iSfdW5.rst M configure M configure.ac diff --git a/Misc/NEWS.d/next/Build/2021-10-11-16-27-38.bpo-45405.iSfdW5.rst b/Misc/NEWS.d/next/Build/2021-10-11-16-27-38.bpo-45405.iSfdW5.rst new file mode 100644 index 0000000000000..13c93d1b8a571 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2021-10-11-16-27-38.bpo-45405.iSfdW5.rst @@ -0,0 +1,2 @@ +Prevent ``internal configure error`` when running ``configure`` +with recent versions of clang. Patch by David Bohman. diff --git a/configure b/configure index 829dd69bb8b30..455481bc5005c 100755 --- a/configure +++ b/configure @@ -5183,9 +5183,6 @@ $as_echo "$as_me: fi -MULTIARCH=$($CC --print-multiarch 2>/dev/null) - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the platform triplet based on compiler characteristics" >&5 $as_echo_n "checking for the platform triplet based on compiler characteristics... " >&6; } cat >> conftest.c <&6; } fi rm -f conftest.c conftest.out +if test x$PLATFORM_TRIPLET != xdarwin; then + MULTIARCH=$($CC --print-multiarch 2>/dev/null) +fi + + if test x$PLATFORM_TRIPLET != x && test x$MULTIARCH != x; then if test x$PLATFORM_TRIPLET != x$MULTIARCH; then as_fn_error $? "internal configure error for the platform triplet, please file a bug report" "$LINENO" 5 diff --git a/configure.ac b/configure.ac index f1cc8e9bcb9ed..1afcba3307ade 100644 --- a/configure.ac +++ b/configure.ac @@ -724,9 +724,6 @@ then fi -MULTIARCH=$($CC --print-multiarch 2>/dev/null) -AC_SUBST(MULTIARCH) - AC_MSG_CHECKING([for the platform triplet based on compiler characteristics]) cat >> conftest.c </dev/null) +fi +AC_SUBST(MULTIARCH) + if test x$PLATFORM_TRIPLET != x && test x$MULTIARCH != x; then if test x$PLATFORM_TRIPLET != x$MULTIARCH; then AC_MSG_ERROR([internal configure error for the platform triplet, please file a bug report]) From webhook-mailer at python.org Tue Mar 15 04:04:25 2022 From: webhook-mailer at python.org (methane) Date: Tue, 15 Mar 2022 08:04:25 -0000 Subject: [Python-checkins] Tools/gdb: Drop code to support Python 2. (GH-31717) Message-ID: https://github.com/python/cpython/commit/52f6ce396ddf1e99205796ae6ad3d880c2713e3e commit: 52f6ce396ddf1e99205796ae6ad3d880c2713e3e branch: main author: Inada Naoki committer: methane date: 2022-03-15T17:04:11+09:00 summary: Tools/gdb: Drop code to support Python 2. (GH-31717) files: M Tools/gdb/libpython.py diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index 8b227e61082be..00cdcca084e74 100755 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -41,20 +41,11 @@ The module also extends gdb with some python-specific commands. ''' -# NOTE: some gdbs are linked with Python 3, so this file should be dual-syntax -# compatible (2.6+ and 3.0+). See #19308. - -from __future__ import print_function - import gdb import os import locale import sys -if sys.version_info[0] >= 3: - unichr = chr - xrange = range - long = int # Look up the gdb.Type for some standard types: # Those need to be refreshed as types (pointer sizes) may change when @@ -80,9 +71,6 @@ def _sizeof_void_p(): return gdb.lookup_type('void').pointer().sizeof -# value computed later, see PyUnicodeObjectPtr.proxy() -_is_pep393 = None - Py_TPFLAGS_MANAGED_DICT = (1 << 4) Py_TPFLAGS_HEAPTYPE = (1 << 9) Py_TPFLAGS_LONG_SUBCLASS = (1 << 24) @@ -119,19 +107,7 @@ def safety_limit(val): def safe_range(val): # As per range, but don't trust the value too much: cap it to a safety # threshold in case the data was corrupted - return xrange(safety_limit(int(val))) - -if sys.version_info[0] >= 3: - def write_unicode(file, text): - file.write(text) -else: - def write_unicode(file, text): - # Write a byte or unicode string to file. Unicode strings are encoded to - # ENCODING encoding with 'backslashreplace' error handler to avoid - # UnicodeEncodeError. - if isinstance(text, unicode): - text = text.encode(ENCODING, 'backslashreplace') - file.write(text) + return range(safety_limit(int(val))) try: os_fsencode = os.fsencode @@ -258,7 +234,7 @@ def type(self): return PyTypeObjectPtr(self.field('ob_type')) def is_null(self): - return 0 == long(self._gdbval) + return 0 == int(self._gdbval) def is_optimized_out(self): ''' @@ -320,7 +296,7 @@ def __repr__(self): return '<%s at remote 0x%x>' % (self.tp_name, self.address) return FakeRepr(self.safe_tp_name(), - long(self._gdbval)) + int(self._gdbval)) def write_repr(self, out, visited): ''' @@ -420,7 +396,7 @@ def get_gdb_type(cls): return gdb.lookup_type(cls._typename).pointer() def as_address(self): - return long(self._gdbval) + return int(self._gdbval) class PyVarObjectPtr(PyObjectPtr): _typename = 'PyVarObject' @@ -529,7 +505,7 @@ def get_keys_values(self): PyDictValuesPtrPtr = gdb.lookup_type("PyDictValues").pointer().pointer() valuesptr = self._gdbval.cast(PyDictValuesPtrPtr) - 4 values = valuesptr.dereference() - if long(values) == 0: + if int(values) == 0: return None values = values['values'] return PyKeysValuesPair(self.get_cached_keys(), values) @@ -562,7 +538,7 @@ def proxyval(self, visited): tp_name = self.safe_tp_name() # Class: - return InstanceProxy(tp_name, attr_dict, long(self._gdbval)) + return InstanceProxy(tp_name, attr_dict, int(self._gdbval)) def write_repr(self, out, visited): # Guard against infinite loops: @@ -737,7 +713,7 @@ def iteritems(self): ''' keys = self.field('ma_keys') values = self.field('ma_values') - has_values = long(values) + has_values = int(values) if has_values: values = values['values'] if has_values: @@ -862,7 +838,7 @@ def proxyval(self, visited): #define PyLong_SHIFT 30 #define PyLong_SHIFT 15 ''' - ob_size = long(self.field('ob_size')) + ob_size = int(self.field('ob_size')) if ob_size == 0: return 0 @@ -873,7 +849,7 @@ def proxyval(self, visited): else: SHIFT = 30 - digits = [long(ob_digit[i]) * 2**(SHIFT*i) + digits = [int(ob_digit[i]) * 2**(SHIFT*i) for i in safe_range(abs(ob_size))] result = sum(digits) if ob_size < 0: @@ -1124,7 +1100,7 @@ def current_line(self): filename = self.filename() try: - with open(os_fsencode(filename), 'r') as fp: + with open(os_fsencode(filename), 'r', encoding="utf-8") as fp: lines = fp.readlines() except IOError: return None @@ -1159,7 +1135,7 @@ def write_repr(self, out, visited): out.write(')') def as_address(self): - return long(self._gdbval) + return int(self._gdbval) def print_traceback(self): if self.is_optimized_out(): @@ -1340,18 +1316,6 @@ def _unichr_is_printable(char): import unicodedata return unicodedata.category(char) not in ("C", "Z") -if sys.maxunicode >= 0x10000: - _unichr = unichr -else: - # Needed for proper surrogate support if sizeof(Py_UNICODE) is 2 in gdb - def _unichr(x): - if x < 0x10000: - return unichr(x) - x -= 0x10000 - ch1 = 0xD800 | (x >> 10) - ch2 = 0xDC00 | (x & 0x3FF) - return unichr(ch1) + unichr(ch2) - class PyUnicodeObjectPtr(PyObjectPtr): _typename = 'PyUnicodeObject' @@ -1361,42 +1325,31 @@ def char_width(self): return _type_Py_UNICODE.sizeof def proxyval(self, visited): - global _is_pep393 - if _is_pep393 is None: - fields = gdb.lookup_type('PyUnicodeObject').fields() - _is_pep393 = 'data' in [f.name for f in fields] - if _is_pep393: - # Python 3.3 and newer - may_have_surrogates = False - compact = self.field('_base') - ascii = compact['_base'] - state = ascii['state'] - is_compact_ascii = (int(state['ascii']) and int(state['compact'])) - if not int(state['ready']): - # string is not ready - field_length = long(compact['wstr_length']) - may_have_surrogates = True - field_str = ascii['wstr'] - else: - field_length = long(ascii['length']) - if is_compact_ascii: - field_str = ascii.address + 1 - elif int(state['compact']): - field_str = compact.address + 1 - else: - field_str = self.field('data')['any'] - repr_kind = int(state['kind']) - if repr_kind == 1: - field_str = field_str.cast(_type_unsigned_char_ptr()) - elif repr_kind == 2: - field_str = field_str.cast(_type_unsigned_short_ptr()) - elif repr_kind == 4: - field_str = field_str.cast(_type_unsigned_int_ptr()) + may_have_surrogates = False + compact = self.field('_base') + ascii = compact['_base'] + state = ascii['state'] + is_compact_ascii = (int(state['ascii']) and int(state['compact'])) + if not int(state['ready']): + # string is not ready + field_length = int(compact['wstr_length']) + may_have_surrogates = True + field_str = ascii['wstr'] else: - # Python 3.2 and earlier - field_length = long(self.field('length')) - field_str = self.field('str') - may_have_surrogates = self.char_width() == 2 + field_length = int(ascii['length']) + if is_compact_ascii: + field_str = ascii.address + 1 + elif int(state['compact']): + field_str = compact.address + 1 + else: + field_str = self.field('data')['any'] + repr_kind = int(state['kind']) + if repr_kind == 1: + field_str = field_str.cast(_type_unsigned_char_ptr()) + elif repr_kind == 2: + field_str = field_str.cast(_type_unsigned_short_ptr()) + elif repr_kind == 4: + field_str = field_str.cast(_type_unsigned_int_ptr()) # Gather a list of ints from the Py_UNICODE array; these are either # UCS-1, UCS-2 or UCS-4 code points: @@ -1426,10 +1379,7 @@ def proxyval(self, visited): # Convert the int code points to unicode characters, and generate a # local unicode instance. - # This splits surrogate pairs if sizeof(Py_UNICODE) is 2 here (in gdb). - result = u''.join([ - (_unichr(ucs) if ucs <= 0x10ffff else '\ufffd') - for ucs in Py_UNICODEs]) + result = u''.join(map(chr, Py_UNICODEs)) return result def write_repr(self, out, visited): @@ -1478,19 +1428,8 @@ def write_repr(self, out, visited): else: ucs = ch ch2 = None - if sys.maxunicode < 0x10000: - # If sizeof(Py_UNICODE) is 2 here (in gdb), join - # surrogate pairs before calling _unichr_is_printable. - if (i < len(proxy) - and 0xD800 <= ord(ch) < 0xDC00 \ - and 0xDC00 <= ord(proxy[i]) <= 0xDFFF): - ch2 = proxy[i] - ucs = ch + ch2 - i += 1 - - # Unfortuately, Python 2's unicode type doesn't seem - # to expose the "isprintable" method - printable = _unichr_is_printable(ucs) + + printable = ucs.isprintable() if printable: try: ucs.encode(ENCODING) @@ -1559,7 +1498,7 @@ def safe_tp_name(self): def safe_self_addresss(self): try: - address = long(self.field('self')) + address = int(self.field('self')) return '%#x' % address except (NullPyObjectPtr, RuntimeError): return '' @@ -1852,7 +1791,7 @@ def print_summary(self): while True: if interp_frame: line = interp_frame.get_truncated_repr(MAX_OUTPUT_LEN) - write_unicode(sys.stdout, '#%i %s\n' % (self.get_index(), line)) + sys.stdout.write('#%i %s\n' % (self.get_index(), line)) if not interp_frame.is_optimized_out(): line = interp_frame.current_line() if line is not None: @@ -1952,7 +1891,7 @@ def invoke(self, args, from_tty): start = 1 try: - f = open(os_fsencode(filename), 'r') + f = open(os_fsencode(filename), 'r', encoding="utf-8") except IOError as err: sys.stdout.write('Unable to open %s: %s\n' % (filename, err)) From webhook-mailer at python.org Tue Mar 15 04:29:39 2022 From: webhook-mailer at python.org (iritkatriel) Date: Tue, 15 Mar 2022 08:29:39 -0000 Subject: [Python-checkins] But Add missing newline to NEWS entry (GH-31893) Message-ID: https://github.com/python/cpython/commit/16995ed0f2b697ca1ff966741288e787e1701ca9 commit: 16995ed0f2b697ca1ff966741288e787e1701ca9 branch: main author: Hugo van Kemenade committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-03-15T08:29:10Z summary: But Add missing newline to NEWS entry (GH-31893) files: M Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst index 4e3ad02057ada..cd3df72664823 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst @@ -1 +1 @@ -Fix docstrings of :attr:`~property.getter`, :attr:`~property.setter`, and :attr:`~property.deleter` to clarify that they create a new copy of the property. \ No newline at end of file +Fix docstrings of :attr:`~property.getter`, :attr:`~property.setter`, and :attr:`~property.deleter` to clarify that they create a new copy of the property. From webhook-mailer at python.org Tue Mar 15 04:51:36 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 15 Mar 2022 08:51:36 -0000 Subject: [Python-checkins] But Add missing newline to NEWS entry (GH-31893) Message-ID: https://github.com/python/cpython/commit/0e4bebad0a099e5f1440edcdd0ce3eae9952bf74 commit: 0e4bebad0a099e5f1440edcdd0ce3eae9952bf74 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-15T01:51:32-07:00 summary: But Add missing newline to NEWS entry (GH-31893) (cherry picked from commit 16995ed0f2b697ca1ff966741288e787e1701ca9) Co-authored-by: Hugo van Kemenade files: M Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst index 4e3ad02057ada..cd3df72664823 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst @@ -1 +1 @@ -Fix docstrings of :attr:`~property.getter`, :attr:`~property.setter`, and :attr:`~property.deleter` to clarify that they create a new copy of the property. \ No newline at end of file +Fix docstrings of :attr:`~property.getter`, :attr:`~property.setter`, and :attr:`~property.deleter` to clarify that they create a new copy of the property. From webhook-mailer at python.org Tue Mar 15 04:56:21 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 15 Mar 2022 08:56:21 -0000 Subject: [Python-checkins] But Add missing newline to NEWS entry (GH-31893) Message-ID: https://github.com/python/cpython/commit/91dfa917e56527c3c3a715f4274a017273c4d664 commit: 91dfa917e56527c3c3a715f4274a017273c4d664 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-15T01:56:13-07:00 summary: But Add missing newline to NEWS entry (GH-31893) (cherry picked from commit 16995ed0f2b697ca1ff966741288e787e1701ca9) Co-authored-by: Hugo van Kemenade files: M Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst index 4e3ad02057ada..cd3df72664823 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst @@ -1 +1 @@ -Fix docstrings of :attr:`~property.getter`, :attr:`~property.setter`, and :attr:`~property.deleter` to clarify that they create a new copy of the property. \ No newline at end of file +Fix docstrings of :attr:`~property.getter`, :attr:`~property.setter`, and :attr:`~property.deleter` to clarify that they create a new copy of the property. From webhook-mailer at python.org Tue Mar 15 05:01:07 2022 From: webhook-mailer at python.org (vsajip) Date: Tue, 15 Mar 2022 09:01:07 -0000 Subject: [Python-checkins] bpo-46557: Log captured warnings without format string (GH-30975) Message-ID: https://github.com/python/cpython/commit/d8066b420b888591f485d132e62979d07abfc3f4 commit: d8066b420b888591f485d132e62979d07abfc3f4 branch: main author: Michael P. Nitowski committer: vsajip date: 2022-03-15T09:01:03Z summary: bpo-46557: Log captured warnings without format string (GH-30975) files: A Misc/NEWS.d/next/Library/2022-01-28-01-23-25.bpo-46557.XSbhyQ.rst M Lib/logging/__init__.py diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index e49e0d02a80cf..160b1afcee0f9 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -2246,7 +2246,9 @@ def _showwarning(message, category, filename, lineno, file=None, line=None): logger = getLogger("py.warnings") if not logger.handlers: logger.addHandler(NullHandler()) - logger.warning("%s", s) + # bpo-46557: Log str(s) as msg instead of logger.warning("%s", s) + # since some log aggregation tools group logs by the msg arg + logger.warning(str(s)) def captureWarnings(capture): """ diff --git a/Misc/NEWS.d/next/Library/2022-01-28-01-23-25.bpo-46557.XSbhyQ.rst b/Misc/NEWS.d/next/Library/2022-01-28-01-23-25.bpo-46557.XSbhyQ.rst new file mode 100644 index 0000000000000..dd7d3f3d6c51f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-01-28-01-23-25.bpo-46557.XSbhyQ.rst @@ -0,0 +1 @@ +Warnings captured by the logging module are now logged without a format string to prevent systems that group logs by the msg argument from grouping captured warnings together. From webhook-mailer at python.org Tue Mar 15 05:41:16 2022 From: webhook-mailer at python.org (tiran) Date: Tue, 15 Mar 2022 09:41:16 -0000 Subject: [Python-checkins] bpo-46587: Skip tests if strftime does not support glibc extension (GH-31873) Message-ID: https://github.com/python/cpython/commit/2cf7f865f099db11cc6903b334d9c376610313e8 commit: 2cf7f865f099db11cc6903b334d9c376610313e8 branch: main author: Christian Heimes committer: tiran date: 2022-03-15T10:41:04+01:00 summary: bpo-46587: Skip tests if strftime does not support glibc extension (GH-31873) Co-authored-by: Victor Stinner files: A Misc/NEWS.d/next/Tests/2022-03-14-17-10-35.bpo-46587.ASDsJX.rst M Lib/test/datetimetester.py M Lib/test/support/__init__.py M Lib/test/test_support.py M Lib/test/test_time.py diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index df3764d61b186..e208a29813eed 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -1676,7 +1676,8 @@ def test_strftime_y2k(self): # Year 42 returns '42', not padded self.assertEqual(d.strftime("%Y"), '%d' % y) # '0042' is obtained anyway - self.assertEqual(d.strftime("%4Y"), '%04d' % y) + if support.has_strftime_extensions: + self.assertEqual(d.strftime("%4Y"), '%04d' % y) def test_replace(self): cls = self.theclass diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index c7bee8be662cc..01bb57ec44f0c 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -520,6 +520,11 @@ def requires_subprocess(): """Used for subprocess, os.spawn calls, fd inheritance""" return unittest.skipUnless(has_subprocess_support, "requires subprocess support") +# Does strftime() support glibc extension like '%4Y'? +try: + has_strftime_extensions = time.strftime("%4Y") != "%4Y" +except ValueError: + has_strftime_extensions = False # Define the URL of a dedicated HTTP server for the network tests. # The URL must use clear-text HTTP: no redirection to encrypted HTTPS. @@ -769,29 +774,29 @@ def check_sizeof(test, o, size): @contextlib.contextmanager def run_with_locale(catstr, *locales): + try: + import locale + category = getattr(locale, catstr) + orig_locale = locale.setlocale(category) + except AttributeError: + # if the test author gives us an invalid category string + raise + except: + # cannot retrieve original locale, so do nothing + locale = orig_locale = None + else: + for loc in locales: try: - import locale - category = getattr(locale, catstr) - orig_locale = locale.setlocale(category) - except AttributeError: - # if the test author gives us an invalid category string - raise + locale.setlocale(category, loc) + break except: - # cannot retrieve original locale, so do nothing - locale = orig_locale = None - else: - for loc in locales: - try: - locale.setlocale(category, loc) - break - except: - pass + pass - try: - yield - finally: - if locale and orig_locale: - locale.setlocale(category, orig_locale) + try: + yield + finally: + if locale and orig_locale: + locale.setlocale(category, orig_locale) #======================================================================= # Decorator for running a function in a specific timezone, correctly diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py index 1ce3c826d6b1b..59e9f3a6c1c8d 100644 --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -682,6 +682,12 @@ def test_print_warning(self): self.check_print_warning("a\nb", 'Warning -- a\nWarning -- b\n') + def test_has_strftime_extensions(self): + if support.is_emscripten or support.is_wasi or sys.platform == "win32": + self.assertFalse(support.has_strftime_extensions) + else: + self.assertTrue(support.has_strftime_extensions) + # XXX -follows a list of untested API # make_legacy_pyc # is_resource_enabled diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py index e3d75da55cb3a..57011d158cd03 100644 --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -622,6 +622,9 @@ class _TestStrftimeYear: def yearstr(self, y): return time.strftime('%Y', (y,) + (0,) * 8) + @unittest.skipUnless( + support.has_strftime_extensions, "requires strftime extension" + ) def test_4dyear(self): # Check that we can return the zero padded value. if self._format == '%04d': diff --git a/Misc/NEWS.d/next/Tests/2022-03-14-17-10-35.bpo-46587.ASDsJX.rst b/Misc/NEWS.d/next/Tests/2022-03-14-17-10-35.bpo-46587.ASDsJX.rst new file mode 100644 index 0000000000000..ebd94abe9ca4c --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2022-03-14-17-10-35.bpo-46587.ASDsJX.rst @@ -0,0 +1,2 @@ +Skip tests if platform's ``strftime`` does not support non-portable glibc +extensions. From webhook-mailer at python.org Tue Mar 15 09:22:36 2022 From: webhook-mailer at python.org (asvetlov) Date: Tue, 15 Mar 2022 13:22:36 -0000 Subject: [Python-checkins] Drop accidentally added whitespaces in asyncio internals (GH-31900) Message-ID: https://github.com/python/cpython/commit/22403d3a814ae2fd7e531479396959d639b98559 commit: 22403d3a814ae2fd7e531479396959d639b98559 branch: main author: Andrew Svetlov committer: asvetlov date: 2022-03-15T15:22:26+02:00 summary: Drop accidentally added whitespaces in asyncio internals (GH-31900) files: M Lib/asyncio/selector_events.py diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index bfd8019da606e..33ebc4b27808c 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -485,7 +485,7 @@ async def sock_recvfrom_into(self, sock, buf, nbytes=0): raise ValueError("the socket must be non-blocking") if not nbytes: nbytes = len(buf) - + try: return sock.recvfrom_into(buf, nbytes) except (BlockingIOError, InterruptedError): From webhook-mailer at python.org Tue Mar 15 09:25:47 2022 From: webhook-mailer at python.org (asvetlov) Date: Tue, 15 Mar 2022 13:25:47 -0000 Subject: [Python-checkins] bpo-20392: Fix inconsistency with uppercase file extensions in mimetypes.guess_type (GH-30229) Message-ID: https://github.com/python/cpython/commit/5dd7ec52b83e7f239774cf7478106fcc7b0a36f3 commit: 5dd7ec52b83e7f239774cf7478106fcc7b0a36f3 branch: main author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> committer: asvetlov date: 2022-03-15T15:25:43+02:00 summary: bpo-20392: Fix inconsistency with uppercase file extensions in mimetypes.guess_type (GH-30229) files: A Misc/NEWS.d/next/Library/2021-12-22-12-02-27.bpo-20392.CLAFIp.rst M Lib/mimetypes.py M Lib/test/test_mimetypes.py diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index 4750408173ec0..1aa32467e278a 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -141,25 +141,23 @@ def guess_type(self, url, strict=True): type = 'text/plain' return type, None # never compressed, so encoding is None base, ext = posixpath.splitext(url) - while ext in self.suffix_map: - base, ext = posixpath.splitext(base + self.suffix_map[ext]) + while (ext_lower := ext.lower()) in self.suffix_map: + base, ext = posixpath.splitext(base + self.suffix_map[ext_lower]) + # encodings_map is case sensitive if ext in self.encodings_map: encoding = self.encodings_map[ext] base, ext = posixpath.splitext(base) else: encoding = None + ext = ext.lower() types_map = self.types_map[True] if ext in types_map: return types_map[ext], encoding - elif ext.lower() in types_map: - return types_map[ext.lower()], encoding elif strict: return None, encoding types_map = self.types_map[False] if ext in types_map: return types_map[ext], encoding - elif ext.lower() in types_map: - return types_map[ext.lower()], encoding else: return None, encoding diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 392ddd2d5eee9..3477b18376a4f 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -33,6 +33,13 @@ def tearDownModule(): class MimeTypesTestCase(unittest.TestCase): def setUp(self): self.db = mimetypes.MimeTypes() + + def test_case_sensitivity(self): + eq = self.assertEqual + eq(self.db.guess_type("foobar.HTML"), self.db.guess_type("foobar.html")) + eq(self.db.guess_type("foobar.TGZ"), self.db.guess_type("foobar.tgz")) + eq(self.db.guess_type("foobar.tar.Z"), ("application/x-tar", "compress")) + eq(self.db.guess_type("foobar.tar.z"), (None, None)) def test_default_data(self): eq = self.assertEqual diff --git a/Misc/NEWS.d/next/Library/2021-12-22-12-02-27.bpo-20392.CLAFIp.rst b/Misc/NEWS.d/next/Library/2021-12-22-12-02-27.bpo-20392.CLAFIp.rst new file mode 100644 index 0000000000000..8973c4d433174 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-12-22-12-02-27.bpo-20392.CLAFIp.rst @@ -0,0 +1 @@ +Fix inconsistency with uppercase file extensions in :meth:`MimeTypes.guess_type`. Patch by Kumar Aditya. From webhook-mailer at python.org Tue Mar 15 09:27:35 2022 From: webhook-mailer at python.org (asvetlov) Date: Tue, 15 Mar 2022 13:27:35 -0000 Subject: [Python-checkins] bpo-46993: Speed up bytearray creation from list and tuple (GH-31834) Message-ID: https://github.com/python/cpython/commit/6dfe09fc5fd5a3ddc6009d5656e635eae30c5240 commit: 6dfe09fc5fd5a3ddc6009d5656e635eae30c5240 branch: main author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> committer: asvetlov date: 2022-03-15T15:27:30+02:00 summary: bpo-46993: Speed up bytearray creation from list and tuple (GH-31834) files: A Misc/NEWS.d/next/Core and Builtins/2022-03-12-09-44-31.bpo-46993.-13hGo.rst M Objects/bytearrayobject.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-12-09-44-31.bpo-46993.-13hGo.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-12-09-44-31.bpo-46993.-13hGo.rst new file mode 100644 index 0000000000000..b7f7078856bd5 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-12-09-44-31.bpo-46993.-13hGo.rst @@ -0,0 +1 @@ +Speed up :class:`bytearray` creation from :class:`list` and :class:`tuple` by 40%. Patch by Kumar Aditya. diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 0ebb2ece39d5d..3493ff046ae13 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -844,8 +844,33 @@ bytearray___init___impl(PyByteArrayObject *self, PyObject *arg, return -1; } - /* XXX Optimize this if the arguments is a list, tuple */ - + if (PyList_CheckExact(arg) || PyTuple_CheckExact(arg)) { + Py_ssize_t size = PySequence_Fast_GET_SIZE(arg); + if (PyByteArray_Resize((PyObject *)self, size) < 0) { + return -1; + } + PyObject **items = PySequence_Fast_ITEMS(arg); + char *s = PyByteArray_AS_STRING(self); + for (Py_ssize_t i = 0; i < size; i++) { + int value; + if (!PyLong_CheckExact(items[i])) { + /* Resize to 0 and go through slowpath */ + if (Py_SIZE(self) != 0) { + if (PyByteArray_Resize((PyObject *)self, 0) < 0) { + return -1; + } + } + goto slowpath; + } + int rc = _getbytevalue(items[i], &value); + if (!rc) { + return -1; + } + s[i] = value; + } + return 0; + } +slowpath: /* Get the iterator */ it = PyObject_GetIter(arg); if (it == NULL) { From webhook-mailer at python.org Tue Mar 15 10:39:25 2022 From: webhook-mailer at python.org (ambv) Date: Tue, 15 Mar 2022 14:39:25 -0000 Subject: [Python-checkins] bpo-45405: Prevent internal configure error when running configure with recent versions of clang. (GH-28845) (GH-31889) Message-ID: https://github.com/python/cpython/commit/dea270a2a80214de22afadaaca2043d0d782eb7d commit: dea270a2a80214de22afadaaca2043d0d782eb7d branch: 3.8 author: Ned Deily committer: ambv date: 2022-03-15T15:39:20+01:00 summary: bpo-45405: Prevent internal configure error when running configure with recent versions of clang. (GH-28845) (GH-31889) Change the configure logic to function properly on macOS when the compiler outputs a platform triplet for option --print-multiarch. The Apple Clang included with Xcode 13.3 now supports --print-multiarch causing configure to fail without this change. Co-authored-by: Ned Deily (cherry picked from commit 9c4766772cda67648184f8ddba546a5fc0167f91) Co-authored-by: David Bohman Automerge-Triggered-By: GH:ned-deily (cherry picked from commit 9901d153c201d852d27dc9d3074e283c26468f6d) Co-authored-by: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> files: A Misc/NEWS.d/next/Build/2021-10-11-16-27-38.bpo-45405.iSfdW5.rst M configure M configure.ac diff --git a/Misc/NEWS.d/next/Build/2021-10-11-16-27-38.bpo-45405.iSfdW5.rst b/Misc/NEWS.d/next/Build/2021-10-11-16-27-38.bpo-45405.iSfdW5.rst new file mode 100644 index 0000000000000..13c93d1b8a571 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2021-10-11-16-27-38.bpo-45405.iSfdW5.rst @@ -0,0 +1,2 @@ +Prevent ``internal configure error`` when running ``configure`` +with recent versions of clang. Patch by David Bohman. diff --git a/configure b/configure index 936f3d4596f53..c091865aff750 100755 --- a/configure +++ b/configure @@ -5160,9 +5160,6 @@ $as_echo "$as_me: fi -MULTIARCH=$($CC --print-multiarch 2>/dev/null) - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the platform triplet based on compiler characteristics" >&5 $as_echo_n "checking for the platform triplet based on compiler characteristics... " >&6; } cat >> conftest.c <&6; } fi rm -f conftest.c conftest.out +if test x$PLATFORM_TRIPLET != xdarwin; then + MULTIARCH=$($CC --print-multiarch 2>/dev/null) +fi + + if test x$PLATFORM_TRIPLET != x && test x$MULTIARCH != x; then if test x$PLATFORM_TRIPLET != x$MULTIARCH; then as_fn_error $? "internal configure error for the platform triplet, please file a bug report" "$LINENO" 5 diff --git a/configure.ac b/configure.ac index e02cc2c65622f..de83332dd3c6e 100644 --- a/configure.ac +++ b/configure.ac @@ -719,9 +719,6 @@ then fi -MULTIARCH=$($CC --print-multiarch 2>/dev/null) -AC_SUBST(MULTIARCH) - AC_MSG_CHECKING([for the platform triplet based on compiler characteristics]) cat >> conftest.c </dev/null) +fi +AC_SUBST(MULTIARCH) + if test x$PLATFORM_TRIPLET != x && test x$MULTIARCH != x; then if test x$PLATFORM_TRIPLET != x$MULTIARCH; then AC_MSG_ERROR([internal configure error for the platform triplet, please file a bug report]) From webhook-mailer at python.org Tue Mar 15 10:39:55 2022 From: webhook-mailer at python.org (ambv) Date: Tue, 15 Mar 2022 14:39:55 -0000 Subject: [Python-checkins] bpo-46985: Upgrade bundled pip to 22.0.4 (GH-31819) (GH-31851) Message-ID: https://github.com/python/cpython/commit/7a315d8a0d4df01f96d82286739b86920ccebc05 commit: 7a315d8a0d4df01f96d82286739b86920ccebc05 branch: 3.8 author: Ned Deily committer: ambv date: 2022-03-15T15:39:50+01:00 summary: bpo-46985: Upgrade bundled pip to 22.0.4 (GH-31819) (GH-31851) (cherry picked from commit d87f1b787ed38dfd307d82452f2efe9dc5b93942) Co-authored-by: Pradyun Gedam files: A Lib/ensurepip/_bundled/pip-22.0.4-py3-none-any.whl A Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst D Lib/ensurepip/_bundled/pip-21.1.1-py3-none-any.whl M Lib/ensurepip/__init__.py diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index 597a1ef9eeaa1..b291e9afb1897 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -8,11 +8,9 @@ __all__ = ["version", "bootstrap"] - +_PACKAGE_NAMES = ('setuptools', 'pip') _SETUPTOOLS_VERSION = "56.0.0" - -_PIP_VERSION = "21.1.1" - +_PIP_VERSION = "22.0.4" _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION, "py3"), ("pip", _PIP_VERSION, "py3"), diff --git a/Lib/ensurepip/_bundled/pip-21.1.1-py3-none-any.whl b/Lib/ensurepip/_bundled/pip-21.1.1-py3-none-any.whl deleted file mode 100644 index 291cc296fa7b4..0000000000000 Binary files a/Lib/ensurepip/_bundled/pip-21.1.1-py3-none-any.whl and /dev/null differ diff --git a/Lib/ensurepip/_bundled/pip-22.0.4-py3-none-any.whl b/Lib/ensurepip/_bundled/pip-22.0.4-py3-none-any.whl new file mode 100644 index 0000000000000..7ba048e245227 Binary files /dev/null and b/Lib/ensurepip/_bundled/pip-22.0.4-py3-none-any.whl differ diff --git a/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst b/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst new file mode 100644 index 0000000000000..2e08ee837f583 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst @@ -0,0 +1 @@ +Upgrade pip wheel bundled with ensurepip (pip 22.0.4) From webhook-mailer at python.org Tue Mar 15 10:59:13 2022 From: webhook-mailer at python.org (asvetlov) Date: Tue, 15 Mar 2022 14:59:13 -0000 Subject: [Python-checkins] bpo-43253: Don't call shutdown() for invalid socket handles (GH-31892) Message-ID: https://github.com/python/cpython/commit/70155412f1543f100d4aa309b8691cbcabd3e0e1 commit: 70155412f1543f100d4aa309b8691cbcabd3e0e1 branch: main author: Maximilian Hils committer: asvetlov date: 2022-03-15T16:59:02+02:00 summary: bpo-43253: Don't call shutdown() for invalid socket handles (GH-31892) files: A Misc/NEWS.d/next/Library/2022-03-15-07-53-45.bpo-43253.rjdLFj.rst M Lib/asyncio/proactor_events.py M Lib/test/test_asyncio/test_proactor_events.py diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index 087f0950d118b..ff6d08f78eecb 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -158,7 +158,7 @@ def _call_connection_lost(self, exc): # end then it may fail with ERROR_NETNAME_DELETED if we # just close our end. First calling shutdown() seems to # cure it, but maybe using DisconnectEx() would be better. - if hasattr(self._sock, 'shutdown'): + if hasattr(self._sock, 'shutdown') and self._sock.fileno() != -1: self._sock.shutdown(socket.SHUT_RDWR) self._sock.close() self._sock = None diff --git a/Lib/test/test_asyncio/test_proactor_events.py b/Lib/test/test_asyncio/test_proactor_events.py index 67573823ecb22..7fca0541ee75a 100644 --- a/Lib/test/test_asyncio/test_proactor_events.py +++ b/Lib/test/test_asyncio/test_proactor_events.py @@ -242,6 +242,14 @@ def test_close_buffer(self): test_utils.run_briefly(self.loop) self.assertFalse(self.protocol.connection_lost.called) + def test_close_invalid_sockobj(self): + tr = self.socket_transport() + self.sock.fileno.return_value = -1 + tr.close() + test_utils.run_briefly(self.loop) + self.protocol.connection_lost.assert_called_with(None) + self.assertFalse(self.sock.shutdown.called) + @mock.patch('asyncio.base_events.logger') def test_fatal_error(self, m_logging): tr = self.socket_transport() diff --git a/Misc/NEWS.d/next/Library/2022-03-15-07-53-45.bpo-43253.rjdLFj.rst b/Misc/NEWS.d/next/Library/2022-03-15-07-53-45.bpo-43253.rjdLFj.rst new file mode 100644 index 0000000000000..b9920cb821b35 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-15-07-53-45.bpo-43253.rjdLFj.rst @@ -0,0 +1 @@ +Fix a crash when closing transports where the underlying socket handle is already invalid on the Proactor event loop. From webhook-mailer at python.org Tue Mar 15 11:04:51 2022 From: webhook-mailer at python.org (ned-deily) Date: Tue, 15 Mar 2022 15:04:51 -0000 Subject: [Python-checkins] bpo-46907: Update macOS installer to SQLite 3.38.1. (GH-31656) Message-ID: https://github.com/python/cpython/commit/ea786a882b9ed4261eafabad6011bc7ef3b5bf94 commit: ea786a882b9ed4261eafabad6011bc7ef3b5bf94 branch: main author: Mariusz Felisiak committer: ned-deily date: 2022-03-15T11:04:41-04:00 summary: bpo-46907: Update macOS installer to SQLite 3.38.1. (GH-31656) files: A Misc/NEWS.d/next/macOS/2022-03-13-11-11-31.bpo-46907.Ql0z1E.rst M Mac/BuildScript/build-installer.py diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index 7e89a3bc82ae2..4a115e1a5f773 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -358,9 +358,9 @@ def library_recipes(): ), ), dict( - name="SQLite 3.37.2", - url="https://sqlite.org/2022/sqlite-autoconf-3370200.tar.gz", - checksum='683cc5312ee74e71079c14d24b7a6d27', + name="SQLite 3.38.1", + url="https://sqlite.org/2022/sqlite-autoconf-3380100.tar.gz", + checksum="5af57892dc0993af596bef56931db23f", extra_cflags=('-Os ' '-DSQLITE_ENABLE_FTS5 ' '-DSQLITE_ENABLE_FTS4 ' diff --git a/Misc/NEWS.d/next/macOS/2022-03-13-11-11-31.bpo-46907.Ql0z1E.rst b/Misc/NEWS.d/next/macOS/2022-03-13-11-11-31.bpo-46907.Ql0z1E.rst new file mode 100644 index 0000000000000..365081f78e22c --- /dev/null +++ b/Misc/NEWS.d/next/macOS/2022-03-13-11-11-31.bpo-46907.Ql0z1E.rst @@ -0,0 +1 @@ +Update macOS installer to SQLite 3.38.1. From webhook-mailer at python.org Tue Mar 15 11:14:28 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 15 Mar 2022 15:14:28 -0000 Subject: [Python-checkins] bpo-20392: Fix inconsistency with uppercase file extensions in mimetypes.guess_type (GH-30229) Message-ID: https://github.com/python/cpython/commit/3c4f24face4cca9256ae79bf6968663a04daf655 commit: 3c4f24face4cca9256ae79bf6968663a04daf655 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-15T08:14:19-07:00 summary: bpo-20392: Fix inconsistency with uppercase file extensions in mimetypes.guess_type (GH-30229) (cherry picked from commit 5dd7ec52b83e7f239774cf7478106fcc7b0a36f3) Co-authored-by: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> files: A Misc/NEWS.d/next/Library/2021-12-22-12-02-27.bpo-20392.CLAFIp.rst M Lib/mimetypes.py M Lib/test/test_mimetypes.py diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index c389685c08f6f..b72ce083a69d0 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -141,25 +141,23 @@ def guess_type(self, url, strict=True): type = 'text/plain' return type, None # never compressed, so encoding is None base, ext = posixpath.splitext(url) - while ext in self.suffix_map: - base, ext = posixpath.splitext(base + self.suffix_map[ext]) + while (ext_lower := ext.lower()) in self.suffix_map: + base, ext = posixpath.splitext(base + self.suffix_map[ext_lower]) + # encodings_map is case sensitive if ext in self.encodings_map: encoding = self.encodings_map[ext] base, ext = posixpath.splitext(base) else: encoding = None + ext = ext.lower() types_map = self.types_map[True] if ext in types_map: return types_map[ext], encoding - elif ext.lower() in types_map: - return types_map[ext.lower()], encoding elif strict: return None, encoding types_map = self.types_map[False] if ext in types_map: return types_map[ext], encoding - elif ext.lower() in types_map: - return types_map[ext.lower()], encoding else: return None, encoding diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 4098a22644092..f31ea4664f4d3 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -33,6 +33,13 @@ def tearDownModule(): class MimeTypesTestCase(unittest.TestCase): def setUp(self): self.db = mimetypes.MimeTypes() + + def test_case_sensitivity(self): + eq = self.assertEqual + eq(self.db.guess_type("foobar.HTML"), self.db.guess_type("foobar.html")) + eq(self.db.guess_type("foobar.TGZ"), self.db.guess_type("foobar.tgz")) + eq(self.db.guess_type("foobar.tar.Z"), ("application/x-tar", "compress")) + eq(self.db.guess_type("foobar.tar.z"), (None, None)) def test_default_data(self): eq = self.assertEqual diff --git a/Misc/NEWS.d/next/Library/2021-12-22-12-02-27.bpo-20392.CLAFIp.rst b/Misc/NEWS.d/next/Library/2021-12-22-12-02-27.bpo-20392.CLAFIp.rst new file mode 100644 index 0000000000000..8973c4d433174 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-12-22-12-02-27.bpo-20392.CLAFIp.rst @@ -0,0 +1 @@ +Fix inconsistency with uppercase file extensions in :meth:`MimeTypes.guess_type`. Patch by Kumar Aditya. From webhook-mailer at python.org Tue Mar 15 11:22:10 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 15 Mar 2022 15:22:10 -0000 Subject: [Python-checkins] bpo-43253: Don't call shutdown() for invalid socket handles (GH-31892) Message-ID: https://github.com/python/cpython/commit/88c243fd8d5a43282ef06bd0872e3b88c68bb856 commit: 88c243fd8d5a43282ef06bd0872e3b88c68bb856 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-15T08:22:01-07:00 summary: bpo-43253: Don't call shutdown() for invalid socket handles (GH-31892) (cherry picked from commit 70155412f1543f100d4aa309b8691cbcabd3e0e1) Co-authored-by: Maximilian Hils files: A Misc/NEWS.d/next/Library/2022-03-15-07-53-45.bpo-43253.rjdLFj.rst M Lib/asyncio/proactor_events.py M Lib/test/test_asyncio/test_proactor_events.py diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index e551896395b84..411685bbda55e 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -158,7 +158,7 @@ def _call_connection_lost(self, exc): # end then it may fail with ERROR_NETNAME_DELETED if we # just close our end. First calling shutdown() seems to # cure it, but maybe using DisconnectEx() would be better. - if hasattr(self._sock, 'shutdown'): + if hasattr(self._sock, 'shutdown') and self._sock.fileno() != -1: self._sock.shutdown(socket.SHUT_RDWR) self._sock.close() self._sock = None diff --git a/Lib/test/test_asyncio/test_proactor_events.py b/Lib/test/test_asyncio/test_proactor_events.py index c024477e3baba..fc6ee1c1c423e 100644 --- a/Lib/test/test_asyncio/test_proactor_events.py +++ b/Lib/test/test_asyncio/test_proactor_events.py @@ -241,6 +241,14 @@ def test_close_buffer(self): test_utils.run_briefly(self.loop) self.assertFalse(self.protocol.connection_lost.called) + def test_close_invalid_sockobj(self): + tr = self.socket_transport() + self.sock.fileno.return_value = -1 + tr.close() + test_utils.run_briefly(self.loop) + self.protocol.connection_lost.assert_called_with(None) + self.assertFalse(self.sock.shutdown.called) + @mock.patch('asyncio.base_events.logger') def test_fatal_error(self, m_logging): tr = self.socket_transport() diff --git a/Misc/NEWS.d/next/Library/2022-03-15-07-53-45.bpo-43253.rjdLFj.rst b/Misc/NEWS.d/next/Library/2022-03-15-07-53-45.bpo-43253.rjdLFj.rst new file mode 100644 index 0000000000000..b9920cb821b35 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-15-07-53-45.bpo-43253.rjdLFj.rst @@ -0,0 +1 @@ +Fix a crash when closing transports where the underlying socket handle is already invalid on the Proactor event loop. From webhook-mailer at python.org Tue Mar 15 11:23:53 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 15 Mar 2022 15:23:53 -0000 Subject: [Python-checkins] bpo-43253: Don't call shutdown() for invalid socket handles (GH-31892) Message-ID: https://github.com/python/cpython/commit/64a68c39cb508b016e5a4486ebb4052f6e65fca0 commit: 64a68c39cb508b016e5a4486ebb4052f6e65fca0 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-15T08:23:47-07:00 summary: bpo-43253: Don't call shutdown() for invalid socket handles (GH-31892) (cherry picked from commit 70155412f1543f100d4aa309b8691cbcabd3e0e1) Co-authored-by: Maximilian Hils files: A Misc/NEWS.d/next/Library/2022-03-15-07-53-45.bpo-43253.rjdLFj.rst M Lib/asyncio/proactor_events.py M Lib/test/test_asyncio/test_proactor_events.py diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index 6762253abc967..e3f95cf21d617 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -158,7 +158,7 @@ def _call_connection_lost(self, exc): # end then it may fail with ERROR_NETNAME_DELETED if we # just close our end. First calling shutdown() seems to # cure it, but maybe using DisconnectEx() would be better. - if hasattr(self._sock, 'shutdown'): + if hasattr(self._sock, 'shutdown') and self._sock.fileno() != -1: self._sock.shutdown(socket.SHUT_RDWR) self._sock.close() self._sock = None diff --git a/Lib/test/test_asyncio/test_proactor_events.py b/Lib/test/test_asyncio/test_proactor_events.py index 1bbb487626e89..acf21494823ae 100644 --- a/Lib/test/test_asyncio/test_proactor_events.py +++ b/Lib/test/test_asyncio/test_proactor_events.py @@ -237,6 +237,14 @@ def test_close_buffer(self): test_utils.run_briefly(self.loop) self.assertFalse(self.protocol.connection_lost.called) + def test_close_invalid_sockobj(self): + tr = self.socket_transport() + self.sock.fileno.return_value = -1 + tr.close() + test_utils.run_briefly(self.loop) + self.protocol.connection_lost.assert_called_with(None) + self.assertFalse(self.sock.shutdown.called) + @mock.patch('asyncio.base_events.logger') def test_fatal_error(self, m_logging): tr = self.socket_transport() diff --git a/Misc/NEWS.d/next/Library/2022-03-15-07-53-45.bpo-43253.rjdLFj.rst b/Misc/NEWS.d/next/Library/2022-03-15-07-53-45.bpo-43253.rjdLFj.rst new file mode 100644 index 0000000000000..b9920cb821b35 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-15-07-53-45.bpo-43253.rjdLFj.rst @@ -0,0 +1 @@ +Fix a crash when closing transports where the underlying socket handle is already invalid on the Proactor event loop. From webhook-mailer at python.org Tue Mar 15 11:32:42 2022 From: webhook-mailer at python.org (ned-deily) Date: Tue, 15 Mar 2022 15:32:42 -0000 Subject: [Python-checkins] Tidy changelog by removing redundant intermediate expat update items. (GH-31907) Message-ID: https://github.com/python/cpython/commit/5263afe43c8df1ad69b8fa0df742767e5d9df722 commit: 5263afe43c8df1ad69b8fa0df742767e5d9df722 branch: 3.7 author: Ned Deily committer: ned-deily date: 2022-03-15T11:32:37-04:00 summary: Tidy changelog by removing redundant intermediate expat update items. (GH-31907) files: D Misc/NEWS.d/next/Core and Builtins/2022-02-22-12-07-53.bpo-46794.6WvJ9o.rst D Misc/NEWS.d/next/Library/2022-01-30-15-16-12.bpo-46400.vweUiO.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-22-12-07-53.bpo-46794.6WvJ9o.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-22-12-07-53.bpo-46794.6WvJ9o.rst deleted file mode 100644 index 127387d32cb7a..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-22-12-07-53.bpo-46794.6WvJ9o.rst +++ /dev/null @@ -1 +0,0 @@ -Bump up the libexpat version into 2.4.6 diff --git a/Misc/NEWS.d/next/Library/2022-01-30-15-16-12.bpo-46400.vweUiO.rst b/Misc/NEWS.d/next/Library/2022-01-30-15-16-12.bpo-46400.vweUiO.rst deleted file mode 100644 index 9c1f24c0e5171..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-30-15-16-12.bpo-46400.vweUiO.rst +++ /dev/null @@ -1 +0,0 @@ -expat: Update libexpat from 2.4.1 to 2.4.4 From webhook-mailer at python.org Tue Mar 15 11:50:34 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 15 Mar 2022 15:50:34 -0000 Subject: [Python-checkins] bpo-20392: Fix inconsistency with uppercase file extensions in mimetypes.guess_type (GH-30229) Message-ID: https://github.com/python/cpython/commit/32ae9ab55f2cd97b5a28d5398c4820d8bc96f30c commit: 32ae9ab55f2cd97b5a28d5398c4820d8bc96f30c branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-15T08:50:01-07:00 summary: bpo-20392: Fix inconsistency with uppercase file extensions in mimetypes.guess_type (GH-30229) (cherry picked from commit 5dd7ec52b83e7f239774cf7478106fcc7b0a36f3) Co-authored-by: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> files: A Misc/NEWS.d/next/Library/2021-12-22-12-02-27.bpo-20392.CLAFIp.rst M Lib/mimetypes.py M Lib/test/test_mimetypes.py diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index d36e1664cdcc8..58ace01b41ab1 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -135,25 +135,23 @@ def guess_type(self, url, strict=True): type = 'text/plain' return type, None # never compressed, so encoding is None base, ext = posixpath.splitext(url) - while ext in self.suffix_map: - base, ext = posixpath.splitext(base + self.suffix_map[ext]) + while (ext_lower := ext.lower()) in self.suffix_map: + base, ext = posixpath.splitext(base + self.suffix_map[ext_lower]) + # encodings_map is case sensitive if ext in self.encodings_map: encoding = self.encodings_map[ext] base, ext = posixpath.splitext(base) else: encoding = None + ext = ext.lower() types_map = self.types_map[True] if ext in types_map: return types_map[ext], encoding - elif ext.lower() in types_map: - return types_map[ext.lower()], encoding elif strict: return None, encoding types_map = self.types_map[False] if ext in types_map: return types_map[ext], encoding - elif ext.lower() in types_map: - return types_map[ext.lower()], encoding else: return None, encoding diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 5d0615e99b4e4..254b8f8a4aeb7 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -27,6 +27,13 @@ def tearDownModule(): class MimeTypesTestCase(unittest.TestCase): def setUp(self): self.db = mimetypes.MimeTypes() + + def test_case_sensitivity(self): + eq = self.assertEqual + eq(self.db.guess_type("foobar.HTML"), self.db.guess_type("foobar.html")) + eq(self.db.guess_type("foobar.TGZ"), self.db.guess_type("foobar.tgz")) + eq(self.db.guess_type("foobar.tar.Z"), ("application/x-tar", "compress")) + eq(self.db.guess_type("foobar.tar.z"), (None, None)) def test_default_data(self): eq = self.assertEqual diff --git a/Misc/NEWS.d/next/Library/2021-12-22-12-02-27.bpo-20392.CLAFIp.rst b/Misc/NEWS.d/next/Library/2021-12-22-12-02-27.bpo-20392.CLAFIp.rst new file mode 100644 index 0000000000000..8973c4d433174 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-12-22-12-02-27.bpo-20392.CLAFIp.rst @@ -0,0 +1 @@ +Fix inconsistency with uppercase file extensions in :meth:`MimeTypes.guess_type`. Patch by Kumar Aditya. From webhook-mailer at python.org Tue Mar 15 12:14:24 2022 From: webhook-mailer at python.org (tiran) Date: Tue, 15 Mar 2022 16:14:24 -0000 Subject: [Python-checkins] bpo-40280: Skip wakeup_fd pipe tests on Emscripten (GH-31909) Message-ID: https://github.com/python/cpython/commit/b43b9b49be7d42d2826106c719d1e51f0776be0a commit: b43b9b49be7d42d2826106c719d1e51f0776be0a branch: main author: Christian Heimes committer: tiran date: 2022-03-15T17:14:15+01:00 summary: bpo-40280: Skip wakeup_fd pipe tests on Emscripten (GH-31909) files: M Lib/test/test_signal.py diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py index 09de608bb771f..37b46065e532c 100644 --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -205,6 +205,9 @@ def test_invalid_socket(self): self.assertRaises((ValueError, OSError), signal.set_wakeup_fd, fd) + # Emscripten does not support fstat on pipes yet. + # https://github.com/emscripten-core/emscripten/issues/16414 + @unittest.skipIf(support.is_emscripten, "Emscripten cannot fstat pipes.") def test_set_wakeup_fd_result(self): r1, w1 = os.pipe() self.addCleanup(os.close, r1) @@ -222,6 +225,7 @@ def test_set_wakeup_fd_result(self): self.assertEqual(signal.set_wakeup_fd(-1), w2) self.assertEqual(signal.set_wakeup_fd(-1), -1) + @unittest.skipIf(support.is_emscripten, "Emscripten cannot fstat pipes.") def test_set_wakeup_fd_socket_result(self): sock1 = socket.socket() self.addCleanup(sock1.close) @@ -241,6 +245,7 @@ def test_set_wakeup_fd_socket_result(self): # On Windows, files are always blocking and Windows does not provide a # function to test if a socket is in non-blocking mode. @unittest.skipIf(sys.platform == "win32", "tests specific to POSIX") + @unittest.skipIf(support.is_emscripten, "Emscripten cannot fstat pipes.") def test_set_wakeup_fd_blocking(self): rfd, wfd = os.pipe() self.addCleanup(os.close, rfd) From webhook-mailer at python.org Tue Mar 15 12:55:22 2022 From: webhook-mailer at python.org (zooba) Date: Tue, 15 Mar 2022 16:55:22 -0000 Subject: [Python-checkins] bpo-46907: Update Windows installer to SQLite 3.38.1. (GH-31655) Message-ID: https://github.com/python/cpython/commit/a8c728b8b742fd8ca5a225f79d99014794b8fdf3 commit: a8c728b8b742fd8ca5a225f79d99014794b8fdf3 branch: main author: Mariusz Felisiak committer: zooba date: 2022-03-15T16:55:10Z summary: bpo-46907: Update Windows installer to SQLite 3.38.1. (GH-31655) files: A Misc/NEWS.d/next/Windows/2022-03-13-11-18-41.bpo-46907.YLzxBM.rst M PCbuild/get_externals.bat M PCbuild/python.props M PCbuild/readme.txt diff --git a/Misc/NEWS.d/next/Windows/2022-03-13-11-18-41.bpo-46907.YLzxBM.rst b/Misc/NEWS.d/next/Windows/2022-03-13-11-18-41.bpo-46907.YLzxBM.rst new file mode 100644 index 0000000000000..7f3b875a59635 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-03-13-11-18-41.bpo-46907.YLzxBM.rst @@ -0,0 +1 @@ +Update Windows installer to use SQLite 3.38.1. diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index b8279e2c7892a..a8c3886a789ef 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -54,7 +54,7 @@ set libraries= set libraries=%libraries% bzip2-1.0.8 if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.4.2 if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1m -set libraries=%libraries% sqlite-3.37.2.0 +set libraries=%libraries% sqlite-3.38.1.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.12.1 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.12.1 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tix-8.4.3.6 diff --git a/PCbuild/python.props b/PCbuild/python.props index 71531b5a23611..67f8d48c21336 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -61,7 +61,7 @@ $(EXTERNALS_DIR) $([System.IO.Path]::GetFullPath(`$(PySourcePath)externals`)) $(ExternalsDir)\ - $(ExternalsDir)sqlite-3.37.2.0\ + $(ExternalsDir)sqlite-3.38.1.0\ $(ExternalsDir)bzip2-1.0.8\ $(ExternalsDir)xz-5.2.2\ $(ExternalsDir)libffi-3.4.2\ diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index 69531f065561e..24bce197389e0 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -189,7 +189,7 @@ _ssl again when building. _sqlite3 - Wraps SQLite 3.37.2, which is itself built by sqlite3.vcxproj + Wraps SQLite 3.38.1, which is itself built by sqlite3.vcxproj Homepage: http://www.sqlite.org/ _tkinter From webhook-mailer at python.org Tue Mar 15 13:06:50 2022 From: webhook-mailer at python.org (markshannon) Date: Tue, 15 Mar 2022 17:06:50 -0000 Subject: [Python-checkins] bpo-45923: Decouple suspension of tracing from tracing flag. (GH-31908) Message-ID: https://github.com/python/cpython/commit/099f75614100e88ed90b68d20a51a8d9c22f81a7 commit: 099f75614100e88ed90b68d20a51a8d9c22f81a7 branch: main author: Mark Shannon committer: markshannon date: 2022-03-15T17:06:21Z summary: bpo-45923: Decouple suspension of tracing from tracing flag. (GH-31908) files: M Include/internal/pycore_pystate.h M Python/ceval.c M Python/pystate.c diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index f0c238a608b10..c4bc53c707fda 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -139,14 +139,9 @@ PyAPI_FUNC(void) _PyThreadState_DeleteExcept( _PyRuntimeState *runtime, PyThreadState *tstate); -static inline void -_PyThreadState_PauseTracing(PyThreadState *tstate) -{ - tstate->cframe->use_tracing = 0; -} static inline void -_PyThreadState_ResumeTracing(PyThreadState *tstate) +_PyThreadState_UpdateTracingState(PyThreadState *tstate) { int use_tracing = (tstate->c_tracefunc != NULL || tstate->c_profilefunc != NULL); diff --git a/Python/ceval.c b/Python/ceval.c index adbf1f689d908..d0fc31ec6c5d8 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -5439,10 +5439,12 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } #if USE_COMPUTED_GOTOS - TARGET_DO_TRACING: { + TARGET_DO_TRACING: #else - case DO_TRACING: { + case DO_TRACING: #endif + { + if (tstate->tracing == 0) { int instr_prev = skip_backwards_over_extended_args(frame->f_code, frame->f_lasti); frame->f_lasti = INSTR_OFFSET(); TRACING_NEXTOPARG(); @@ -5482,11 +5484,11 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int frame->stacktop = -1; } } - TRACING_NEXTOPARG(); - PRE_DISPATCH_GOTO(); - DISPATCH_GOTO(); } - + TRACING_NEXTOPARG(); + PRE_DISPATCH_GOTO(); + DISPATCH_GOTO(); + } #if USE_COMPUTED_GOTOS _unknown_opcode: @@ -6673,27 +6675,38 @@ initialize_trace_info(PyTraceInfo *trace_info, _PyInterpreterFrame *frame) } } +void +PyThreadState_EnterTracing(PyThreadState *tstate) +{ + tstate->tracing++; +} + +void +PyThreadState_LeaveTracing(PyThreadState *tstate) +{ + tstate->tracing--; +} + static int call_trace(Py_tracefunc func, PyObject *obj, PyThreadState *tstate, _PyInterpreterFrame *frame, int what, PyObject *arg) { int result; - if (tstate->tracing) + if (tstate->tracing) { return 0; - tstate->tracing++; - _PyThreadState_PauseTracing(tstate); + } PyFrameObject *f = _PyFrame_GetFrameObject(frame); if (f == NULL) { return -1; } + PyThreadState_EnterTracing(tstate); assert (frame->f_lasti >= 0); initialize_trace_info(&tstate->trace_info, frame); f->f_lineno = _PyCode_CheckLineNumber(frame->f_lasti*sizeof(_Py_CODEUNIT), &tstate->trace_info.bounds); result = func(obj, f, what, arg); f->f_lineno = 0; - _PyThreadState_ResumeTracing(tstate); - tstate->tracing--; + PyThreadState_LeaveTracing(tstate); return result; } @@ -6706,7 +6719,6 @@ _PyEval_CallTracing(PyObject *func, PyObject *args) PyObject *result; tstate->tracing = 0; - _PyThreadState_ResumeTracing(tstate); result = PyObject_Call(func, args, NULL); tstate->tracing = save_tracing; tstate->cframe->use_tracing = save_use_tracing; @@ -6773,7 +6785,7 @@ _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) tstate->c_profilefunc = NULL; tstate->c_profileobj = NULL; /* Must make sure that tracing is not ignored if 'profileobj' is freed */ - _PyThreadState_ResumeTracing(tstate); + _PyThreadState_UpdateTracingState(tstate); Py_XDECREF(profileobj); Py_XINCREF(arg); @@ -6781,7 +6793,7 @@ _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) tstate->c_profilefunc = func; /* Flag that tracing or profiling is turned on */ - _PyThreadState_ResumeTracing(tstate); + _PyThreadState_UpdateTracingState(tstate); return 0; } @@ -6814,7 +6826,7 @@ _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) tstate->c_tracefunc = NULL; tstate->c_traceobj = NULL; /* Must make sure that profiling is not ignored if 'traceobj' is freed */ - _PyThreadState_ResumeTracing(tstate); + _PyThreadState_UpdateTracingState(tstate); Py_XDECREF(traceobj); Py_XINCREF(arg); @@ -6822,7 +6834,7 @@ _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) tstate->c_tracefunc = func; /* Flag that tracing or profiling is turned on */ - _PyThreadState_ResumeTracing(tstate); + _PyThreadState_UpdateTracingState(tstate); return 0; } diff --git a/Python/pystate.c b/Python/pystate.c index edf2f62431f3d..1b4e31b95cd0b 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -1333,23 +1333,6 @@ PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc) return 0; } - -void -PyThreadState_EnterTracing(PyThreadState *tstate) -{ - tstate->tracing++; - _PyThreadState_PauseTracing(tstate); -} - -void -PyThreadState_LeaveTracing(PyThreadState *tstate) -{ - tstate->tracing--; - _PyThreadState_ResumeTracing(tstate); -} - - - /* Routines for advanced debuggers, requested by David Beazley. Don't use unless you know what you are doing! */ From webhook-mailer at python.org Tue Mar 15 15:30:55 2022 From: webhook-mailer at python.org (ned-deily) Date: Tue, 15 Mar 2022 19:30:55 -0000 Subject: [Python-checkins] bpo-47024: Update Windows builds and macOS installer build to use OpenSSL 1.1.1n. (GH-31911) Message-ID: https://github.com/python/cpython/commit/b6204466c1209de5a0794c475096429fdb457a16 commit: b6204466c1209de5a0794c475096429fdb457a16 branch: 3.7 author: Ned Deily committer: ned-deily date: 2022-03-15T15:30:49-04:00 summary: bpo-47024: Update Windows builds and macOS installer build to use OpenSSL 1.1.1n. (GH-31911) files: A Misc/NEWS.d/next/Build/2022-03-15-11-53-10.bpo-47024.p3PjRy.rst M .azure-pipelines/ci.yml M .azure-pipelines/pr.yml M .github/workflows/build.yml M .github/workflows/coverage.yml M Mac/BuildScript/build-installer.py M PCbuild/get_externals.bat M PCbuild/python.props M Tools/ssl/multissltests.py diff --git a/.azure-pipelines/ci.yml b/.azure-pipelines/ci.yml index b9070a4e00a74..eaaa88c9634f5 100644 --- a/.azure-pipelines/ci.yml +++ b/.azure-pipelines/ci.yml @@ -61,7 +61,7 @@ jobs: variables: testRunTitle: '$(build.sourceBranchName)-linux' testRunPlatform: linux - openssl_version: 1.1.1g + openssl_version: 1.1.1n steps: - template: ./posix-steps.yml @@ -118,7 +118,7 @@ jobs: variables: testRunTitle: '$(Build.SourceBranchName)-linux-coverage' testRunPlatform: linux-coverage - openssl_version: 1.1.1g + openssl_version: 1.1.1n steps: - template: ./posix-steps.yml diff --git a/.azure-pipelines/pr.yml b/.azure-pipelines/pr.yml index 026e2835596d0..7f01f8b25c2cc 100644 --- a/.azure-pipelines/pr.yml +++ b/.azure-pipelines/pr.yml @@ -61,7 +61,7 @@ jobs: variables: testRunTitle: '$(system.pullRequest.TargetBranch)-linux' testRunPlatform: linux - openssl_version: 1.1.1g + openssl_version: 1.1.1n steps: - template: ./posix-steps.yml @@ -118,7 +118,7 @@ jobs: variables: testRunTitle: '$(Build.SourceBranchName)-linux-coverage' testRunPlatform: linux-coverage - openssl_version: 1.1.1g + openssl_version: 1.1.1n steps: - template: ./posix-steps.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4678b2d1187a6..530eba70b5ba2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -77,7 +77,7 @@ jobs: needs: check_source if: needs.check_source.outputs.run_tests == 'true' env: - OPENSSL_VER: 1.1.1f + OPENSSL_VER: 1.1.1n steps: - uses: actions/checkout at v2 - name: Install Dependencies diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index bfb077b299474..762cdb5ab2188 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -23,7 +23,7 @@ jobs: name: 'Ubuntu (Coverage)' runs-on: ubuntu-latest env: - OPENSSL_VER: 1.1.1f + OPENSSL_VER: 1.1.1n steps: - uses: actions/checkout at v2 - name: Install Dependencies diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index 4fab4882efaeb..76078dcd22c39 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -209,9 +209,9 @@ def library_recipes(): result.extend([ dict( - name="OpenSSL 1.1.1g", - url="https://www.openssl.org/source/openssl-1.1.1g.tar.gz", - checksum='76766e98997660138cdaf13a187bd234', + name="OpenSSL 1.1.1n", + url="https://www.openssl.org/source/openssl-1.1.1n.tar.gz", + checksum='2aad5635f9bb338bc2c6b7d19cbc9676', buildrecipe=build_universal_openssl, configure=None, install=None, diff --git a/Misc/NEWS.d/next/Build/2022-03-15-11-53-10.bpo-47024.p3PjRy.rst b/Misc/NEWS.d/next/Build/2022-03-15-11-53-10.bpo-47024.p3PjRy.rst new file mode 100644 index 0000000000000..235ece3c3d2ef --- /dev/null +++ b/Misc/NEWS.d/next/Build/2022-03-15-11-53-10.bpo-47024.p3PjRy.rst @@ -0,0 +1 @@ +Update Windows builds and macOS installer build to use OpenSSL 1.1.1n. diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index 9c7f81542ed04..677a6a41ab611 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -49,7 +49,7 @@ echo.Fetching external libraries... set libraries= set libraries=%libraries% bzip2-1.0.8 -if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1g +if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1n set libraries=%libraries% sqlite-3.31.1.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.9.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.9.0 @@ -72,7 +72,7 @@ for %%e in (%libraries%) do ( echo.Fetching external binaries... set binaries= -if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1g +if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1n if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.9.0 if NOT "%IncludeSSLSrc%"=="false" set binaries=%binaries% nasm-2.11.06 diff --git a/PCbuild/python.props b/PCbuild/python.props index d3ad12c72830b..296bfd637bf9e 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -49,8 +49,8 @@ $(ExternalsDir)sqlite-3.31.1.0\ $(ExternalsDir)bzip2-1.0.8\ $(ExternalsDir)xz-5.2.2\ - $(ExternalsDir)openssl-1.1.1g\ - $(ExternalsDir)openssl-bin-1.1.1g\$(ArchName)\ + $(ExternalsDir)openssl-1.1.1n\ + $(ExternalsDir)openssl-bin-1.1.1n\$(ArchName)\ $(opensslOutDir)include $(ExternalsDir)\nasm-2.11.06\ $(ExternalsDir)\zlib-1.2.11\ diff --git a/Tools/ssl/multissltests.py b/Tools/ssl/multissltests.py index 3818165a836fb..dc74f8d401ee7 100755 --- a/Tools/ssl/multissltests.py +++ b/Tools/ssl/multissltests.py @@ -48,7 +48,7 @@ ] OPENSSL_RECENT_VERSIONS = [ - "1.1.1g", + "1.1.1n", # "3.0.0-alpha2" ] From webhook-mailer at python.org Tue Mar 15 16:03:28 2022 From: webhook-mailer at python.org (tiran) Date: Tue, 15 Mar 2022 20:03:28 -0000 Subject: [Python-checkins] bpo-47024: Update OpenSSL to 1.1.1n (GH-31895) Message-ID: https://github.com/python/cpython/commit/af0a50de4b77dc774fcfdf5468ec320b08bfb53b commit: af0a50de4b77dc774fcfdf5468ec320b08bfb53b branch: main author: Christian Heimes committer: tiran date: 2022-03-15T21:03:04+01:00 summary: bpo-47024: Update OpenSSL to 1.1.1n (GH-31895) Co-authored-by: Zachary Ware files: A Misc/NEWS.d/next/Build/2022-03-15-09-28-55.bpo-47024.t7-dcu.rst M .azure-pipelines/ci.yml M .azure-pipelines/pr.yml M .github/workflows/build.yml M Mac/BuildScript/build-installer.py M PCbuild/get_externals.bat M PCbuild/python.props M Tools/ssl/multissltests.py diff --git a/.azure-pipelines/ci.yml b/.azure-pipelines/ci.yml index 638625540e44c..199547432be29 100644 --- a/.azure-pipelines/ci.yml +++ b/.azure-pipelines/ci.yml @@ -57,7 +57,7 @@ jobs: variables: testRunTitle: '$(build.sourceBranchName)-linux' testRunPlatform: linux - openssl_version: 1.1.1m + openssl_version: 1.1.1n steps: - template: ./posix-steps.yml @@ -83,7 +83,7 @@ jobs: variables: testRunTitle: '$(Build.SourceBranchName)-linux-coverage' testRunPlatform: linux-coverage - openssl_version: 1.1.1m + openssl_version: 1.1.1n steps: - template: ./posix-steps.yml diff --git a/.azure-pipelines/pr.yml b/.azure-pipelines/pr.yml index 8b065e6caea53..b96a192005a42 100644 --- a/.azure-pipelines/pr.yml +++ b/.azure-pipelines/pr.yml @@ -57,7 +57,7 @@ jobs: variables: testRunTitle: '$(system.pullRequest.TargetBranch)-linux' testRunPlatform: linux - openssl_version: 1.1.1m + openssl_version: 1.1.1n steps: - template: ./posix-steps.yml @@ -83,7 +83,7 @@ jobs: variables: testRunTitle: '$(Build.SourceBranchName)-linux-coverage' testRunPlatform: linux-coverage - openssl_version: 1.1.1m + openssl_version: 1.1.1n steps: - template: ./posix-steps.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8b1709d37f9aa..b950c594709ec 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -167,7 +167,7 @@ jobs: needs: check_source if: needs.check_source.outputs.run_tests == 'true' env: - OPENSSL_VER: 1.1.1m + OPENSSL_VER: 1.1.1n PYTHONSTRICTEXTENSIONBUILD: 1 steps: - uses: actions/checkout at v2 @@ -226,7 +226,7 @@ jobs: strategy: fail-fast: false matrix: - openssl_ver: [1.1.1m, 3.0.1] + openssl_ver: [1.1.1n, 3.0.2] env: OPENSSL_VER: ${{ matrix.openssl_ver }} MULTISSL_DIR: ${{ github.workspace }}/multissl @@ -273,7 +273,7 @@ jobs: needs: check_source if: needs.check_source.outputs.run_tests == 'true' env: - OPENSSL_VER: 1.1.1m + OPENSSL_VER: 1.1.1n PYTHONSTRICTEXTENSIONBUILD: 1 ASAN_OPTIONS: detect_leaks=0:allocator_may_return_null=1:handle_segv=0 steps: diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index 4a115e1a5f773..27719b85f1f50 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -246,9 +246,9 @@ def library_recipes(): result.extend([ dict( - name="OpenSSL 1.1.1m", - url="https://www.openssl.org/source/openssl-1.1.1m.tar.gz", - checksum='8ec70f665c145c3103f6e330f538a9db', + name="OpenSSL 1.1.1n", + url="https://www.openssl.org/source/openssl-1.1.1n.tar.gz", + checksum='2aad5635f9bb338bc2c6b7d19cbc9676', buildrecipe=build_universal_openssl, configure=None, install=None, diff --git a/Misc/NEWS.d/next/Build/2022-03-15-09-28-55.bpo-47024.t7-dcu.rst b/Misc/NEWS.d/next/Build/2022-03-15-09-28-55.bpo-47024.t7-dcu.rst new file mode 100644 index 0000000000000..1035cbab1ba61 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2022-03-15-09-28-55.bpo-47024.t7-dcu.rst @@ -0,0 +1 @@ +Update OpenSSL to 1.1.1n for macOS installers and all Windows builds. diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index a8c3886a789ef..189b31246d545 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -53,7 +53,7 @@ echo.Fetching external libraries... set libraries= set libraries=%libraries% bzip2-1.0.8 if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.4.2 -if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1m +if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1n set libraries=%libraries% sqlite-3.38.1.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.12.1 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.12.1 @@ -77,7 +77,7 @@ echo.Fetching external binaries... set binaries= if NOT "%IncludeLibffi%"=="false" set binaries=%binaries% libffi-3.4.2 -if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1m +if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1n if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.12.1 if NOT "%IncludeSSLSrc%"=="false" set binaries=%binaries% nasm-2.11.06 diff --git a/PCbuild/python.props b/PCbuild/python.props index 67f8d48c21336..e64173737cf72 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -67,8 +67,8 @@ $(ExternalsDir)libffi-3.4.2\ $(ExternalsDir)libffi-3.4.2\$(ArchName)\ $(libffiOutDir)include - $(ExternalsDir)openssl-1.1.1m\ - $(ExternalsDir)openssl-bin-1.1.1m\$(ArchName)\ + $(ExternalsDir)openssl-1.1.1n\ + $(ExternalsDir)openssl-bin-1.1.1n\$(ArchName)\ $(opensslOutDir)include $(ExternalsDir)\nasm-2.11.06\ $(ExternalsDir)\zlib-1.2.11\ diff --git a/Tools/ssl/multissltests.py b/Tools/ssl/multissltests.py index a41cabff534b0..82076808bfd37 100755 --- a/Tools/ssl/multissltests.py +++ b/Tools/ssl/multissltests.py @@ -47,8 +47,8 @@ ] OPENSSL_RECENT_VERSIONS = [ - "1.1.1m", - "3.0.1" + "1.1.1n", + "3.0.2" ] LIBRESSL_OLD_VERSIONS = [ From webhook-mailer at python.org Tue Mar 15 16:31:08 2022 From: webhook-mailer at python.org (tiran) Date: Tue, 15 Mar 2022 20:31:08 -0000 Subject: [Python-checkins] [3.10] bpo-47024: Update OpenSSL to 1.1.1n (GH-31895) (GH-31916) Message-ID: https://github.com/python/cpython/commit/a59ac1e7d20713573c15c5259c83e998a73e9094 commit: a59ac1e7d20713573c15c5259c83e998a73e9094 branch: 3.10 author: Christian Heimes committer: tiran date: 2022-03-15T21:31:00+01:00 summary: [3.10] bpo-47024: Update OpenSSL to 1.1.1n (GH-31895) (GH-31916) Co-authored-by: Zachary Ware . Co-authored-by: Christian Heimes files: A Misc/NEWS.d/next/Build/2022-03-15-09-28-55.bpo-47024.t7-dcu.rst M .azure-pipelines/ci.yml M .azure-pipelines/pr.yml M .github/workflows/build.yml M Mac/BuildScript/build-installer.py M PCbuild/get_externals.bat M PCbuild/python.props M Tools/ssl/multissltests.py diff --git a/.azure-pipelines/ci.yml b/.azure-pipelines/ci.yml index 25cc726504b37..d0efa77f93052 100644 --- a/.azure-pipelines/ci.yml +++ b/.azure-pipelines/ci.yml @@ -57,7 +57,7 @@ jobs: variables: testRunTitle: '$(build.sourceBranchName)-linux' testRunPlatform: linux - openssl_version: 1.1.1m + openssl_version: 1.1.1n steps: - template: ./posix-steps.yml @@ -83,7 +83,7 @@ jobs: variables: testRunTitle: '$(Build.SourceBranchName)-linux-coverage' testRunPlatform: linux-coverage - openssl_version: 1.1.1m + openssl_version: 1.1.1n steps: - template: ./posix-steps.yml diff --git a/.azure-pipelines/pr.yml b/.azure-pipelines/pr.yml index e2aae324f211b..a4f32460c7ea0 100644 --- a/.azure-pipelines/pr.yml +++ b/.azure-pipelines/pr.yml @@ -57,7 +57,7 @@ jobs: variables: testRunTitle: '$(system.pullRequest.TargetBranch)-linux' testRunPlatform: linux - openssl_version: 1.1.1m + openssl_version: 1.1.1n steps: - template: ./posix-steps.yml @@ -83,7 +83,7 @@ jobs: variables: testRunTitle: '$(Build.SourceBranchName)-linux-coverage' testRunPlatform: linux-coverage - openssl_version: 1.1.1m + openssl_version: 1.1.1n steps: - template: ./posix-steps.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1102449a1af06..8bd506c9f3135 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -181,7 +181,7 @@ jobs: needs: check_source if: needs.check_source.outputs.run_tests == 'true' env: - OPENSSL_VER: 1.1.1m + OPENSSL_VER: 1.1.1n PYTHONSTRICTEXTENSIONBUILD: 1 steps: - uses: actions/checkout at v2 @@ -225,7 +225,7 @@ jobs: strategy: fail-fast: false matrix: - openssl_ver: [1.1.1m, 3.0.1] + openssl_ver: [1.1.1n, 3.0.2] env: OPENSSL_VER: ${{ matrix.openssl_ver }} MULTISSL_DIR: ${{ github.workspace }}/multissl diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index 6720c0ba1785e..4308a2003ce73 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -246,9 +246,9 @@ def library_recipes(): result.extend([ dict( - name="OpenSSL 1.1.1m", - url="https://www.openssl.org/source/openssl-1.1.1m.tar.gz", - checksum='8ec70f665c145c3103f6e330f538a9db', + name="OpenSSL 1.1.1n", + url="https://www.openssl.org/source/openssl-1.1.1n.tar.gz", + checksum='2aad5635f9bb338bc2c6b7d19cbc9676', buildrecipe=build_universal_openssl, configure=None, install=None, diff --git a/Misc/NEWS.d/next/Build/2022-03-15-09-28-55.bpo-47024.t7-dcu.rst b/Misc/NEWS.d/next/Build/2022-03-15-09-28-55.bpo-47024.t7-dcu.rst new file mode 100644 index 0000000000000..1035cbab1ba61 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2022-03-15-09-28-55.bpo-47024.t7-dcu.rst @@ -0,0 +1 @@ +Update OpenSSL to 1.1.1n for macOS installers and all Windows builds. diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index 462e0db361d09..7129898c6bc62 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -53,7 +53,7 @@ echo.Fetching external libraries... set libraries= set libraries=%libraries% bzip2-1.0.8 if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.3.0 -if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1m +if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1n set libraries=%libraries% sqlite-3.37.2.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.12.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.12.0 @@ -77,7 +77,7 @@ echo.Fetching external binaries... set binaries= if NOT "%IncludeLibffi%"=="false" set binaries=%binaries% libffi-3.3.0 -if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1m +if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1n if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.12.0 if NOT "%IncludeSSLSrc%"=="false" set binaries=%binaries% nasm-2.11.06 diff --git a/PCbuild/python.props b/PCbuild/python.props index eddb65879d3ab..7a11cfafedf5e 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -63,8 +63,8 @@ $(ExternalsDir)libffi-3.3.0\ $(ExternalsDir)libffi-3.3.0\$(ArchName)\ $(libffiOutDir)include - $(ExternalsDir)openssl-1.1.1m\ - $(ExternalsDir)openssl-bin-1.1.1m\$(ArchName)\ + $(ExternalsDir)openssl-1.1.1n\ + $(ExternalsDir)openssl-bin-1.1.1n\$(ArchName)\ $(opensslOutDir)include $(ExternalsDir)\nasm-2.11.06\ $(ExternalsDir)\zlib-1.2.11\ diff --git a/Tools/ssl/multissltests.py b/Tools/ssl/multissltests.py index a41cabff534b0..82076808bfd37 100755 --- a/Tools/ssl/multissltests.py +++ b/Tools/ssl/multissltests.py @@ -47,8 +47,8 @@ ] OPENSSL_RECENT_VERSIONS = [ - "1.1.1m", - "3.0.1" + "1.1.1n", + "3.0.2" ] LIBRESSL_OLD_VERSIONS = [ From webhook-mailer at python.org Tue Mar 15 16:34:54 2022 From: webhook-mailer at python.org (tiran) Date: Tue, 15 Mar 2022 20:34:54 -0000 Subject: [Python-checkins] [3.9] bpo-47024: Update OpenSSL to 1.1.1n (GH-31895) (#31917) Message-ID: https://github.com/python/cpython/commit/513911b359c88df2b32d0bc2776438f52d5e4584 commit: 513911b359c88df2b32d0bc2776438f52d5e4584 branch: 3.9 author: Christian Heimes committer: tiran date: 2022-03-15T21:34:49+01:00 summary: [3.9] bpo-47024: Update OpenSSL to 1.1.1n (GH-31895) (#31917) Co-authored-by: Zachary Ware . Co-authored-by: Christian Heimes . Co-authored-by: Christian Heimes files: A Misc/NEWS.d/next/Build/2022-03-15-09-28-55.bpo-47024.t7-dcu.rst M .azure-pipelines/ci.yml M .azure-pipelines/pr.yml M .github/workflows/build.yml M Mac/BuildScript/build-installer.py M PCbuild/get_externals.bat M PCbuild/python.props M Tools/ssl/multissltests.py diff --git a/.azure-pipelines/ci.yml b/.azure-pipelines/ci.yml index 25cc726504b37..d0efa77f93052 100644 --- a/.azure-pipelines/ci.yml +++ b/.azure-pipelines/ci.yml @@ -57,7 +57,7 @@ jobs: variables: testRunTitle: '$(build.sourceBranchName)-linux' testRunPlatform: linux - openssl_version: 1.1.1m + openssl_version: 1.1.1n steps: - template: ./posix-steps.yml @@ -83,7 +83,7 @@ jobs: variables: testRunTitle: '$(Build.SourceBranchName)-linux-coverage' testRunPlatform: linux-coverage - openssl_version: 1.1.1m + openssl_version: 1.1.1n steps: - template: ./posix-steps.yml diff --git a/.azure-pipelines/pr.yml b/.azure-pipelines/pr.yml index e2aae324f211b..a4f32460c7ea0 100644 --- a/.azure-pipelines/pr.yml +++ b/.azure-pipelines/pr.yml @@ -57,7 +57,7 @@ jobs: variables: testRunTitle: '$(system.pullRequest.TargetBranch)-linux' testRunPlatform: linux - openssl_version: 1.1.1m + openssl_version: 1.1.1n steps: - template: ./posix-steps.yml @@ -83,7 +83,7 @@ jobs: variables: testRunTitle: '$(Build.SourceBranchName)-linux-coverage' testRunPlatform: linux-coverage - openssl_version: 1.1.1m + openssl_version: 1.1.1n steps: - template: ./posix-steps.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6f1b16537f506..596f4d88e26e9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -165,7 +165,7 @@ jobs: needs: check_source if: needs.check_source.outputs.run_tests == 'true' env: - OPENSSL_VER: 1.1.1m + OPENSSL_VER: 1.1.1n PYTHONSTRICTEXTENSIONBUILD: 1 steps: - uses: actions/checkout at v2 @@ -207,7 +207,7 @@ jobs: strategy: fail-fast: false matrix: - openssl_ver: [1.0.2u, 1.1.0l, 1.1.1m, 3.0.1] + openssl_ver: [1.0.2u, 1.1.0l, 1.1.1n, 3.0.2] env: OPENSSL_VER: ${{ matrix.openssl_ver }} MULTISSL_DIR: ${{ github.workspace }}/multissl diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index 47a01056f2e5c..9909679e0713a 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -244,9 +244,9 @@ def library_recipes(): result.extend([ dict( - name="OpenSSL 1.1.1m", - url="https://www.openssl.org/source/openssl-1.1.1m.tar.gz", - checksum='8ec70f665c145c3103f6e330f538a9db', + name="OpenSSL 1.1.1n", + url="https://www.openssl.org/source/openssl-1.1.1n.tar.gz", + checksum='2aad5635f9bb338bc2c6b7d19cbc9676', buildrecipe=build_universal_openssl, configure=None, install=None, diff --git a/Misc/NEWS.d/next/Build/2022-03-15-09-28-55.bpo-47024.t7-dcu.rst b/Misc/NEWS.d/next/Build/2022-03-15-09-28-55.bpo-47024.t7-dcu.rst new file mode 100644 index 0000000000000..1035cbab1ba61 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2022-03-15-09-28-55.bpo-47024.t7-dcu.rst @@ -0,0 +1 @@ +Update OpenSSL to 1.1.1n for macOS installers and all Windows builds. diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index 462e0db361d09..7129898c6bc62 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -53,7 +53,7 @@ echo.Fetching external libraries... set libraries= set libraries=%libraries% bzip2-1.0.8 if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.3.0 -if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1m +if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1n set libraries=%libraries% sqlite-3.37.2.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.12.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.12.0 @@ -77,7 +77,7 @@ echo.Fetching external binaries... set binaries= if NOT "%IncludeLibffi%"=="false" set binaries=%binaries% libffi-3.3.0 -if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1m +if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1n if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.12.0 if NOT "%IncludeSSLSrc%"=="false" set binaries=%binaries% nasm-2.11.06 diff --git a/PCbuild/python.props b/PCbuild/python.props index eddb65879d3ab..7a11cfafedf5e 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -63,8 +63,8 @@ $(ExternalsDir)libffi-3.3.0\ $(ExternalsDir)libffi-3.3.0\$(ArchName)\ $(libffiOutDir)include - $(ExternalsDir)openssl-1.1.1m\ - $(ExternalsDir)openssl-bin-1.1.1m\$(ArchName)\ + $(ExternalsDir)openssl-1.1.1n\ + $(ExternalsDir)openssl-bin-1.1.1n\$(ArchName)\ $(opensslOutDir)include $(ExternalsDir)\nasm-2.11.06\ $(ExternalsDir)\zlib-1.2.11\ diff --git a/Tools/ssl/multissltests.py b/Tools/ssl/multissltests.py index 437efb22914b8..14c4918acc273 100755 --- a/Tools/ssl/multissltests.py +++ b/Tools/ssl/multissltests.py @@ -49,8 +49,8 @@ ] OPENSSL_RECENT_VERSIONS = [ - "1.1.1m", - "3.0.1" + "1.1.1n", + "3.0.2" ] LIBRESSL_OLD_VERSIONS = [ From webhook-mailer at python.org Tue Mar 15 16:53:58 2022 From: webhook-mailer at python.org (ambv) Date: Tue, 15 Mar 2022 20:53:58 -0000 Subject: [Python-checkins] [3.8] bpo-47024: Update Windows builds and macOS installer build to use OpenSSL 1.1.1n. (GH-31912) Message-ID: https://github.com/python/cpython/commit/e8b72fc7f3937b6b86354110917da161ca36cff7 commit: e8b72fc7f3937b6b86354110917da161ca36cff7 branch: 3.8 author: Ned Deily committer: ambv date: 2022-03-15T21:53:48+01:00 summary: [3.8] bpo-47024: Update Windows builds and macOS installer build to use OpenSSL 1.1.1n. (GH-31912) * bpo-47024: Update Windows builds and macOS installer build to use OpenSSL 1.1.1n. * Revert inadvertent sqlite downgrade files: A Misc/NEWS.d/next/Build/2022-03-15-11-53-10.bpo-47024.p3PjRy.rst D Mac/BuildScript/0001-Darwin-platform-allows-to-build-on-releases-before-Y.patch M .azure-pipelines/ci.yml M .azure-pipelines/pr.yml M .github/workflows/build.yml M .github/workflows/coverage.yml M Mac/BuildScript/build-installer.py M PCbuild/get_externals.bat M PCbuild/python.props M Tools/ssl/multissltests.py diff --git a/.azure-pipelines/ci.yml b/.azure-pipelines/ci.yml index 2284a5fb36b19..d0efa77f93052 100644 --- a/.azure-pipelines/ci.yml +++ b/.azure-pipelines/ci.yml @@ -57,7 +57,7 @@ jobs: variables: testRunTitle: '$(build.sourceBranchName)-linux' testRunPlatform: linux - openssl_version: 1.1.1l + openssl_version: 1.1.1n steps: - template: ./posix-steps.yml @@ -83,7 +83,7 @@ jobs: variables: testRunTitle: '$(Build.SourceBranchName)-linux-coverage' testRunPlatform: linux-coverage - openssl_version: 1.1.1l + openssl_version: 1.1.1n steps: - template: ./posix-steps.yml diff --git a/.azure-pipelines/pr.yml b/.azure-pipelines/pr.yml index 1a3bf75ed4c1e..a4f32460c7ea0 100644 --- a/.azure-pipelines/pr.yml +++ b/.azure-pipelines/pr.yml @@ -57,7 +57,7 @@ jobs: variables: testRunTitle: '$(system.pullRequest.TargetBranch)-linux' testRunPlatform: linux - openssl_version: 1.1.1l + openssl_version: 1.1.1n steps: - template: ./posix-steps.yml @@ -83,7 +83,7 @@ jobs: variables: testRunTitle: '$(Build.SourceBranchName)-linux-coverage' testRunPlatform: linux-coverage - openssl_version: 1.1.1l + openssl_version: 1.1.1n steps: - template: ./posix-steps.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 88aa37d431828..5c8f6f27b7d81 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -143,7 +143,7 @@ jobs: needs: check_source if: needs.check_source.outputs.run_tests == 'true' env: - OPENSSL_VER: 1.1.1l + OPENSSL_VER: 1.1.1n steps: - uses: actions/checkout at v2 - name: Install Dependencies diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 5ec2e526ab840..762cdb5ab2188 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -23,7 +23,7 @@ jobs: name: 'Ubuntu (Coverage)' runs-on: ubuntu-latest env: - OPENSSL_VER: 1.1.1k + OPENSSL_VER: 1.1.1n steps: - uses: actions/checkout at v2 - name: Install Dependencies diff --git a/Mac/BuildScript/0001-Darwin-platform-allows-to-build-on-releases-before-Y.patch b/Mac/BuildScript/0001-Darwin-platform-allows-to-build-on-releases-before-Y.patch deleted file mode 100644 index 51ccdc2267ee8..0000000000000 --- a/Mac/BuildScript/0001-Darwin-platform-allows-to-build-on-releases-before-Y.patch +++ /dev/null @@ -1,59 +0,0 @@ -From cef404f1e7a598166cbc2fd2e0048f7e2d752ad5 Mon Sep 17 00:00:00 2001 -From: David Carlier -Date: Tue, 24 Aug 2021 22:40:14 +0100 -Subject: [PATCH] Darwin platform allows to build on releases before - Yosemite/ios 8. - -issue #16407 #16408 ---- - crypto/rand/rand_unix.c | 5 +---- - include/crypto/rand.h | 10 ++++++++++ - 2 files changed, 11 insertions(+), 4 deletions(-) - -diff --git a/crypto/rand/rand_unix.c b/crypto/rand/rand_unix.c -index 43f1069d15..0f4525106a 100644 ---- a/crypto/rand/rand_unix.c -+++ b/crypto/rand/rand_unix.c -@@ -34,9 +34,6 @@ - #if defined(__OpenBSD__) - # include - #endif --#if defined(__APPLE__) --# include --#endif - - #if defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__) - # include -@@ -381,7 +378,7 @@ static ssize_t syscall_random(void *buf, size_t buflen) - if (errno != ENOSYS) - return -1; - } --# elif defined(__APPLE__) -+# elif defined(OPENSSL_APPLE_CRYPTO_RANDOM) - if (CCRandomGenerateBytes(buf, buflen) == kCCSuccess) - return (ssize_t)buflen; - -diff --git a/include/crypto/rand.h b/include/crypto/rand.h -index 5350d3a931..674f840fd1 100644 ---- a/include/crypto/rand.h -+++ b/include/crypto/rand.h -@@ -20,6 +20,16 @@ - - # include - -+# if defined(__APPLE__) && !defined(OPENSSL_NO_APPLE_CRYPTO_RANDOM) -+# include -+# if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000) || \ -+ (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) -+# define OPENSSL_APPLE_CRYPTO_RANDOM 1 -+# include -+# include -+# endif -+# endif -+ - /* forward declaration */ - typedef struct rand_pool_st RAND_POOL; - --- -2.33.0 - diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index db25eb890625c..74c2c517d0eaa 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -242,10 +242,9 @@ def library_recipes(): result.extend([ dict( - name="OpenSSL 1.1.1l", - url="https://www.openssl.org/source/openssl-1.1.1l.tar.gz", - checksum='ac0d4387f3ba0ad741b0580dd45f6ff3', - patches=['0001-Darwin-platform-allows-to-build-on-releases-before-Y.patch'], + name="OpenSSL 1.1.1n", + url="https://www.openssl.org/source/openssl-1.1.1n.tar.gz", + checksum='2aad5635f9bb338bc2c6b7d19cbc9676', buildrecipe=build_universal_openssl, configure=None, install=None, diff --git a/Misc/NEWS.d/next/Build/2022-03-15-11-53-10.bpo-47024.p3PjRy.rst b/Misc/NEWS.d/next/Build/2022-03-15-11-53-10.bpo-47024.p3PjRy.rst new file mode 100644 index 0000000000000..235ece3c3d2ef --- /dev/null +++ b/Misc/NEWS.d/next/Build/2022-03-15-11-53-10.bpo-47024.p3PjRy.rst @@ -0,0 +1 @@ +Update Windows builds and macOS installer build to use OpenSSL 1.1.1n. diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index 2eff5e0bd0a00..e0183bf250ae8 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -53,7 +53,7 @@ echo.Fetching external libraries... set libraries= set libraries=%libraries% bzip2-1.0.8 if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.3.0 -if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1l +if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1n set libraries=%libraries% sqlite-3.35.5.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.9.0 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.9.0 @@ -77,7 +77,7 @@ echo.Fetching external binaries... set binaries= if NOT "%IncludeLibffi%"=="false" set binaries=%binaries% libffi-3.3.0 -if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1l +if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1n if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.9.0 if NOT "%IncludeSSLSrc%"=="false" set binaries=%binaries% nasm-2.11.06 diff --git a/PCbuild/python.props b/PCbuild/python.props index 7dfcf8f8a25d9..ec33f3d60e972 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -62,8 +62,8 @@ $(ExternalsDir)libffi-3.3.0\ $(ExternalsDir)libffi-3.3.0\$(ArchName)\ $(libffiOutDir)include - $(ExternalsDir)openssl-1.1.1l\ - $(ExternalsDir)openssl-bin-1.1.1l\$(ArchName)\ + $(ExternalsDir)openssl-1.1.1n\ + $(ExternalsDir)openssl-bin-1.1.1n\$(ArchName)\ $(opensslOutDir)include $(ExternalsDir)\nasm-2.11.06\ $(ExternalsDir)\zlib-1.2.11\ diff --git a/Tools/ssl/multissltests.py b/Tools/ssl/multissltests.py index 41d964ec3ff14..0e010b1deee07 100755 --- a/Tools/ssl/multissltests.py +++ b/Tools/ssl/multissltests.py @@ -49,8 +49,8 @@ ] OPENSSL_RECENT_VERSIONS = [ - "1.1.1l", - "3.0.0-beta1" + "1.1.1n", + "3.0.1" ] LIBRESSL_OLD_VERSIONS = [ From webhook-mailer at python.org Tue Mar 15 16:55:48 2022 From: webhook-mailer at python.org (tiran) Date: Tue, 15 Mar 2022 20:55:48 -0000 Subject: [Python-checkins] bpo-40280: Detect presence of time.tzset and thread_time clock (GH-31898) Message-ID: https://github.com/python/cpython/commit/a4674f0194067a801f6c6bdb4fc6448e3a40e069 commit: a4674f0194067a801f6c6bdb4fc6448e3a40e069 branch: main author: Christian Heimes committer: tiran date: 2022-03-15T21:55:35+01:00 summary: bpo-40280: Detect presence of time.tzset and thread_time clock (GH-31898) files: M Lib/test/datetimetester.py M Lib/test/test_strptime.py M Lib/test/test_time.py M Modules/timemodule.c diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index e208a29813eed..efea40d3f4ff1 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -5856,6 +5856,9 @@ def test_gaps(self): ldt = tz.fromutc(udt.replace(tzinfo=tz)) self.assertEqual(ldt.fold, 0) + @unittest.skipUnless( + hasattr(time, "tzset"), "time module has no attribute tzset" + ) def test_system_transitions(self): if ('Riyadh8' in self.zonename or # From tzdata NEWS file: diff --git a/Lib/test/test_strptime.py b/Lib/test/test_strptime.py index 55a0f426731a5..e5f75b7aab9aa 100644 --- a/Lib/test/test_strptime.py +++ b/Lib/test/test_strptime.py @@ -390,6 +390,9 @@ def test_timezone(self): "LocaleTime().timezone has duplicate values and " "time.daylight but timezone value not set to -1") + @unittest.skipUnless( + hasattr(time, "tzset"), "time module has no attribute tzset" + ) def test_bad_timezone(self): # Explicitly test possibility of bad timezone; # when time.tzname[0] == time.tzname[1] and time.daylight diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py index 57011d158cd03..faac639613a5c 100644 --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -561,8 +561,9 @@ def test_get_clock_info(self): 'perf_counter', 'process_time', 'time', - 'thread_time', ] + if hasattr(time, 'thread_time'): + clocks.append('thread_time') for name in clocks: with self.subTest(name=name): diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 5b2d9b768ddd6..7475ef344b72b 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -1479,7 +1479,9 @@ _PyTime_GetThreadTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) return 0; } -#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_PROCESS_CPUTIME_ID) +#elif defined(HAVE_CLOCK_GETTIME) && \ + defined(CLOCK_PROCESS_CPUTIME_ID) && \ + !defined(__EMSCRIPTEN__) #define HAVE_THREAD_TIME #if defined(__APPLE__) && defined(__has_attribute) && __has_attribute(availability) From webhook-mailer at python.org Tue Mar 15 18:42:51 2022 From: webhook-mailer at python.org (ambv) Date: Tue, 15 Mar 2022 22:42:51 -0000 Subject: [Python-checkins] Python 3.8.13 Message-ID: https://github.com/python/cpython/commit/f1c3816ddf19076f8c16fa75a6846e32eba37fcb commit: f1c3816ddf19076f8c16fa75a6846e32eba37fcb branch: 3.8 author: ?ukasz Langa committer: ambv date: 2022-03-15T22:43:42+01:00 summary: Python 3.8.13 files: A Misc/NEWS.d/3.8.13.rst D Misc/NEWS.d/next/Build/2021-09-16-18-00-43.bpo-45220.TgbkvW.rst D Misc/NEWS.d/next/Build/2021-10-11-16-27-38.bpo-45405.iSfdW5.rst D Misc/NEWS.d/next/Build/2022-03-15-11-53-10.bpo-47024.p3PjRy.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-22-12-07-53.bpo-46794.6WvJ9o.rst D Misc/NEWS.d/next/Documentation/2020-06-18-23-37-03.bpo-41028.vM8bC8.rst D Misc/NEWS.d/next/Library/2021-08-06-13-00-28.bpo-44849.O78F_f.rst D Misc/NEWS.d/next/Library/2022-01-22-14-49-10.bpo-46474.eKQhvx.rst D Misc/NEWS.d/next/Library/2022-01-30-15-16-12.bpo-46400.vweUiO.rst D Misc/NEWS.d/next/Library/2022-02-15-11-57-53.bpo-46756.AigSPi.rst D Misc/NEWS.d/next/Library/2022-02-18-22-10-30.bpo-46784.SVOQJx.rst D Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst D Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst D Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst D Misc/NEWS.d/next/Tests/2021-08-18-18-30-12.bpo-44949.VE5ENv.rst D Misc/NEWS.d/next/Tests/2021-09-14-13-16-18.bpo-45195.EyQR1G.rst D Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst D Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst D Misc/NEWS.d/next/macOS/2021-10-25-02-02-21.bpo-44828.XBdXlJ.rst M Include/patchlevel.h M Lib/pydoc_data/topics.py M README.rst diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 7b579cb0b0493..020cb189807c3 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -18,12 +18,12 @@ /*--start constants--*/ #define PY_MAJOR_VERSION 3 #define PY_MINOR_VERSION 8 -#define PY_MICRO_VERSION 12 +#define PY_MICRO_VERSION 13 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL #define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "3.8.12+" +#define PY_VERSION "3.8.13" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index 7e8d507907763..55fb7c0f88189 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Mon Aug 30 16:25:18 2021 +# Autogenerated by Sphinx on Tue Mar 15 22:39:04 2022 topics = {'assert': 'The "assert" statement\n' '**********************\n' '\n' @@ -3224,13 +3224,13 @@ '\n' ' If "__new__()" is invoked during object construction and ' 'it returns\n' - ' an instance or subclass of *cls*, then the new ' - 'instance?s\n' - ' "__init__()" method will be invoked like ' - '"__init__(self[, ...])",\n' - ' where *self* is the new instance and the remaining ' - 'arguments are\n' - ' the same as were passed to the object constructor.\n' + ' an instance of *cls*, then the new instance?s ' + '"__init__()" method\n' + ' will be invoked like "__init__(self[, ...])", where ' + '*self* is the\n' + ' new instance and the remaining arguments are the same as ' + 'were\n' + ' passed to the object constructor.\n' '\n' ' If "__new__()" does not return an instance of *cls*, ' 'then the new\n' @@ -7096,9 +7096,9 @@ ' of the object truncated to an "Integral" (typically an ' '"int").\n' '\n' - ' If "__int__()" is not defined then the built-in function ' - '"int()"\n' - ' falls back to "__trunc__()".\n', + ' The built-in function "int()" falls back to ' + '"__trunc__()" if\n' + ' neither "__int__()" nor "__index__()" is defined.\n', 'objects': 'Objects, values and types\n' '*************************\n' '\n' @@ -8066,13 +8066,13 @@ '\n' ' If "__new__()" is invoked during object construction and ' 'it returns\n' - ' an instance or subclass of *cls*, then the new ' - 'instance?s\n' - ' "__init__()" method will be invoked like "__init__(self[, ' - '...])",\n' - ' where *self* is the new instance and the remaining ' - 'arguments are\n' - ' the same as were passed to the object constructor.\n' + ' an instance of *cls*, then the new instance?s ' + '"__init__()" method\n' + ' will be invoked like "__init__(self[, ...])", where ' + '*self* is the\n' + ' new instance and the remaining arguments are the same as ' + 'were\n' + ' passed to the object constructor.\n' '\n' ' If "__new__()" does not return an instance of *cls*, then ' 'the new\n' @@ -9833,9 +9833,9 @@ ' of the object truncated to an "Integral" (typically an ' '"int").\n' '\n' - ' If "__int__()" is not defined then the built-in function ' - '"int()"\n' - ' falls back to "__trunc__()".\n' + ' The built-in function "int()" falls back to "__trunc__()" ' + 'if\n' + ' neither "__int__()" nor "__index__()" is defined.\n' '\n' '\n' 'With Statement Context Managers\n' diff --git a/Misc/NEWS.d/3.8.13.rst b/Misc/NEWS.d/3.8.13.rst new file mode 100644 index 0000000000000..fcf7e14afc09f --- /dev/null +++ b/Misc/NEWS.d/3.8.13.rst @@ -0,0 +1,180 @@ +.. bpo: 46794 +.. date: 2022-02-22-12-07-53 +.. nonce: 6WvJ9o +.. release date: 2022-03-15 +.. section: Core and Builtins + +Bump up the libexpat version into 2.4.6 + +.. + +.. bpo: 46985 +.. date: 2022-03-11-13-34-16 +.. nonce: BgoMr2 +.. section: Library + +Upgrade pip wheel bundled with ensurepip (pip 22.0.4) + +.. + +.. bpo: 46932 +.. date: 2022-03-07-20-20-34 +.. nonce: xbarAs +.. section: Library + +Update bundled libexpat to 2.4.7 + +.. + +.. bpo: 46811 +.. date: 2022-02-20-21-03-31 +.. nonce: 8BxgdQ +.. section: Library + +Make test suite support Expat >=2.4.5 + +.. + +.. bpo: 46784 +.. date: 2022-02-18-22-10-30 +.. nonce: SVOQJx +.. section: Library + +Fix libexpat symbols collisions with user dynamically loaded or statically +linked libexpat in embedded Python. + +.. + +.. bpo: 46756 +.. date: 2022-02-15-11-57-53 +.. nonce: AigSPi +.. section: Library + +Fix a bug in :meth:`urllib.request.HTTPPasswordMgr.find_user_password` and +:meth:`urllib.request.HTTPPasswordMgrWithPriorAuth.is_authenticated` which +allowed to bypass authorization. For example, access to URI +``example.org/foobar`` was allowed if the user was authorized for URI +``example.org/foo``. + +.. + +.. bpo: 46400 +.. date: 2022-01-30-15-16-12 +.. nonce: vweUiO +.. section: Library + +expat: Update libexpat from 2.4.1 to 2.4.4 + +.. + +.. bpo: 46474 +.. date: 2022-01-22-14-49-10 +.. nonce: eKQhvx +.. section: Library + +In ``importlib.metadata.EntryPoint.pattern``, avoid potential REDoS by +limiting ambiguity in consecutive whitespace. + +.. + +.. bpo: 44849 +.. date: 2021-08-06-13-00-28 +.. nonce: O78F_f +.. section: Library + +Fix the :func:`os.set_inheritable` function on FreeBSD 14 for file +descriptor opened with the :data:`~os.O_PATH` flag: ignore the +:data:`~errno.EBADF` error on ``ioctl()``, fallback on the ``fcntl()`` +implementation. Patch by Victor Stinner. + +.. + +.. bpo: 41028 +.. date: 2020-06-18-23-37-03 +.. nonce: vM8bC8 +.. section: Documentation + +Language and version switchers, previously maintained in every cpython +branches, are now handled by docsbuild-script. + +.. + +.. bpo: 45195 +.. date: 2021-09-14-13-16-18 +.. nonce: EyQR1G +.. section: Tests + +Fix test_readline.test_nonascii(): sometimes, the newline character is not +written at the end, so don't expect it in the output. Patch by Victor +Stinner. + +.. + +.. bpo: 44949 +.. date: 2021-08-18-18-30-12 +.. nonce: VE5ENv +.. section: Tests + +Fix auto history tests of test_readline: sometimes, the newline character is +not written at the end, so don't expect it in the output. + +.. + +.. bpo: 47024 +.. date: 2022-03-15-11-53-10 +.. nonce: p3PjRy +.. section: Build + +Update Windows builds and macOS installer build to use OpenSSL 1.1.1n. + +.. + +.. bpo: 45405 +.. date: 2021-10-11-16-27-38 +.. nonce: iSfdW5 +.. section: Build + +Prevent ``internal configure error`` when running ``configure`` with recent +versions of clang. Patch by David Bohman. + +.. + +.. bpo: 45220 +.. date: 2021-09-16-18-00-43 +.. nonce: TgbkvW +.. section: Build + +Avoid building with the Windows 11 SDK previews automatically. This may be +overridden by setting the ``DefaultWindowsSDKVersion`` environment variable +before building. + +.. + +.. bpo: 44549 +.. date: 2022-03-07-17-46-40 +.. nonce: SPrGS9 +.. section: Windows + +Update bzip2 to 1.0.8 in Windows builds to mitigate CVE-2016-3189 and +CVE-2019-12900 + +.. + +.. bpo: 46948 +.. date: 2022-03-07-16-34-11 +.. nonce: Ufd4tG +.. section: Windows + +Prevent CVE-2022-26488 by ensuring the Add to PATH option in the Windows +installer uses the correct path when being repaired. + +.. + +.. bpo: 44828 +.. date: 2021-10-25-02-02-21 +.. nonce: XBdXlJ +.. section: macOS + +Avoid tkinter file dialog failure on macOS 12 Monterey when using the Tk +8.6.11 provided by python.org macOS installers. Patch by Marc Culler of the +Tk project. diff --git a/Misc/NEWS.d/next/Build/2021-09-16-18-00-43.bpo-45220.TgbkvW.rst b/Misc/NEWS.d/next/Build/2021-09-16-18-00-43.bpo-45220.TgbkvW.rst deleted file mode 100644 index 8bbd634fa61a3..0000000000000 --- a/Misc/NEWS.d/next/Build/2021-09-16-18-00-43.bpo-45220.TgbkvW.rst +++ /dev/null @@ -1,3 +0,0 @@ -Avoid building with the Windows 11 SDK previews automatically. This may be -overridden by setting the ``DefaultWindowsSDKVersion`` environment variable -before building. diff --git a/Misc/NEWS.d/next/Build/2021-10-11-16-27-38.bpo-45405.iSfdW5.rst b/Misc/NEWS.d/next/Build/2021-10-11-16-27-38.bpo-45405.iSfdW5.rst deleted file mode 100644 index 13c93d1b8a571..0000000000000 --- a/Misc/NEWS.d/next/Build/2021-10-11-16-27-38.bpo-45405.iSfdW5.rst +++ /dev/null @@ -1,2 +0,0 @@ -Prevent ``internal configure error`` when running ``configure`` -with recent versions of clang. Patch by David Bohman. diff --git a/Misc/NEWS.d/next/Build/2022-03-15-11-53-10.bpo-47024.p3PjRy.rst b/Misc/NEWS.d/next/Build/2022-03-15-11-53-10.bpo-47024.p3PjRy.rst deleted file mode 100644 index 235ece3c3d2ef..0000000000000 --- a/Misc/NEWS.d/next/Build/2022-03-15-11-53-10.bpo-47024.p3PjRy.rst +++ /dev/null @@ -1 +0,0 @@ -Update Windows builds and macOS installer build to use OpenSSL 1.1.1n. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-22-12-07-53.bpo-46794.6WvJ9o.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-22-12-07-53.bpo-46794.6WvJ9o.rst deleted file mode 100644 index 127387d32cb7a..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-22-12-07-53.bpo-46794.6WvJ9o.rst +++ /dev/null @@ -1 +0,0 @@ -Bump up the libexpat version into 2.4.6 diff --git a/Misc/NEWS.d/next/Documentation/2020-06-18-23-37-03.bpo-41028.vM8bC8.rst b/Misc/NEWS.d/next/Documentation/2020-06-18-23-37-03.bpo-41028.vM8bC8.rst deleted file mode 100644 index 5fc4155b55346..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2020-06-18-23-37-03.bpo-41028.vM8bC8.rst +++ /dev/null @@ -1,2 +0,0 @@ -Language and version switchers, previously maintained in every cpython -branches, are now handled by docsbuild-script. diff --git a/Misc/NEWS.d/next/Library/2021-08-06-13-00-28.bpo-44849.O78F_f.rst b/Misc/NEWS.d/next/Library/2021-08-06-13-00-28.bpo-44849.O78F_f.rst deleted file mode 100644 index b1f225485ddef..0000000000000 --- a/Misc/NEWS.d/next/Library/2021-08-06-13-00-28.bpo-44849.O78F_f.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix the :func:`os.set_inheritable` function on FreeBSD 14 for file descriptor -opened with the :data:`~os.O_PATH` flag: ignore the :data:`~errno.EBADF` -error on ``ioctl()``, fallback on the ``fcntl()`` implementation. Patch by -Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2022-01-22-14-49-10.bpo-46474.eKQhvx.rst b/Misc/NEWS.d/next/Library/2022-01-22-14-49-10.bpo-46474.eKQhvx.rst deleted file mode 100644 index 156b7de4f6787..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-22-14-49-10.bpo-46474.eKQhvx.rst +++ /dev/null @@ -1,2 +0,0 @@ -In ``importlib.metadata.EntryPoint.pattern``, avoid potential REDoS by -limiting ambiguity in consecutive whitespace. diff --git a/Misc/NEWS.d/next/Library/2022-01-30-15-16-12.bpo-46400.vweUiO.rst b/Misc/NEWS.d/next/Library/2022-01-30-15-16-12.bpo-46400.vweUiO.rst deleted file mode 100644 index 9c1f24c0e5171..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-30-15-16-12.bpo-46400.vweUiO.rst +++ /dev/null @@ -1 +0,0 @@ -expat: Update libexpat from 2.4.1 to 2.4.4 diff --git a/Misc/NEWS.d/next/Library/2022-02-15-11-57-53.bpo-46756.AigSPi.rst b/Misc/NEWS.d/next/Library/2022-02-15-11-57-53.bpo-46756.AigSPi.rst deleted file mode 100644 index 1660640c5d3fb..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-15-11-57-53.bpo-46756.AigSPi.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fix a bug in :meth:`urllib.request.HTTPPasswordMgr.find_user_password` and -:meth:`urllib.request.HTTPPasswordMgrWithPriorAuth.is_authenticated` which -allowed to bypass authorization. For example, access to URI -``example.org/foobar`` was allowed if the user was authorized for URI -``example.org/foo``. diff --git a/Misc/NEWS.d/next/Library/2022-02-18-22-10-30.bpo-46784.SVOQJx.rst b/Misc/NEWS.d/next/Library/2022-02-18-22-10-30.bpo-46784.SVOQJx.rst deleted file mode 100644 index d190816637ae8..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-18-22-10-30.bpo-46784.SVOQJx.rst +++ /dev/null @@ -1 +0,0 @@ -Fix libexpat symbols collisions with user dynamically loaded or statically linked libexpat in embedded Python. diff --git a/Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst b/Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst deleted file mode 100644 index 6969bd1898f65..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst +++ /dev/null @@ -1 +0,0 @@ -Make test suite support Expat >=2.4.5 diff --git a/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst b/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst deleted file mode 100644 index 8545c656eab89..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst +++ /dev/null @@ -1 +0,0 @@ -Update bundled libexpat to 2.4.7 diff --git a/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst b/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst deleted file mode 100644 index 2e08ee837f583..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst +++ /dev/null @@ -1 +0,0 @@ -Upgrade pip wheel bundled with ensurepip (pip 22.0.4) diff --git a/Misc/NEWS.d/next/Tests/2021-08-18-18-30-12.bpo-44949.VE5ENv.rst b/Misc/NEWS.d/next/Tests/2021-08-18-18-30-12.bpo-44949.VE5ENv.rst deleted file mode 100644 index 7fdf1810b165e..0000000000000 --- a/Misc/NEWS.d/next/Tests/2021-08-18-18-30-12.bpo-44949.VE5ENv.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix auto history tests of test_readline: sometimes, the newline character is -not written at the end, so don't expect it in the output. diff --git a/Misc/NEWS.d/next/Tests/2021-09-14-13-16-18.bpo-45195.EyQR1G.rst b/Misc/NEWS.d/next/Tests/2021-09-14-13-16-18.bpo-45195.EyQR1G.rst deleted file mode 100644 index 16a1f4440483c..0000000000000 --- a/Misc/NEWS.d/next/Tests/2021-09-14-13-16-18.bpo-45195.EyQR1G.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix test_readline.test_nonascii(): sometimes, the newline character is not -written at the end, so don't expect it in the output. Patch by Victor -Stinner. diff --git a/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst b/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst deleted file mode 100644 index cfc4827882ded..0000000000000 --- a/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst +++ /dev/null @@ -1,2 +0,0 @@ -Prevent CVE-2022-26488 by ensuring the Add to PATH option in the Windows -installer uses the correct path when being repaired. diff --git a/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst b/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst deleted file mode 100644 index 0f1ef9af6c617..0000000000000 --- a/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst +++ /dev/null @@ -1,2 +0,0 @@ -Update bzip2 to 1.0.8 in Windows builds to mitigate CVE-2016-3189 and -CVE-2019-12900 diff --git a/Misc/NEWS.d/next/macOS/2021-10-25-02-02-21.bpo-44828.XBdXlJ.rst b/Misc/NEWS.d/next/macOS/2021-10-25-02-02-21.bpo-44828.XBdXlJ.rst deleted file mode 100644 index 021d7e4d73782..0000000000000 --- a/Misc/NEWS.d/next/macOS/2021-10-25-02-02-21.bpo-44828.XBdXlJ.rst +++ /dev/null @@ -1,3 +0,0 @@ -Avoid tkinter file dialog failure on macOS 12 Monterey when using the Tk -8.6.11 provided by python.org macOS installers. Patch by Marc Culler of the -Tk project. diff --git a/README.rst b/README.rst index 2797b59f79b8b..bd1b5abf8c13b 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -This is Python version 3.8.12 +This is Python version 3.8.13 ============================= .. image:: https://travis-ci.org/python/cpython.svg?branch=3.8 From webhook-mailer at python.org Tue Mar 15 18:44:33 2022 From: webhook-mailer at python.org (ambv) Date: Tue, 15 Mar 2022 22:44:33 -0000 Subject: [Python-checkins] Python 3.9.11 Message-ID: https://github.com/python/cpython/commit/0f0c55c9f0f4c358d759470702821c471fcd1bc8 commit: 0f0c55c9f0f4c358d759470702821c471fcd1bc8 branch: 3.9 author: ?ukasz Langa committer: ambv date: 2022-03-15T21:47:24+01:00 summary: Python 3.9.11 files: A Misc/NEWS.d/3.9.11.rst D Misc/NEWS.d/next/Build/2022-01-08-12-43-31.bpo-45925.38F3NO.rst D Misc/NEWS.d/next/Build/2022-01-25-12-32-37.bpo-46513.mPm9B4.rst D Misc/NEWS.d/next/Build/2022-01-26-22-59-12.bpo-38472.RxfLho.rst D Misc/NEWS.d/next/Build/2022-03-15-09-28-55.bpo-47024.t7-dcu.rst D Misc/NEWS.d/next/Core and Builtins/2022-01-14-20-55-34.bpo-46383.v8MTl4.rst D Misc/NEWS.d/next/Core and Builtins/2022-01-22-14-39-23.bpo-46417.3U5SfN.rst D Misc/NEWS.d/next/Core and Builtins/2022-01-24-21-24-41.bpo-46503.4UrPsE.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-04-04-33-18.bpo-46615.puArY9.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-06-23-08-30.bpo-40479.zED3Zu.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-12-11-16-40.bpo-46732.3Z_qxd.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-15-20-26-46.bpo-46762.1H7vab.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-22-12-07-53.bpo-46794.6WvJ9o.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-25-02-01-42.bpo-46852._3zg8D.rst D Misc/NEWS.d/next/Documentation/2022-01-21-21-33-48.bpo-46463.fBbdTG.rst D Misc/NEWS.d/next/IDLE/2021-10-14-16-55-03.bpo-45447.FhiH5P.rst D Misc/NEWS.d/next/IDLE/2022-01-26-19-33-55.bpo-45296.LzZKdU.rst D Misc/NEWS.d/next/IDLE/2022-02-03-15-47-53.bpo-46630.tREOjo.rst D Misc/NEWS.d/next/Library/2021-09-06-15-46-53.bpo-24959.UVFgiO.rst D Misc/NEWS.d/next/Library/2021-11-03-13-41-49.bpo-45703.35AagL.rst D Misc/NEWS.d/next/Library/2021-11-08-20-27-41.bpo-44439.I_8qro.rst D Misc/NEWS.d/next/Library/2021-12-15-06-29-00.bpo-46080.AuQpLt.rst D Misc/NEWS.d/next/Library/2021-12-22-12-02-27.bpo-20392.CLAFIp.rst D Misc/NEWS.d/next/Library/2021-12-28-11-55-10.bpo-21987.avBK-p.rst D Misc/NEWS.d/next/Library/2021-12-29-14-42-09.bpo-43118.BoVi_5.rst D Misc/NEWS.d/next/Library/2022-01-11-15-54-15.bpo-46333.B1faiF.rst D Misc/NEWS.d/next/Library/2022-01-20-10-35-10.bpo-46434.geS-aP.rst D Misc/NEWS.d/next/Library/2022-01-22-05-05-08.bpo-46469.plUab5.rst D Misc/NEWS.d/next/Library/2022-01-22-14-49-10.bpo-46474.eKQhvx.rst D Misc/NEWS.d/next/Library/2022-01-23-18-04-45.bpo-41403.SgoHqV.rst D Misc/NEWS.d/next/Library/2022-01-23-19-37-00.bpo-46436.Biz1p9.rst D Misc/NEWS.d/next/Library/2022-01-24-23-55-30.bpo-46491.jmIKHo.rst D Misc/NEWS.d/next/Library/2022-01-26-20-36-30.bpo-46539.23iW1d.rst D Misc/NEWS.d/next/Library/2022-01-27-12-24-38.bpo-46487.UDkN2z.rst D Misc/NEWS.d/next/Library/2022-01-30-15-16-12.bpo-46400.vweUiO.rst D Misc/NEWS.d/next/Library/2022-01-31-15-40-38.bpo-46591.prBD1M.rst D Misc/NEWS.d/next/Library/2022-02-05-18-22-05.bpo-45948.w4mCnE.rst D Misc/NEWS.d/next/Library/2022-02-07-13-15-16.bpo-46672.4swIjx.rst D Misc/NEWS.d/next/Library/2022-02-09-00-53-23.bpo-45863.zqQXVv.rst D Misc/NEWS.d/next/Library/2022-02-15-11-57-53.bpo-46756.AigSPi.rst D Misc/NEWS.d/next/Library/2022-02-17-13-10-50.bpo-39327.ytIT7Z.rst D Misc/NEWS.d/next/Library/2022-02-18-22-10-30.bpo-46784.SVOQJx.rst D Misc/NEWS.d/next/Library/2022-02-20-12-59-46.bpo-46252.KG1SqA.rst D Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst D Misc/NEWS.d/next/Library/2022-02-22-15-08-30.bpo-46827.hvj38S.rst D Misc/NEWS.d/next/Library/2022-02-23-00-55-59.bpo-44886.I40Mbr.rst D Misc/NEWS.d/next/Library/2022-03-05-09-43-53.bpo-25707.gTlclP.rst D Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst D Misc/NEWS.d/next/Library/2022-03-08-22-41-59.bpo-46955.IOoonN.rst D Misc/NEWS.d/next/Library/2022-03-10-14-51-11.bpo-46968.ym2QxL.rst D Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst D Misc/NEWS.d/next/Library/2022-03-13-15-04-05.bpo-47004.SyYpxd.rst D Misc/NEWS.d/next/Library/2022-03-15-07-53-45.bpo-43253.rjdLFj.rst D Misc/NEWS.d/next/Tests/2022-01-17-13-10-04.bpo-13886.5mZH4b.rst D Misc/NEWS.d/next/Tests/2022-01-28-01-17-10.bpo-46542.xRLTdj.rst D Misc/NEWS.d/next/Tests/2022-01-29-12-37-53.bpo-46576.-prRaV.rst D Misc/NEWS.d/next/Tests/2022-01-31-17-34-13.bpo-46542.RTMm1T.rst D Misc/NEWS.d/next/Tests/2022-02-02-02-24-04.bpo-44359.kPPSmN.rst D Misc/NEWS.d/next/Tests/2022-02-02-18-14-38.bpo-46616.URvBtE.rst D Misc/NEWS.d/next/Tests/2022-02-10-14-33-47.bpo-46708.avLfCb.rst D Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst D Misc/NEWS.d/next/Windows/2022-02-04-18-02-33.bpo-46638.mSJOSX.rst D Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst D Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst D Misc/NEWS.d/next/macOS/2022-01-26-12-04-09.bpo-45925.yBSiYO.rst M Include/patchlevel.h M Lib/pydoc_data/topics.py M README.rst diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 094f1215ee3fb..bf343ad960b8c 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -18,12 +18,12 @@ /*--start constants--*/ #define PY_MAJOR_VERSION 3 #define PY_MINOR_VERSION 9 -#define PY_MICRO_VERSION 10 +#define PY_MICRO_VERSION 11 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL #define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "3.9.10+" +#define PY_VERSION "3.9.11" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index 67a51977cfe74..0e63c31f1b4fe 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Thu Jan 13 21:46:32 2022 +# Autogenerated by Sphinx on Tue Mar 15 21:44:32 2022 topics = {'assert': 'The "assert" statement\n' '**********************\n' '\n' @@ -5408,19 +5408,19 @@ 'with an\n' '*alignment* type of "\'=\'".\n' '\n' - 'The *precision* is a decimal number indicating how many ' + 'The *precision* is a decimal integer indicating how many ' 'digits should\n' - 'be displayed after the decimal point for a floating point ' - 'value\n' - 'formatted with "\'f\'" and "\'F\'", or before and after the ' - 'decimal point\n' - 'for a floating point value formatted with "\'g\'" or ' - '"\'G\'". For non-\n' - 'number types the field indicates the maximum field size - ' - 'in other\n' - 'words, how many characters will be used from the field ' - 'content. The\n' - '*precision* is not allowed for integer values.\n' + 'be displayed after the decimal point for presentation types ' + '"\'f\'" and\n' + '"\'F\'", or before and after the decimal point for ' + 'presentation types\n' + '"\'g\'" or "\'G\'". For string presentation types the ' + 'field indicates the\n' + 'maximum field size - in other words, how many characters ' + 'will be used\n' + 'from the field content. The *precision* is not allowed for ' + 'integer\n' + 'presentation types.\n' '\n' 'Finally, the *type* determines how the data should be ' 'presented.\n' @@ -7515,12 +7515,12 @@ '\n' ' raise_stmt ::= "raise" [expression ["from" expression]]\n' '\n' - 'If no expressions are present, "raise" re-raises the last ' - 'exception\n' - 'that was active in the current scope. If no exception is active ' - 'in\n' - 'the current scope, a "RuntimeError" exception is raised indicating\n' - 'that this is an error.\n' + 'If no expressions are present, "raise" re-raises the exception that ' + 'is\n' + 'currently being handled, which is also known as the *active\n' + 'exception*. If there isn?t currently an active exception, a\n' + '"RuntimeError" exception is raised indicating that this is an ' + 'error.\n' '\n' 'Otherwise, "raise" evaluates the first expression as the exception\n' 'object. It must be either a subclass or an instance of\n' @@ -7575,11 +7575,14 @@ ' File "", line 4, in \n' ' RuntimeError: Something bad happened\n' '\n' - 'A similar mechanism works implicitly if an exception is raised ' - 'inside\n' - 'an exception handler or a "finally" clause: the previous exception ' - 'is\n' - 'then attached as the new exception?s "__context__" attribute:\n' + 'A similar mechanism works implicitly if a new exception is raised ' + 'when\n' + 'an exception is already being handled. An exception may be ' + 'handled\n' + 'when an "except" or "finally" clause, or a "with" statement, is ' + 'used.\n' + 'The previous exception is then attached as the new exception?s\n' + '"__context__" attribute:\n' '\n' ' >>> try:\n' ' ... print(1 / 0)\n' @@ -9079,14 +9082,14 @@ '\n' 'Whenever a class inherits from another class, ' '"__init_subclass__()" is\n' - 'called on that class. This way, it is possible to write ' - 'classes which\n' - 'change the behavior of subclasses. This is closely related ' - 'to class\n' - 'decorators, but where class decorators only affect the ' - 'specific class\n' - 'they?re applied to, "__init_subclass__" solely applies to ' - 'future\n' + 'called on the parent class. This way, it is possible to ' + 'write classes\n' + 'which change the behavior of subclasses. This is closely ' + 'related to\n' + 'class decorators, but where class decorators only affect the ' + 'specific\n' + 'class they?re applied to, "__init_subclass__" solely applies ' + 'to future\n' 'subclasses of the class defining the method.\n' '\n' 'classmethod object.__init_subclass__(cls)\n' @@ -11393,67 +11396,86 @@ 'subscriptions': 'Subscriptions\n' '*************\n' '\n' - 'Subscription of a sequence (string, tuple or list) or ' - 'mapping\n' - '(dictionary) object usually selects an item from the ' - 'collection:\n' + 'The subscription of an instance of a container class will ' + 'generally\n' + 'select an element from the container. The subscription of a ' + '*generic\n' + 'class* will generally return a GenericAlias object.\n' '\n' ' subscription ::= primary "[" expression_list "]"\n' '\n' + 'When an object is subscripted, the interpreter will ' + 'evaluate the\n' + 'primary and the expression list.\n' + '\n' 'The primary must evaluate to an object that supports ' - 'subscription\n' - '(lists or dictionaries for example). User-defined objects ' - 'can support\n' - 'subscription by defining a "__getitem__()" method.\n' + 'subscription. An\n' + 'object may support subscription through defining one or ' + 'both of\n' + '"__getitem__()" and "__class_getitem__()". When the primary ' + 'is\n' + 'subscripted, the evaluated result of the expression list ' + 'will be\n' + 'passed to one of these methods. For more details on when\n' + '"__class_getitem__" is called instead of "__getitem__", ' + 'see\n' + '__class_getitem__ versus __getitem__.\n' + '\n' + 'If the expression list contains at least one comma, it will ' + 'evaluate\n' + 'to a "tuple" containing the items of the expression list. ' + 'Otherwise,\n' + 'the expression list will evaluate to the value of the ' + 'list?s sole\n' + 'member.\n' '\n' 'For built-in objects, there are two types of objects that ' 'support\n' - 'subscription:\n' + 'subscription via "__getitem__()":\n' '\n' - 'If the primary is a mapping, the expression list must ' - 'evaluate to an\n' - 'object whose value is one of the keys of the mapping, and ' + '1. Mappings. If the primary is a *mapping*, the expression ' + 'list must\n' + ' evaluate to an object whose value is one of the keys of ' 'the\n' - 'subscription selects the value in the mapping that ' - 'corresponds to that\n' - 'key. (The expression list is a tuple except if it has ' - 'exactly one\n' - 'item.)\n' - '\n' - 'If the primary is a sequence, the expression list must ' - 'evaluate to an\n' - 'integer or a slice (as discussed in the following ' - 'section).\n' + ' mapping, and the subscription selects the value in the ' + 'mapping that\n' + ' corresponds to that key. An example of a builtin mapping ' + 'class is\n' + ' the "dict" class.\n' + '\n' + '2. Sequences. If the primary is a *sequence*, the ' + 'expression list must\n' + ' evaluate to an "int" or a "slice" (as discussed in the ' + 'following\n' + ' section). Examples of builtin sequence classes include ' + 'the "str",\n' + ' "list" and "tuple" classes.\n' '\n' 'The formal syntax makes no special provision for negative ' 'indices in\n' - 'sequences; however, built-in sequences all provide a ' + '*sequences*. However, built-in sequences all provide a ' '"__getitem__()"\n' 'method that interprets negative indices by adding the ' 'length of the\n' - 'sequence to the index (so that "x[-1]" selects the last ' - 'item of "x").\n' - 'The resulting value must be a nonnegative integer less than ' - 'the number\n' - 'of items in the sequence, and the subscription selects the ' - 'item whose\n' - 'index is that value (counting from zero). Since the support ' - 'for\n' - 'negative indices and slicing occurs in the object?s ' - '"__getitem__()"\n' - 'method, subclasses overriding this method will need to ' - 'explicitly add\n' - 'that support.\n' - '\n' - 'A string?s items are characters. A character is not a ' - 'separate data\n' - 'type but a string of exactly one character.\n' - '\n' - 'Subscription of certain *classes* or *types* creates a ' - 'generic alias.\n' - 'In this case, user-defined classes can support subscription ' - 'by\n' - 'providing a "__class_getitem__()" classmethod.\n', + 'sequence to the index so that, for example, "x[-1]" selects ' + 'the last\n' + 'item of "x". The resulting value must be a nonnegative ' + 'integer less\n' + 'than the number of items in the sequence, and the ' + 'subscription selects\n' + 'the item whose index is that value (counting from zero). ' + 'Since the\n' + 'support for negative indices and slicing occurs in the ' + 'object?s\n' + '"__getitem__()" method, subclasses overriding this method ' + 'will need to\n' + 'explicitly add that support.\n' + '\n' + 'A "string" is a special kind of sequence whose items are ' + '*characters*.\n' + 'A character is not a separate data type but a string of ' + 'exactly one\n' + 'character.\n', 'truth': 'Truth Value Testing\n' '*******************\n' '\n' diff --git a/Misc/NEWS.d/3.9.11.rst b/Misc/NEWS.d/3.9.11.rst new file mode 100644 index 0000000000000..5efbb4bfc6db9 --- /dev/null +++ b/Misc/NEWS.d/3.9.11.rst @@ -0,0 +1,672 @@ +.. bpo: 46852 +.. date: 2022-02-25-02-01-42 +.. nonce: _3zg8D +.. release date: 2022-03-15 +.. section: Core and Builtins + +Rename the private undocumented ``float.__set_format__()`` method to +``float.__setformat__()`` to fix a typo introduced in Python 3.7. The method +is only used by test_float. Patch by Victor Stinner. + +.. + +.. bpo: 46794 +.. date: 2022-02-22-12-07-53 +.. nonce: 6WvJ9o +.. section: Core and Builtins + +Bump up the libexpat version into 2.4.6 + +.. + +.. bpo: 46762 +.. date: 2022-02-15-20-26-46 +.. nonce: 1H7vab +.. section: Core and Builtins + +Fix an assert failure in debug builds when a '<', '>', or '=' is the last +character in an f-string that's missing a closing right brace. + +.. + +.. bpo: 46732 +.. date: 2022-02-12-11-16-40 +.. nonce: 3Z_qxd +.. section: Core and Builtins + +Correct the docstring for the :meth:`__bool__` method. Patch by Jelle +Zijlstra. + +.. + +.. bpo: 40479 +.. date: 2022-02-06-23-08-30 +.. nonce: zED3Zu +.. section: Core and Builtins + +Add a missing call to ``va_end()`` in ``Modules/_hashopenssl.c``. + +.. + +.. bpo: 46615 +.. date: 2022-02-04-04-33-18 +.. nonce: puArY9 +.. section: Core and Builtins + +When iterating over sets internally in ``setobject.c``, acquire strong +references to the resulting items from the set. This prevents crashes in +corner-cases of various set operations where the set gets mutated. + +.. + +.. bpo: 43721 +.. date: 2022-02-01-10-05-27 +.. nonce: -1XAIo +.. section: Core and Builtins + +Fix docstrings of :attr:`~property.getter`, :attr:`~property.setter`, and +:attr:`~property.deleter` to clarify that they create a new copy of the +property. + +.. + +.. bpo: 46503 +.. date: 2022-01-24-21-24-41 +.. nonce: 4UrPsE +.. section: Core and Builtins + +Fix an assert when parsing some invalid \N escape sequences in f-strings. + +.. + +.. bpo: 46417 +.. date: 2022-01-22-14-39-23 +.. nonce: 3U5SfN +.. section: Core and Builtins + +Fix a race condition on setting a type ``__bases__`` attribute: the internal +function ``add_subclass()`` now gets the ``PyTypeObject.tp_subclasses`` +member after calling :c:func:`PyWeakref_NewRef` which can trigger a garbage +collection which can indirectly modify ``PyTypeObject.tp_subclasses``. Patch +by Victor Stinner. + +.. + +.. bpo: 46383 +.. date: 2022-01-14-20-55-34 +.. nonce: v8MTl4 +.. section: Core and Builtins + +Fix invalid signature of ``_zoneinfo``'s ``module_free`` function to resolve +a crash on wasm32-emscripten platform. + +.. + +.. bpo: 43253 +.. date: 2022-03-15-07-53-45 +.. nonce: rjdLFj +.. section: Library + +Fix a crash when closing transports where the underlying socket handle is +already invalid on the Proactor event loop. + +.. + +.. bpo: 47004 +.. date: 2022-03-13-15-04-05 +.. nonce: SyYpxd +.. section: Library + +Apply bugfixes from importlib_metadata 4.11.3, including bugfix for +EntryPoint.extras, which was returning match objects and not the extras +strings. + +.. + +.. bpo: 46985 +.. date: 2022-03-11-13-34-16 +.. nonce: BgoMr2 +.. section: Library + +Upgrade pip wheel bundled with ensurepip (pip 22.0.4) + +.. + +.. bpo: 46968 +.. date: 2022-03-10-14-51-11 +.. nonce: ym2QxL +.. section: Library + +:mod:`faulthandler`: On Linux 5.14 and newer, dynamically determine size of +signal handler stack size CPython allocates using +``getauxval(AT_MINSIGSTKSZ)``. This changes allows for Python extension's +request to Linux kernel to use AMX_TILE instruction set on Sapphire Rapids +Xeon processor to succeed, unblocking use of the ISA in frameworks. + +.. + +.. bpo: 46955 +.. date: 2022-03-08-22-41-59 +.. nonce: IOoonN +.. section: Library + +Expose :class:`asyncio.base_events.Server` as :class:`asyncio.Server`. Patch +by Stefan Zabka. + +.. + +.. bpo: 46932 +.. date: 2022-03-07-20-20-34 +.. nonce: xbarAs +.. section: Library + +Update bundled libexpat to 2.4.7 + +.. + +.. bpo: 25707 +.. date: 2022-03-05-09-43-53 +.. nonce: gTlclP +.. section: Library + +Fixed a file leak in :func:`xml.etree.ElementTree.iterparse` when the +iterator is not exhausted. Patch by Jacob Walls. + +.. + +.. bpo: 44886 +.. date: 2022-02-23-00-55-59 +.. nonce: I40Mbr +.. section: Library + +Inherit asyncio proactor datagram transport from +:class:`asyncio.DatagramTransport`. + +.. + +.. bpo: 46827 +.. date: 2022-02-22-15-08-30 +.. nonce: hvj38S +.. section: Library + +Support UDP sockets in :meth:`asyncio.loop.sock_connect` for selector-based +event loops. Patch by Thomas Grainger. + +.. + +.. bpo: 46811 +.. date: 2022-02-20-21-03-31 +.. nonce: 8BxgdQ +.. section: Library + +Make test suite support Expat >=2.4.5 + +.. + +.. bpo: 46252 +.. date: 2022-02-20-12-59-46 +.. nonce: KG1SqA +.. section: Library + +Raise :exc:`TypeError` if :class:`ssl.SSLSocket` is passed to +transport-based APIs. + +.. + +.. bpo: 46784 +.. date: 2022-02-18-22-10-30 +.. nonce: SVOQJx +.. section: Library + +Fix libexpat symbols collisions with user dynamically loaded or statically +linked libexpat in embedded Python. + +.. + +.. bpo: 39327 +.. date: 2022-02-17-13-10-50 +.. nonce: ytIT7Z +.. section: Library + +:func:`shutil.rmtree` can now work with VirtualBox shared folders when +running from the guest operating-system. + +.. + +.. bpo: 46756 +.. date: 2022-02-15-11-57-53 +.. nonce: AigSPi +.. section: Library + +Fix a bug in :meth:`urllib.request.HTTPPasswordMgr.find_user_password` and +:meth:`urllib.request.HTTPPasswordMgrWithPriorAuth.is_authenticated` which +allowed to bypass authorization. For example, access to URI +``example.org/foobar`` was allowed if the user was authorized for URI +``example.org/foo``. + +.. + +.. bpo: 45863 +.. date: 2022-02-09-00-53-23 +.. nonce: zqQXVv +.. section: Library + +When the :mod:`tarfile` module creates a pax format archive, it will put an +integer representation of timestamps in the ustar header (if possible) for +the benefit of older unarchivers, in addition to the existing full-precision +timestamps in the pax extended header. + +.. + +.. bpo: 46672 +.. date: 2022-02-07-13-15-16 +.. nonce: 4swIjx +.. section: Library + +Fix ``NameError`` in :func:`asyncio.gather` when initial type check fails. + +.. + +.. bpo: 45948 +.. date: 2022-02-05-18-22-05 +.. nonce: w4mCnE +.. section: Library + +Fixed a discrepancy in the C implementation of the +:mod:`xml.etree.ElementTree` module. Now, instantiating an +:class:`xml.etree.ElementTree.XMLParser` with a ``target=None`` keyword +provides a default :class:`xml.etree.ElementTree.TreeBuilder` target as the +Python implementation does. + +.. + +.. bpo: 46591 +.. date: 2022-01-31-15-40-38 +.. nonce: prBD1M +.. section: Library + +Make the IDLE doc URL on the About IDLE dialog clickable. + +.. + +.. bpo: 46400 +.. date: 2022-01-30-15-16-12 +.. nonce: vweUiO +.. section: Library + +expat: Update libexpat from 2.4.1 to 2.4.4 + +.. + +.. bpo: 46487 +.. date: 2022-01-27-12-24-38 +.. nonce: UDkN2z +.. section: Library + +Add the ``get_write_buffer_limits`` method to +:class:`asyncio.transports.WriteTransport` and to the SSL transport. + +.. + +.. bpo: 46539 +.. date: 2022-01-26-20-36-30 +.. nonce: 23iW1d +.. section: Library + +In :func:`typing.get_type_hints`, support evaluating stringified +``ClassVar`` and ``Final`` annotations inside ``Annotated``. Patch by +Gregory Beauregard. + +.. + +.. bpo: 46491 +.. date: 2022-01-24-23-55-30 +.. nonce: jmIKHo +.. section: Library + +Allow :data:`typing.Annotated` to wrap :data:`typing.Final` and +:data:`typing.ClassVar`. Patch by Gregory Beauregard. + +.. + +.. bpo: 46436 +.. date: 2022-01-23-19-37-00 +.. nonce: Biz1p9 +.. section: Library + +Fix command-line option ``-d``/``--directory`` in module :mod:`http.server` +which is ignored when combined with command-line option ``--cgi``. Patch by +G?ry Ogam. + +.. + +.. bpo: 41403 +.. date: 2022-01-23-18-04-45 +.. nonce: SgoHqV +.. section: Library + +Make :meth:`mock.patch` raise a :exc:`TypeError` with a relevant error +message on invalid arg. Previously it allowed a cryptic +:exc:`AttributeError` to escape. + +.. + +.. bpo: 46474 +.. date: 2022-01-22-14-49-10 +.. nonce: eKQhvx +.. section: Library + +In ``importlib.metadata.EntryPoint.pattern``, avoid potential REDoS by +limiting ambiguity in consecutive whitespace. + +.. + +.. bpo: 46469 +.. date: 2022-01-22-05-05-08 +.. nonce: plUab5 +.. section: Library + +:mod:`asyncio` generic classes now return :class:`types.GenericAlias` in +``__class_getitem__`` instead of the same class. + +.. + +.. bpo: 46434 +.. date: 2022-01-20-10-35-10 +.. nonce: geS-aP +.. section: Library + +:mod:`pdb` now gracefully handles ``help`` when :attr:`__doc__` is missing, +for example when run with pregenerated optimized ``.pyc`` files. + +.. + +.. bpo: 46333 +.. date: 2022-01-11-15-54-15 +.. nonce: B1faiF +.. section: Library + +The :meth:`__eq__` and :meth:`__hash__` methods of +:class:`typing.ForwardRef` now honor the ``module`` parameter of +:class:`typing.ForwardRef`. Forward references from different modules are +now differentiated. + +.. + +.. bpo: 43118 +.. date: 2021-12-29-14-42-09 +.. nonce: BoVi_5 +.. section: Library + +Fix a bug in :func:`inspect.signature` that was causing it to fail on some +subclasses of classes with a ``__text_signature__`` referencing module +globals. Patch by Weipeng Hong. + +.. + +.. bpo: 21987 +.. date: 2021-12-28-11-55-10 +.. nonce: avBK-p +.. section: Library + +Fix an issue with :meth:`tarfile.TarFile.getmember` getting a directory name +with a trailing slash. + +.. + +.. bpo: 20392 +.. date: 2021-12-22-12-02-27 +.. nonce: CLAFIp +.. section: Library + +Fix inconsistency with uppercase file extensions in +:meth:`MimeTypes.guess_type`. Patch by Kumar Aditya. + +.. + +.. bpo: 46080 +.. date: 2021-12-15-06-29-00 +.. nonce: AuQpLt +.. section: Library + +Fix exception in argparse help text generation if a +:class:`argparse.BooleanOptionalAction` argument's default is +``argparse.SUPPRESS`` and it has ``help`` specified. Patch by Felix +Fontein. + +.. + +.. bpo: 44439 +.. date: 2021-11-08-20-27-41 +.. nonce: I_8qro +.. section: Library + +Fix ``.write()`` method of a member file in ``ZipFile``, when the input data +is an object that supports the buffer protocol, the file length may be +wrong. + +.. + +.. bpo: 45703 +.. date: 2021-11-03-13-41-49 +.. nonce: 35AagL +.. section: Library + +When a namespace package is imported before another module from the same +namespace is created/installed in a different :data:`sys.path` location +while the program is running, calling the +:func:`importlib.invalidate_caches` function will now also guarantee the new +module is noticed. + +.. + +.. bpo: 24959 +.. date: 2021-09-06-15-46-53 +.. nonce: UVFgiO +.. section: Library + +Fix bug where :mod:`unittest` sometimes drops frames from tracebacks of +exceptions raised in tests. + +.. + +.. bpo: 46463 +.. date: 2022-01-21-21-33-48 +.. nonce: fBbdTG +.. section: Documentation + +Fixes :file:`escape4chm.py` script used when building the CHM documentation +file + +.. + +.. bpo: 46913 +.. date: 2022-03-03-17-36-24 +.. nonce: vxETIE +.. section: Tests + +Fix test_faulthandler.test_sigfpe() if Python is built with undefined +behavior sanitizer (UBSAN): disable UBSAN on the faulthandler_sigfpe() +function. Patch by Victor Stinner. + +.. + +.. bpo: 46708 +.. date: 2022-02-10-14-33-47 +.. nonce: avLfCb +.. section: Tests + +Prevent default asyncio event loop policy modification warning after +``test_asyncio`` execution. + +.. + +.. bpo: 46616 +.. date: 2022-02-02-18-14-38 +.. nonce: URvBtE +.. section: Tests + +Ensures ``test_importlib.test_windows`` cleans up registry keys after +completion. + +.. + +.. bpo: 44359 +.. date: 2022-02-02-02-24-04 +.. nonce: kPPSmN +.. section: Tests + +test_ftplib now silently ignores socket errors to prevent logging unhandled +threading exceptions. Patch by Victor Stinner. + +.. + +.. bpo: 46542 +.. date: 2022-01-31-17-34-13 +.. nonce: RTMm1T +.. section: Tests + +Fix a Python crash in test_lib2to3 when using Python built in debug mode: +limit the recursion limit. Patch by Victor Stinner. + +.. + +.. bpo: 46576 +.. date: 2022-01-29-12-37-53 +.. nonce: -prRaV +.. section: Tests + +test_peg_generator now disables compiler optimization when testing +compilation of its own C extensions to significantly speed up the testing on +non-debug builds of CPython. + +.. + +.. bpo: 46542 +.. date: 2022-01-28-01-17-10 +.. nonce: xRLTdj +.. section: Tests + +Fix ``test_json`` tests checking for :exc:`RecursionError`: modify these +tests to use ``support.infinite_recursion()``. Patch by Victor Stinner. + +.. + +.. bpo: 13886 +.. date: 2022-01-17-13-10-04 +.. nonce: 5mZH4b +.. section: Tests + +Skip test_builtin PTY tests on non-ASCII characters if the readline module +is loaded. The readline module changes input() behavior, but test_builtin is +not intented to test the readline module. Patch by Victor Stinner. + +.. + +.. bpo: 47024 +.. date: 2022-03-15-09-28-55 +.. nonce: t7-dcu +.. section: Build + +Update OpenSSL to 1.1.1n for macOS installers and all Windows builds. + +.. + +.. bpo: 38472 +.. date: 2022-01-26-22-59-12 +.. nonce: RxfLho +.. section: Build + +Fix GCC detection in setup.py when cross-compiling. The C compiler is now +run with LC_ALL=C. Previously, the detection failed with a German locale. + +.. + +.. bpo: 46513 +.. date: 2022-01-25-12-32-37 +.. nonce: mPm9B4 +.. section: Build + +:program:`configure` no longer uses ``AC_C_CHAR_UNSIGNED`` macro and +``pyconfig.h`` no longer defines reserved symbol ``__CHAR_UNSIGNED__``. + +.. + +.. bpo: 45925 +.. date: 2022-01-08-12-43-31 +.. nonce: 38F3NO +.. section: Build + +Update Windows installer to use SQLite 3.37.2. + +.. + +.. bpo: 44549 +.. date: 2022-03-07-17-46-40 +.. nonce: SPrGS9 +.. section: Windows + +Update bzip2 to 1.0.8 in Windows builds to mitigate CVE-2016-3189 and +CVE-2019-12900 + +.. + +.. bpo: 46948 +.. date: 2022-03-07-16-34-11 +.. nonce: Ufd4tG +.. section: Windows + +Prevent CVE-2022-26488 by ensuring the Add to PATH option in the Windows +installer uses the correct path when being repaired. + +.. + +.. bpo: 46638 +.. date: 2022-02-04-18-02-33 +.. nonce: mSJOSX +.. section: Windows + +Ensures registry virtualization is consistently disabled. For 3.10 and +earlier, it remains enabled (some registry writes are protected), while for +3.11 and later it is disabled (registry modifications affect all +applications). + +.. + +.. bpo: 45925 +.. date: 2022-01-26-12-04-09 +.. nonce: yBSiYO +.. section: macOS + +Update macOS installer to SQLite 3.37.2. + +.. + +.. bpo: 46630 +.. date: 2022-02-03-15-47-53 +.. nonce: tREOjo +.. section: IDLE + +Make query dialogs on Windows start with a cursor in the entry box. + +.. + +.. bpo: 45296 +.. date: 2022-01-26-19-33-55 +.. nonce: LzZKdU +.. section: IDLE + +Clarify close, quit, and exit in IDLE. In the File menu, 'Close' and 'Exit' +are now 'Close Window' (the current one) and 'Exit' is now 'Exit IDLE' (by +closing all windows). In Shell, 'quit()' and 'exit()' mean 'close Shell'. +If there are no other windows, this also exits IDLE. + +.. + +.. bpo: 45447 +.. date: 2021-10-14-16-55-03 +.. nonce: FhiH5P +.. section: IDLE + +Apply IDLE syntax highlighting to `.pyi` files. Patch by Alex Waygood and +Terry Jan Reedy. diff --git a/Misc/NEWS.d/next/Build/2022-01-08-12-43-31.bpo-45925.38F3NO.rst b/Misc/NEWS.d/next/Build/2022-01-08-12-43-31.bpo-45925.38F3NO.rst deleted file mode 100644 index e802912bfcff7..0000000000000 --- a/Misc/NEWS.d/next/Build/2022-01-08-12-43-31.bpo-45925.38F3NO.rst +++ /dev/null @@ -1 +0,0 @@ -Update Windows installer to use SQLite 3.37.2. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Build/2022-01-25-12-32-37.bpo-46513.mPm9B4.rst b/Misc/NEWS.d/next/Build/2022-01-25-12-32-37.bpo-46513.mPm9B4.rst deleted file mode 100644 index b8986ae31a340..0000000000000 --- a/Misc/NEWS.d/next/Build/2022-01-25-12-32-37.bpo-46513.mPm9B4.rst +++ /dev/null @@ -1,2 +0,0 @@ -:program:`configure` no longer uses ``AC_C_CHAR_UNSIGNED`` macro and -``pyconfig.h`` no longer defines reserved symbol ``__CHAR_UNSIGNED__``. diff --git a/Misc/NEWS.d/next/Build/2022-01-26-22-59-12.bpo-38472.RxfLho.rst b/Misc/NEWS.d/next/Build/2022-01-26-22-59-12.bpo-38472.RxfLho.rst deleted file mode 100644 index 4e0ee70bdc513..0000000000000 --- a/Misc/NEWS.d/next/Build/2022-01-26-22-59-12.bpo-38472.RxfLho.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix GCC detection in setup.py when cross-compiling. The C compiler is now -run with LC_ALL=C. Previously, the detection failed with a German locale. diff --git a/Misc/NEWS.d/next/Build/2022-03-15-09-28-55.bpo-47024.t7-dcu.rst b/Misc/NEWS.d/next/Build/2022-03-15-09-28-55.bpo-47024.t7-dcu.rst deleted file mode 100644 index 1035cbab1ba61..0000000000000 --- a/Misc/NEWS.d/next/Build/2022-03-15-09-28-55.bpo-47024.t7-dcu.rst +++ /dev/null @@ -1 +0,0 @@ -Update OpenSSL to 1.1.1n for macOS installers and all Windows builds. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-01-14-20-55-34.bpo-46383.v8MTl4.rst b/Misc/NEWS.d/next/Core and Builtins/2022-01-14-20-55-34.bpo-46383.v8MTl4.rst deleted file mode 100644 index 8f8b12732a690..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-01-14-20-55-34.bpo-46383.v8MTl4.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix invalid signature of ``_zoneinfo``'s ``module_free`` function to resolve -a crash on wasm32-emscripten platform. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-01-22-14-39-23.bpo-46417.3U5SfN.rst b/Misc/NEWS.d/next/Core and Builtins/2022-01-22-14-39-23.bpo-46417.3U5SfN.rst deleted file mode 100644 index 54fe09b7ba454..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-01-22-14-39-23.bpo-46417.3U5SfN.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fix a race condition on setting a type ``__bases__`` attribute: the internal -function ``add_subclass()`` now gets the ``PyTypeObject.tp_subclasses`` -member after calling :c:func:`PyWeakref_NewRef` which can trigger a garbage -collection which can indirectly modify ``PyTypeObject.tp_subclasses``. Patch -by Victor Stinner. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-01-24-21-24-41.bpo-46503.4UrPsE.rst b/Misc/NEWS.d/next/Core and Builtins/2022-01-24-21-24-41.bpo-46503.4UrPsE.rst deleted file mode 100644 index e48028d72ca8e..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-01-24-21-24-41.bpo-46503.4UrPsE.rst +++ /dev/null @@ -1 +0,0 @@ -Fix an assert when parsing some invalid \N escape sequences in f-strings. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst deleted file mode 100644 index cd3df72664823..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst +++ /dev/null @@ -1 +0,0 @@ -Fix docstrings of :attr:`~property.getter`, :attr:`~property.setter`, and :attr:`~property.deleter` to clarify that they create a new copy of the property. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-04-04-33-18.bpo-46615.puArY9.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-04-04-33-18.bpo-46615.puArY9.rst deleted file mode 100644 index 6dee92a546e33..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-04-04-33-18.bpo-46615.puArY9.rst +++ /dev/null @@ -1 +0,0 @@ -When iterating over sets internally in ``setobject.c``, acquire strong references to the resulting items from the set. This prevents crashes in corner-cases of various set operations where the set gets mutated. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-06-23-08-30.bpo-40479.zED3Zu.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-06-23-08-30.bpo-40479.zED3Zu.rst deleted file mode 100644 index 52701d53d8fe2..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-06-23-08-30.bpo-40479.zED3Zu.rst +++ /dev/null @@ -1 +0,0 @@ -Add a missing call to ``va_end()`` in ``Modules/_hashopenssl.c``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-12-11-16-40.bpo-46732.3Z_qxd.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-12-11-16-40.bpo-46732.3Z_qxd.rst deleted file mode 100644 index 9937116bb2e7b..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-12-11-16-40.bpo-46732.3Z_qxd.rst +++ /dev/null @@ -1,2 +0,0 @@ -Correct the docstring for the :meth:`__bool__` method. Patch by Jelle -Zijlstra. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-15-20-26-46.bpo-46762.1H7vab.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-15-20-26-46.bpo-46762.1H7vab.rst deleted file mode 100644 index cd53eb4ffaddd..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-15-20-26-46.bpo-46762.1H7vab.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix an assert failure in debug builds when a '<', '>', or '=' is the last -character in an f-string that's missing a closing right brace. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-22-12-07-53.bpo-46794.6WvJ9o.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-22-12-07-53.bpo-46794.6WvJ9o.rst deleted file mode 100644 index 127387d32cb7a..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-22-12-07-53.bpo-46794.6WvJ9o.rst +++ /dev/null @@ -1 +0,0 @@ -Bump up the libexpat version into 2.4.6 diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-25-02-01-42.bpo-46852._3zg8D.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-25-02-01-42.bpo-46852._3zg8D.rst deleted file mode 100644 index 65b826473b915..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-25-02-01-42.bpo-46852._3zg8D.rst +++ /dev/null @@ -1,3 +0,0 @@ -Rename the private undocumented ``float.__set_format__()`` method to -``float.__setformat__()`` to fix a typo introduced in Python 3.7. The method -is only used by test_float. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Documentation/2022-01-21-21-33-48.bpo-46463.fBbdTG.rst b/Misc/NEWS.d/next/Documentation/2022-01-21-21-33-48.bpo-46463.fBbdTG.rst deleted file mode 100644 index d418190bb8fc8..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2022-01-21-21-33-48.bpo-46463.fBbdTG.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixes :file:`escape4chm.py` script used when building the CHM documentation -file diff --git a/Misc/NEWS.d/next/IDLE/2021-10-14-16-55-03.bpo-45447.FhiH5P.rst b/Misc/NEWS.d/next/IDLE/2021-10-14-16-55-03.bpo-45447.FhiH5P.rst deleted file mode 100644 index 2b5170c7631d2..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2021-10-14-16-55-03.bpo-45447.FhiH5P.rst +++ /dev/null @@ -1,2 +0,0 @@ -Apply IDLE syntax highlighting to `.pyi` files. Patch by Alex Waygood -and Terry Jan Reedy. diff --git a/Misc/NEWS.d/next/IDLE/2022-01-26-19-33-55.bpo-45296.LzZKdU.rst b/Misc/NEWS.d/next/IDLE/2022-01-26-19-33-55.bpo-45296.LzZKdU.rst deleted file mode 100644 index a5b0f8b4ffa80..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2022-01-26-19-33-55.bpo-45296.LzZKdU.rst +++ /dev/null @@ -1,4 +0,0 @@ -Clarify close, quit, and exit in IDLE. In the File menu, 'Close' and 'Exit' -are now 'Close Window' (the current one) and 'Exit' is now 'Exit IDLE' -(by closing all windows). In Shell, 'quit()' and 'exit()' mean 'close Shell'. -If there are no other windows, this also exits IDLE. diff --git a/Misc/NEWS.d/next/IDLE/2022-02-03-15-47-53.bpo-46630.tREOjo.rst b/Misc/NEWS.d/next/IDLE/2022-02-03-15-47-53.bpo-46630.tREOjo.rst deleted file mode 100644 index 81e35486eaf21..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2022-02-03-15-47-53.bpo-46630.tREOjo.rst +++ /dev/null @@ -1 +0,0 @@ -Make query dialogs on Windows start with a cursor in the entry box. diff --git a/Misc/NEWS.d/next/Library/2021-09-06-15-46-53.bpo-24959.UVFgiO.rst b/Misc/NEWS.d/next/Library/2021-09-06-15-46-53.bpo-24959.UVFgiO.rst deleted file mode 100644 index b702986f9468a..0000000000000 --- a/Misc/NEWS.d/next/Library/2021-09-06-15-46-53.bpo-24959.UVFgiO.rst +++ /dev/null @@ -1 +0,0 @@ -Fix bug where :mod:`unittest` sometimes drops frames from tracebacks of exceptions raised in tests. diff --git a/Misc/NEWS.d/next/Library/2021-11-03-13-41-49.bpo-45703.35AagL.rst b/Misc/NEWS.d/next/Library/2021-11-03-13-41-49.bpo-45703.35AagL.rst deleted file mode 100644 index 9fa9be56b8327..0000000000000 --- a/Misc/NEWS.d/next/Library/2021-11-03-13-41-49.bpo-45703.35AagL.rst +++ /dev/null @@ -1,5 +0,0 @@ -When a namespace package is imported before another module from the same -namespace is created/installed in a different :data:`sys.path` location -while the program is running, calling the -:func:`importlib.invalidate_caches` function will now also guarantee the new -module is noticed. diff --git a/Misc/NEWS.d/next/Library/2021-11-08-20-27-41.bpo-44439.I_8qro.rst b/Misc/NEWS.d/next/Library/2021-11-08-20-27-41.bpo-44439.I_8qro.rst deleted file mode 100644 index f4e562c4236d2..0000000000000 --- a/Misc/NEWS.d/next/Library/2021-11-08-20-27-41.bpo-44439.I_8qro.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix ``.write()`` method of a member file in ``ZipFile``, when the input data is -an object that supports the buffer protocol, the file length may be wrong. diff --git a/Misc/NEWS.d/next/Library/2021-12-15-06-29-00.bpo-46080.AuQpLt.rst b/Misc/NEWS.d/next/Library/2021-12-15-06-29-00.bpo-46080.AuQpLt.rst deleted file mode 100644 index e42d84e31e759..0000000000000 --- a/Misc/NEWS.d/next/Library/2021-12-15-06-29-00.bpo-46080.AuQpLt.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix exception in argparse help text generation if a -:class:`argparse.BooleanOptionalAction` argument's default is -``argparse.SUPPRESS`` and it has ``help`` specified. Patch by Felix Fontein. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2021-12-22-12-02-27.bpo-20392.CLAFIp.rst b/Misc/NEWS.d/next/Library/2021-12-22-12-02-27.bpo-20392.CLAFIp.rst deleted file mode 100644 index 8973c4d433174..0000000000000 --- a/Misc/NEWS.d/next/Library/2021-12-22-12-02-27.bpo-20392.CLAFIp.rst +++ /dev/null @@ -1 +0,0 @@ -Fix inconsistency with uppercase file extensions in :meth:`MimeTypes.guess_type`. Patch by Kumar Aditya. diff --git a/Misc/NEWS.d/next/Library/2021-12-28-11-55-10.bpo-21987.avBK-p.rst b/Misc/NEWS.d/next/Library/2021-12-28-11-55-10.bpo-21987.avBK-p.rst deleted file mode 100644 index 305dd16d53b49..0000000000000 --- a/Misc/NEWS.d/next/Library/2021-12-28-11-55-10.bpo-21987.avBK-p.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix an issue with :meth:`tarfile.TarFile.getmember` getting a directory name -with a trailing slash. diff --git a/Misc/NEWS.d/next/Library/2021-12-29-14-42-09.bpo-43118.BoVi_5.rst b/Misc/NEWS.d/next/Library/2021-12-29-14-42-09.bpo-43118.BoVi_5.rst deleted file mode 100644 index a37c22cd78c09..0000000000000 --- a/Misc/NEWS.d/next/Library/2021-12-29-14-42-09.bpo-43118.BoVi_5.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix a bug in :func:`inspect.signature` that was causing it to fail on some -subclasses of classes with a ``__text_signature__`` referencing module -globals. Patch by Weipeng Hong. diff --git a/Misc/NEWS.d/next/Library/2022-01-11-15-54-15.bpo-46333.B1faiF.rst b/Misc/NEWS.d/next/Library/2022-01-11-15-54-15.bpo-46333.B1faiF.rst deleted file mode 100644 index ec3c6d54ee499..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-11-15-54-15.bpo-46333.B1faiF.rst +++ /dev/null @@ -1,4 +0,0 @@ -The :meth:`__eq__` and :meth:`__hash__` methods of -:class:`typing.ForwardRef` now honor the ``module`` parameter of -:class:`typing.ForwardRef`. Forward references from different -modules are now differentiated. diff --git a/Misc/NEWS.d/next/Library/2022-01-20-10-35-10.bpo-46434.geS-aP.rst b/Misc/NEWS.d/next/Library/2022-01-20-10-35-10.bpo-46434.geS-aP.rst deleted file mode 100644 index 6000781fa5aea..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-20-10-35-10.bpo-46434.geS-aP.rst +++ /dev/null @@ -1,2 +0,0 @@ -:mod:`pdb` now gracefully handles ``help`` when :attr:`__doc__` is missing, -for example when run with pregenerated optimized ``.pyc`` files. diff --git a/Misc/NEWS.d/next/Library/2022-01-22-05-05-08.bpo-46469.plUab5.rst b/Misc/NEWS.d/next/Library/2022-01-22-05-05-08.bpo-46469.plUab5.rst deleted file mode 100644 index 0d0e4b5d3d735..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-22-05-05-08.bpo-46469.plUab5.rst +++ /dev/null @@ -1 +0,0 @@ -:mod:`asyncio` generic classes now return :class:`types.GenericAlias` in ``__class_getitem__`` instead of the same class. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2022-01-22-14-49-10.bpo-46474.eKQhvx.rst b/Misc/NEWS.d/next/Library/2022-01-22-14-49-10.bpo-46474.eKQhvx.rst deleted file mode 100644 index 156b7de4f6787..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-22-14-49-10.bpo-46474.eKQhvx.rst +++ /dev/null @@ -1,2 +0,0 @@ -In ``importlib.metadata.EntryPoint.pattern``, avoid potential REDoS by -limiting ambiguity in consecutive whitespace. diff --git a/Misc/NEWS.d/next/Library/2022-01-23-18-04-45.bpo-41403.SgoHqV.rst b/Misc/NEWS.d/next/Library/2022-01-23-18-04-45.bpo-41403.SgoHqV.rst deleted file mode 100644 index ede159b25641f..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-23-18-04-45.bpo-41403.SgoHqV.rst +++ /dev/null @@ -1,3 +0,0 @@ -Make :meth:`mock.patch` raise a :exc:`TypeError` with a relevant error -message on invalid arg. Previously it allowed a cryptic -:exc:`AttributeError` to escape. diff --git a/Misc/NEWS.d/next/Library/2022-01-23-19-37-00.bpo-46436.Biz1p9.rst b/Misc/NEWS.d/next/Library/2022-01-23-19-37-00.bpo-46436.Biz1p9.rst deleted file mode 100644 index ccfd949506443..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-23-19-37-00.bpo-46436.Biz1p9.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix command-line option ``-d``/``--directory`` in module :mod:`http.server` -which is ignored when combined with command-line option ``--cgi``. Patch by -G?ry Ogam. diff --git a/Misc/NEWS.d/next/Library/2022-01-24-23-55-30.bpo-46491.jmIKHo.rst b/Misc/NEWS.d/next/Library/2022-01-24-23-55-30.bpo-46491.jmIKHo.rst deleted file mode 100644 index f66e8868f753f..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-24-23-55-30.bpo-46491.jmIKHo.rst +++ /dev/null @@ -1 +0,0 @@ -Allow :data:`typing.Annotated` to wrap :data:`typing.Final` and :data:`typing.ClassVar`. Patch by Gregory Beauregard. diff --git a/Misc/NEWS.d/next/Library/2022-01-26-20-36-30.bpo-46539.23iW1d.rst b/Misc/NEWS.d/next/Library/2022-01-26-20-36-30.bpo-46539.23iW1d.rst deleted file mode 100644 index 2bdde21b6e58e..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-26-20-36-30.bpo-46539.23iW1d.rst +++ /dev/null @@ -1 +0,0 @@ -In :func:`typing.get_type_hints`, support evaluating stringified ``ClassVar`` and ``Final`` annotations inside ``Annotated``. Patch by Gregory Beauregard. diff --git a/Misc/NEWS.d/next/Library/2022-01-27-12-24-38.bpo-46487.UDkN2z.rst b/Misc/NEWS.d/next/Library/2022-01-27-12-24-38.bpo-46487.UDkN2z.rst deleted file mode 100644 index adbc50a4bf9b7..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-27-12-24-38.bpo-46487.UDkN2z.rst +++ /dev/null @@ -1 +0,0 @@ -Add the ``get_write_buffer_limits`` method to :class:`asyncio.transports.WriteTransport` and to the SSL transport. diff --git a/Misc/NEWS.d/next/Library/2022-01-30-15-16-12.bpo-46400.vweUiO.rst b/Misc/NEWS.d/next/Library/2022-01-30-15-16-12.bpo-46400.vweUiO.rst deleted file mode 100644 index 9c1f24c0e5171..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-30-15-16-12.bpo-46400.vweUiO.rst +++ /dev/null @@ -1 +0,0 @@ -expat: Update libexpat from 2.4.1 to 2.4.4 diff --git a/Misc/NEWS.d/next/Library/2022-01-31-15-40-38.bpo-46591.prBD1M.rst b/Misc/NEWS.d/next/Library/2022-01-31-15-40-38.bpo-46591.prBD1M.rst deleted file mode 100644 index 7785faa1c4cbf..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-31-15-40-38.bpo-46591.prBD1M.rst +++ /dev/null @@ -1 +0,0 @@ -Make the IDLE doc URL on the About IDLE dialog clickable. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2022-02-05-18-22-05.bpo-45948.w4mCnE.rst b/Misc/NEWS.d/next/Library/2022-02-05-18-22-05.bpo-45948.w4mCnE.rst deleted file mode 100644 index 42dc114b5ad60..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-05-18-22-05.bpo-45948.w4mCnE.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fixed a discrepancy in the C implementation of the -:mod:`xml.etree.ElementTree` module. Now, instantiating an -:class:`xml.etree.ElementTree.XMLParser` with a ``target=None`` -keyword provides a default :class:`xml.etree.ElementTree.TreeBuilder` -target as the Python implementation does. diff --git a/Misc/NEWS.d/next/Library/2022-02-07-13-15-16.bpo-46672.4swIjx.rst b/Misc/NEWS.d/next/Library/2022-02-07-13-15-16.bpo-46672.4swIjx.rst deleted file mode 100644 index 9a76c29a334d8..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-07-13-15-16.bpo-46672.4swIjx.rst +++ /dev/null @@ -1 +0,0 @@ -Fix ``NameError`` in :func:`asyncio.gather` when initial type check fails. diff --git a/Misc/NEWS.d/next/Library/2022-02-09-00-53-23.bpo-45863.zqQXVv.rst b/Misc/NEWS.d/next/Library/2022-02-09-00-53-23.bpo-45863.zqQXVv.rst deleted file mode 100644 index 3a1335cc77b9d..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-09-00-53-23.bpo-45863.zqQXVv.rst +++ /dev/null @@ -1 +0,0 @@ -When the :mod:`tarfile` module creates a pax format archive, it will put an integer representation of timestamps in the ustar header (if possible) for the benefit of older unarchivers, in addition to the existing full-precision timestamps in the pax extended header. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2022-02-15-11-57-53.bpo-46756.AigSPi.rst b/Misc/NEWS.d/next/Library/2022-02-15-11-57-53.bpo-46756.AigSPi.rst deleted file mode 100644 index 1660640c5d3fb..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-15-11-57-53.bpo-46756.AigSPi.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fix a bug in :meth:`urllib.request.HTTPPasswordMgr.find_user_password` and -:meth:`urllib.request.HTTPPasswordMgrWithPriorAuth.is_authenticated` which -allowed to bypass authorization. For example, access to URI -``example.org/foobar`` was allowed if the user was authorized for URI -``example.org/foo``. diff --git a/Misc/NEWS.d/next/Library/2022-02-17-13-10-50.bpo-39327.ytIT7Z.rst b/Misc/NEWS.d/next/Library/2022-02-17-13-10-50.bpo-39327.ytIT7Z.rst deleted file mode 100644 index fc6e8250922ff..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-17-13-10-50.bpo-39327.ytIT7Z.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`shutil.rmtree` can now work with VirtualBox shared folders when -running from the guest operating-system. diff --git a/Misc/NEWS.d/next/Library/2022-02-18-22-10-30.bpo-46784.SVOQJx.rst b/Misc/NEWS.d/next/Library/2022-02-18-22-10-30.bpo-46784.SVOQJx.rst deleted file mode 100644 index d190816637ae8..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-18-22-10-30.bpo-46784.SVOQJx.rst +++ /dev/null @@ -1 +0,0 @@ -Fix libexpat symbols collisions with user dynamically loaded or statically linked libexpat in embedded Python. diff --git a/Misc/NEWS.d/next/Library/2022-02-20-12-59-46.bpo-46252.KG1SqA.rst b/Misc/NEWS.d/next/Library/2022-02-20-12-59-46.bpo-46252.KG1SqA.rst deleted file mode 100644 index a15e7aaaa3389..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-20-12-59-46.bpo-46252.KG1SqA.rst +++ /dev/null @@ -1,2 +0,0 @@ -Raise :exc:`TypeError` if :class:`ssl.SSLSocket` is passed to -transport-based APIs. diff --git a/Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst b/Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst deleted file mode 100644 index 6969bd1898f65..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst +++ /dev/null @@ -1 +0,0 @@ -Make test suite support Expat >=2.4.5 diff --git a/Misc/NEWS.d/next/Library/2022-02-22-15-08-30.bpo-46827.hvj38S.rst b/Misc/NEWS.d/next/Library/2022-02-22-15-08-30.bpo-46827.hvj38S.rst deleted file mode 100644 index 259686ab1ddda..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-22-15-08-30.bpo-46827.hvj38S.rst +++ /dev/null @@ -1 +0,0 @@ -Support UDP sockets in :meth:`asyncio.loop.sock_connect` for selector-based event loops. Patch by Thomas Grainger. diff --git a/Misc/NEWS.d/next/Library/2022-02-23-00-55-59.bpo-44886.I40Mbr.rst b/Misc/NEWS.d/next/Library/2022-02-23-00-55-59.bpo-44886.I40Mbr.rst deleted file mode 100644 index be223ddd58ba1..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-23-00-55-59.bpo-44886.I40Mbr.rst +++ /dev/null @@ -1,2 +0,0 @@ -Inherit asyncio proactor datagram transport from -:class:`asyncio.DatagramTransport`. diff --git a/Misc/NEWS.d/next/Library/2022-03-05-09-43-53.bpo-25707.gTlclP.rst b/Misc/NEWS.d/next/Library/2022-03-05-09-43-53.bpo-25707.gTlclP.rst deleted file mode 100644 index a59f0a7657ff2..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-05-09-43-53.bpo-25707.gTlclP.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed a file leak in :func:`xml.etree.ElementTree.iterparse` when the -iterator is not exhausted. Patch by Jacob Walls. diff --git a/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst b/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst deleted file mode 100644 index 8545c656eab89..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst +++ /dev/null @@ -1 +0,0 @@ -Update bundled libexpat to 2.4.7 diff --git a/Misc/NEWS.d/next/Library/2022-03-08-22-41-59.bpo-46955.IOoonN.rst b/Misc/NEWS.d/next/Library/2022-03-08-22-41-59.bpo-46955.IOoonN.rst deleted file mode 100644 index 75fee1240d3cd..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-08-22-41-59.bpo-46955.IOoonN.rst +++ /dev/null @@ -1,2 +0,0 @@ -Expose :class:`asyncio.base_events.Server` as :class:`asyncio.Server`. Patch -by Stefan Zabka. diff --git a/Misc/NEWS.d/next/Library/2022-03-10-14-51-11.bpo-46968.ym2QxL.rst b/Misc/NEWS.d/next/Library/2022-03-10-14-51-11.bpo-46968.ym2QxL.rst deleted file mode 100644 index 0da5ae76572ba..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-10-14-51-11.bpo-46968.ym2QxL.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`faulthandler`: On Linux 5.14 and newer, dynamically determine size of -signal handler stack size CPython allocates using ``getauxval(AT_MINSIGSTKSZ)``. -This changes allows for Python extension's request to Linux kernel to use -AMX_TILE instruction set on Sapphire Rapids Xeon processor to succeed, -unblocking use of the ISA in frameworks. diff --git a/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst b/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst deleted file mode 100644 index 2e08ee837f583..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst +++ /dev/null @@ -1 +0,0 @@ -Upgrade pip wheel bundled with ensurepip (pip 22.0.4) diff --git a/Misc/NEWS.d/next/Library/2022-03-13-15-04-05.bpo-47004.SyYpxd.rst b/Misc/NEWS.d/next/Library/2022-03-13-15-04-05.bpo-47004.SyYpxd.rst deleted file mode 100644 index 3cb3b212d89e9..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-13-15-04-05.bpo-47004.SyYpxd.rst +++ /dev/null @@ -1,3 +0,0 @@ -Apply bugfixes from importlib_metadata 4.11.3, including bugfix for -EntryPoint.extras, which was returning match objects and not the extras -strings. diff --git a/Misc/NEWS.d/next/Library/2022-03-15-07-53-45.bpo-43253.rjdLFj.rst b/Misc/NEWS.d/next/Library/2022-03-15-07-53-45.bpo-43253.rjdLFj.rst deleted file mode 100644 index b9920cb821b35..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-15-07-53-45.bpo-43253.rjdLFj.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a crash when closing transports where the underlying socket handle is already invalid on the Proactor event loop. diff --git a/Misc/NEWS.d/next/Tests/2022-01-17-13-10-04.bpo-13886.5mZH4b.rst b/Misc/NEWS.d/next/Tests/2022-01-17-13-10-04.bpo-13886.5mZH4b.rst deleted file mode 100644 index cd19dce37d5c8..0000000000000 --- a/Misc/NEWS.d/next/Tests/2022-01-17-13-10-04.bpo-13886.5mZH4b.rst +++ /dev/null @@ -1,3 +0,0 @@ -Skip test_builtin PTY tests on non-ASCII characters if the readline module -is loaded. The readline module changes input() behavior, but test_builtin is -not intented to test the readline module. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Tests/2022-01-28-01-17-10.bpo-46542.xRLTdj.rst b/Misc/NEWS.d/next/Tests/2022-01-28-01-17-10.bpo-46542.xRLTdj.rst deleted file mode 100644 index c6b64ce017b6c..0000000000000 --- a/Misc/NEWS.d/next/Tests/2022-01-28-01-17-10.bpo-46542.xRLTdj.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix ``test_json`` tests checking for :exc:`RecursionError`: modify these tests -to use ``support.infinite_recursion()``. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Tests/2022-01-29-12-37-53.bpo-46576.-prRaV.rst b/Misc/NEWS.d/next/Tests/2022-01-29-12-37-53.bpo-46576.-prRaV.rst deleted file mode 100644 index be50fc8cbe0a5..0000000000000 --- a/Misc/NEWS.d/next/Tests/2022-01-29-12-37-53.bpo-46576.-prRaV.rst +++ /dev/null @@ -1,3 +0,0 @@ -test_peg_generator now disables compiler optimization when testing -compilation of its own C extensions to significantly speed up the -testing on non-debug builds of CPython. diff --git a/Misc/NEWS.d/next/Tests/2022-01-31-17-34-13.bpo-46542.RTMm1T.rst b/Misc/NEWS.d/next/Tests/2022-01-31-17-34-13.bpo-46542.RTMm1T.rst deleted file mode 100644 index 5596498724930..0000000000000 --- a/Misc/NEWS.d/next/Tests/2022-01-31-17-34-13.bpo-46542.RTMm1T.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a Python crash in test_lib2to3 when using Python built in debug mode: -limit the recursion limit. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Tests/2022-02-02-02-24-04.bpo-44359.kPPSmN.rst b/Misc/NEWS.d/next/Tests/2022-02-02-02-24-04.bpo-44359.kPPSmN.rst deleted file mode 100644 index 00c29b1ca4089..0000000000000 --- a/Misc/NEWS.d/next/Tests/2022-02-02-02-24-04.bpo-44359.kPPSmN.rst +++ /dev/null @@ -1,2 +0,0 @@ -test_ftplib now silently ignores socket errors to prevent logging unhandled -threading exceptions. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Tests/2022-02-02-18-14-38.bpo-46616.URvBtE.rst b/Misc/NEWS.d/next/Tests/2022-02-02-18-14-38.bpo-46616.URvBtE.rst deleted file mode 100644 index 31c63c3d8f181..0000000000000 --- a/Misc/NEWS.d/next/Tests/2022-02-02-18-14-38.bpo-46616.URvBtE.rst +++ /dev/null @@ -1,2 +0,0 @@ -Ensures ``test_importlib.test_windows`` cleans up registry keys after -completion. diff --git a/Misc/NEWS.d/next/Tests/2022-02-10-14-33-47.bpo-46708.avLfCb.rst b/Misc/NEWS.d/next/Tests/2022-02-10-14-33-47.bpo-46708.avLfCb.rst deleted file mode 100644 index 119107a8fb96c..0000000000000 --- a/Misc/NEWS.d/next/Tests/2022-02-10-14-33-47.bpo-46708.avLfCb.rst +++ /dev/null @@ -1,2 +0,0 @@ -Prevent default asyncio event loop policy modification warning after -``test_asyncio`` execution. diff --git a/Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst b/Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst deleted file mode 100644 index 65fed1c249d87..0000000000000 --- a/Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix test_faulthandler.test_sigfpe() if Python is built with undefined -behavior sanitizer (UBSAN): disable UBSAN on the faulthandler_sigfpe() -function. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Windows/2022-02-04-18-02-33.bpo-46638.mSJOSX.rst b/Misc/NEWS.d/next/Windows/2022-02-04-18-02-33.bpo-46638.mSJOSX.rst deleted file mode 100644 index 536aae68f8329..0000000000000 --- a/Misc/NEWS.d/next/Windows/2022-02-04-18-02-33.bpo-46638.mSJOSX.rst +++ /dev/null @@ -1,4 +0,0 @@ -Ensures registry virtualization is consistently disabled. For 3.10 and -earlier, it remains enabled (some registry writes are protected), while for -3.11 and later it is disabled (registry modifications affect all -applications). diff --git a/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst b/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst deleted file mode 100644 index cfc4827882ded..0000000000000 --- a/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst +++ /dev/null @@ -1,2 +0,0 @@ -Prevent CVE-2022-26488 by ensuring the Add to PATH option in the Windows -installer uses the correct path when being repaired. diff --git a/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst b/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst deleted file mode 100644 index 0f1ef9af6c617..0000000000000 --- a/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst +++ /dev/null @@ -1,2 +0,0 @@ -Update bzip2 to 1.0.8 in Windows builds to mitigate CVE-2016-3189 and -CVE-2019-12900 diff --git a/Misc/NEWS.d/next/macOS/2022-01-26-12-04-09.bpo-45925.yBSiYO.rst b/Misc/NEWS.d/next/macOS/2022-01-26-12-04-09.bpo-45925.yBSiYO.rst deleted file mode 100644 index 3705266c154b7..0000000000000 --- a/Misc/NEWS.d/next/macOS/2022-01-26-12-04-09.bpo-45925.yBSiYO.rst +++ /dev/null @@ -1 +0,0 @@ -Update macOS installer to SQLite 3.37.2. \ No newline at end of file diff --git a/README.rst b/README.rst index 2d921be5e03d4..8856328f9d0bf 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -This is Python version 3.9.10 +This is Python version 3.9.11 ============================= .. image:: https://travis-ci.org/python/cpython.svg?branch=3.9 From webhook-mailer at python.org Tue Mar 15 20:08:45 2022 From: webhook-mailer at python.org (brandtbucher) Date: Wed, 16 Mar 2022 00:08:45 -0000 Subject: [Python-checkins] bpo-46841: Don't scan backwards in bytecode (GH-31901) Message-ID: https://github.com/python/cpython/commit/49e1e1e1bd59cac1855b1ef4dec05d649ebcd81a commit: 49e1e1e1bd59cac1855b1ef4dec05d649ebcd81a branch: main author: Mark Shannon committer: brandtbucher date: 2022-03-15T17:08:37-07:00 summary: bpo-46841: Don't scan backwards in bytecode (GH-31901) files: M Objects/genobject.c M Python/ceval.c diff --git a/Objects/genobject.c b/Objects/genobject.c index 4fac0ce241c09..6551b939c4590 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -359,9 +359,12 @@ _PyGen_yf(PyGenObject *gen) assert(code[0] != SEND); return NULL; } - - if (code[(frame->f_lasti-1)*sizeof(_Py_CODEUNIT)] != SEND || frame->stacktop < 0) + int opcode = code[(frame->f_lasti+1)*sizeof(_Py_CODEUNIT)]; + int oparg = code[(frame->f_lasti+1)*sizeof(_Py_CODEUNIT)+1]; + if (opcode != RESUME || oparg < 2) { + /* Not in a yield from */ return NULL; + } yf = _PyFrame_StackPeek(frame); Py_INCREF(yf); } diff --git a/Python/ceval.c b/Python/ceval.c index d0fc31ec6c5d8..81759ad770b1e 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1565,16 +1565,6 @@ trace_function_exit(PyThreadState *tstate, _PyInterpreterFrame *frame, PyObject return 0; } -static int -skip_backwards_over_extended_args(PyCodeObject *code, int offset) -{ - _Py_CODEUNIT *instrs = (_Py_CODEUNIT *)PyBytes_AS_STRING(code->co_code); - while (offset > 0 && _Py_OPCODE(instrs[offset-1]) == EXTENDED_ARG) { - offset--; - } - return offset; -} - static _PyInterpreterFrame * pop_frame(PyThreadState *tstate, _PyInterpreterFrame *frame) { @@ -5445,7 +5435,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int #endif { if (tstate->tracing == 0) { - int instr_prev = skip_backwards_over_extended_args(frame->f_code, frame->f_lasti); + int instr_prev = frame->f_lasti; frame->f_lasti = INSTR_OFFSET(); TRACING_NEXTOPARG(); if (opcode == RESUME) { @@ -6737,9 +6727,13 @@ maybe_call_line_trace(Py_tracefunc func, PyObject *obj, then call the trace function if we're tracing source lines. */ initialize_trace_info(&tstate->trace_info, frame); - _Py_CODEUNIT prev = ((_Py_CODEUNIT *)PyBytes_AS_STRING(frame->f_code->co_code))[instr_prev]; + int entry_point = 0; + _Py_CODEUNIT *code = (_Py_CODEUNIT *)PyBytes_AS_STRING(frame->f_code->co_code); + while (_Py_OPCODE(code[entry_point]) != RESUME) { + entry_point++; + } int lastline; - if (_Py_OPCODE(prev) == RESUME && _Py_OPARG(prev) == 0) { + if (instr_prev <= entry_point) { lastline = -1; } else { From webhook-mailer at python.org Tue Mar 15 20:44:26 2022 From: webhook-mailer at python.org (zooba) Date: Wed, 16 Mar 2022 00:44:26 -0000 Subject: [Python-checkins] In Windows release builds, do not attempt to copy Tcl/Tk for ARM64 when it is not being published (GH-31918) Message-ID: https://github.com/python/cpython/commit/cb495a1e9f3acfcd8cb94a6b89c79d0909e3383f commit: cb495a1e9f3acfcd8cb94a6b89c79d0909e3383f branch: main author: Steve Dower committer: zooba date: 2022-03-16T00:44:17Z summary: In Windows release builds, do not attempt to copy Tcl/Tk for ARM64 when it is not being published (GH-31918) files: M .azure-pipelines/windows-release.yml M .azure-pipelines/windows-release/msi-steps.yml M .azure-pipelines/windows-release/stage-build.yml M .azure-pipelines/windows-release/stage-layout-full.yml M .azure-pipelines/windows-release/stage-layout-msix.yml M .azure-pipelines/windows-release/stage-msi.yml diff --git a/.azure-pipelines/windows-release.yml b/.azure-pipelines/windows-release.yml index c038ccdb8675a..ae2d1b9da1321 100644 --- a/.azure-pipelines/windows-release.yml +++ b/.azure-pipelines/windows-release.yml @@ -38,6 +38,14 @@ parameters: displayName: "Publish ARM64 build" type: boolean default: true +# Because there is no ARM64 Tcl/Tk pre-3.11, we need a separate option +# to keep those builds working when the files are going to be absent. +# Eventually when we stop releasing anything that old, we can drop this +# argument (and make it implicitly always 'true') +- name: ARM64TclTk + displayName: "Use Tcl/Tk for ARM64" + type: boolean + default: true - name: DoPGO displayName: "Run PGO" type: boolean @@ -98,6 +106,8 @@ stages: displayName: Build binaries jobs: - template: windows-release/stage-build.yml + parameters: + ARM64TclTk: ${{ parameters.ARM64TclTk }} - stage: Sign displayName: Sign binaries @@ -110,6 +120,8 @@ stages: dependsOn: Sign jobs: - template: windows-release/stage-layout-full.yml + parameters: + ARM64TclTk: ${{ parameters.ARM64TclTk }} - template: windows-release/stage-layout-embed.yml - template: windows-release/stage-layout-nuget.yml @@ -130,6 +142,8 @@ stages: condition: and(succeeded(), eq(variables['DoMSIX'], 'true')) jobs: - template: windows-release/stage-layout-msix.yml + parameters: + ARM64TclTk: ${{ parameters.ARM64TclTk }} - stage: Pack_MSIX displayName: Package MSIX @@ -143,6 +157,8 @@ stages: condition: and(succeeded(), eq(variables['DoMSI'], 'true')) jobs: - template: windows-release/stage-msi.yml + parameters: + ARM64TclTk: ${{ parameters.ARM64TclTk }} - stage: Test_MSI displayName: Test MSI installer diff --git a/.azure-pipelines/windows-release/msi-steps.yml b/.azure-pipelines/windows-release/msi-steps.yml index 3c08a0660abe9..c3c2c43032c00 100644 --- a/.azure-pipelines/windows-release/msi-steps.yml +++ b/.azure-pipelines/windows-release/msi-steps.yml @@ -1,3 +1,6 @@ +parameters: + ARM64TclTk: true + steps: - template: ./checkout.yml @@ -71,12 +74,13 @@ steps: artifactName: tcltk_lib_amd64 targetPath: $(Build.BinariesDirectory)\tcltk_lib_amd64 - - task: DownloadPipelineArtifact at 1 - displayName: 'Download artifact: tcltk_lib_arm64' - condition: and(succeeded(), eq(variables['PublishARM64'], 'true')) - inputs: - artifactName: tcltk_lib_arm64 - targetPath: $(Build.BinariesDirectory)\tcltk_lib_arm64 + - ${{ if eq(parameters.ARM64TclTk, true) }}: + - task: DownloadPipelineArtifact at 1 + displayName: 'Download artifact: tcltk_lib_arm64' + condition: and(succeeded(), eq(variables['PublishARM64'], 'true')) + inputs: + artifactName: tcltk_lib_arm64 + targetPath: $(Build.BinariesDirectory)\tcltk_lib_arm64 - powershell: | copy $(Build.BinariesDirectory)\amd64\Activate.ps1 Lib\venv\scripts\common\Activate.ps1 -Force @@ -137,8 +141,9 @@ steps: PYTHON: $(Build.BinariesDirectory)\win32\python.exe PythonForBuild: $(Build.BinariesDirectory)\win32\python.exe PYTHONHOME: $(Build.SourcesDirectory) - TclTkLibraryDir: $(Build.BinariesDirectory)\tcltk_lib_arm64 BuildForRelease: true + ${{ if eq(parameters.ARM64TclTk, true) }}: + TclTkLibraryDir: $(Build.BinariesDirectory)\tcltk_lib_arm64 - task: CopyFiles at 2 displayName: 'Assemble artifact: msi (win32)' diff --git a/.azure-pipelines/windows-release/stage-build.yml b/.azure-pipelines/windows-release/stage-build.yml index e45034f650fb9..2745d79dd069c 100644 --- a/.azure-pipelines/windows-release/stage-build.yml +++ b/.azure-pipelines/windows-release/stage-build.yml @@ -1,3 +1,6 @@ +parameters: + ARM64TclTk: true + jobs: - job: Build_Docs displayName: Docs build @@ -166,12 +169,13 @@ jobs: platform: x64 msbuildArguments: /t:CopyTclTkLib /p:OutDir="$(Build.ArtifactStagingDirectory)\tcl_amd64" - - task: MSBuild at 1 - displayName: 'Copy Tcl/Tk lib for publish' - inputs: - solution: PCbuild\tcltk.props - platform: ARM64 - msbuildArguments: /t:CopyTclTkLib /p:OutDir="$(Build.ArtifactStagingDirectory)\tcl_arm64" + - ${{ if eq(parameters.ARM64TclTk, true) }}: + - task: MSBuild at 1 + displayName: 'Copy Tcl/Tk lib for publish' + inputs: + solution: PCbuild\tcltk.props + platform: ARM64 + msbuildArguments: /t:CopyTclTkLib /p:OutDir="$(Build.ArtifactStagingDirectory)\tcl_arm64" - task: PublishPipelineArtifact at 0 displayName: 'Publish artifact: tcltk_lib_win32' @@ -185,8 +189,9 @@ jobs: targetPath: '$(Build.ArtifactStagingDirectory)\tcl_amd64' artifactName: tcltk_lib_amd64 - - task: PublishPipelineArtifact at 0 - displayName: 'Publish artifact: tcltk_lib_arm64' - inputs: - targetPath: '$(Build.ArtifactStagingDirectory)\tcl_arm64' - artifactName: tcltk_lib_arm64 + - ${{ if eq(parameters.ARM64TclTk, true) }}: + - task: PublishPipelineArtifact at 0 + displayName: 'Publish artifact: tcltk_lib_arm64' + inputs: + targetPath: '$(Build.ArtifactStagingDirectory)\tcl_arm64' + artifactName: tcltk_lib_arm64 diff --git a/.azure-pipelines/windows-release/stage-layout-full.yml b/.azure-pipelines/windows-release/stage-layout-full.yml index 3546df60e4e03..343ee1f73c215 100644 --- a/.azure-pipelines/windows-release/stage-layout-full.yml +++ b/.azure-pipelines/windows-release/stage-layout-full.yml @@ -1,3 +1,6 @@ +parameters: + ARM64TclTk: true + jobs: - job: Make_Layouts displayName: Make layouts @@ -26,7 +29,8 @@ jobs: HostArch: amd64 Python: $(Build.BinariesDirectory)\bin_amd64\python.exe PYTHONHOME: $(Build.SourcesDirectory) - TclLibrary: $(Build.BinariesDirectory)\tcltk_lib\tcl8 + ${{ if eq(parameters.ARM64TclTk, true) }}: + TclLibrary: $(Build.BinariesDirectory)\tcltk_lib\tcl8 steps: - template: ./checkout.yml diff --git a/.azure-pipelines/windows-release/stage-layout-msix.yml b/.azure-pipelines/windows-release/stage-layout-msix.yml index 913bfcd919704..a44e1ede20326 100644 --- a/.azure-pipelines/windows-release/stage-layout-msix.yml +++ b/.azure-pipelines/windows-release/stage-layout-msix.yml @@ -1,3 +1,6 @@ +parameters: + ARM64TclTk: true + jobs: - job: Make_MSIX_Layout displayName: Make MSIX layout @@ -25,7 +28,8 @@ jobs: HostArch: amd64 Python: $(Build.BinariesDirectory)\bin_amd64\python.exe PYTHONHOME: $(Build.SourcesDirectory) - TclLibrary: $(Build.BinariesDirectory)\tcltk_lib\tcl8 + ${{ if eq(parameters.ARM64TclTk, true) }}: + TclLibrary: $(Build.BinariesDirectory)\tcltk_lib\tcl8 steps: - template: ./checkout.yml diff --git a/.azure-pipelines/windows-release/stage-msi.yml b/.azure-pipelines/windows-release/stage-msi.yml index f14bc9a45ae38..0566544a6eb63 100644 --- a/.azure-pipelines/windows-release/stage-msi.yml +++ b/.azure-pipelines/windows-release/stage-msi.yml @@ -1,3 +1,6 @@ +parameters: + ARM64TclTk: true + jobs: - job: Make_MSI displayName: Make MSI @@ -16,6 +19,8 @@ jobs: steps: - template: msi-steps.yml + parameters: + ARM64TclTk: ${{ parameters.ARM64TclTk }} - job: Make_Signed_MSI displayName: Make signed MSI @@ -34,3 +39,5 @@ jobs: steps: - template: msi-steps.yml + parameters: + ARM64TclTk: ${{ parameters.ARM64TclTk }} From webhook-mailer at python.org Tue Mar 15 20:46:38 2022 From: webhook-mailer at python.org (zooba) Date: Wed, 16 Mar 2022 00:46:38 -0000 Subject: [Python-checkins] bpo-46948: Fix launcher installer build failure due to first part of fix (GH-31920) Message-ID: https://github.com/python/cpython/commit/708812085355c92f32e547d1f1d1f29aefbbc27e commit: 708812085355c92f32e547d1f1d1f29aefbbc27e branch: main author: Steve Dower committer: zooba date: 2022-03-16T00:46:33Z summary: bpo-46948: Fix launcher installer build failure due to first part of fix (GH-31920) files: M Tools/msi/common.wxs diff --git a/Tools/msi/common.wxs b/Tools/msi/common.wxs index d8f3cde99ab52..4554e80014a29 100644 --- a/Tools/msi/common.wxs +++ b/Tools/msi/common.wxs @@ -61,6 +61,7 @@ + @@ -69,6 +70,7 @@ + From webhook-mailer at python.org Tue Mar 15 21:13:16 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 16 Mar 2022 01:13:16 -0000 Subject: [Python-checkins] bpo-46948: Fix launcher installer build failure due to first part of fix (GH-31920) Message-ID: https://github.com/python/cpython/commit/58d30b992d67c8471f79a7307e4c1cda64311e3b commit: 58d30b992d67c8471f79a7307e4c1cda64311e3b branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-15T18:13:03-07:00 summary: bpo-46948: Fix launcher installer build failure due to first part of fix (GH-31920) (cherry picked from commit 708812085355c92f32e547d1f1d1f29aefbbc27e) Co-authored-by: Steve Dower files: M Tools/msi/common.wxs diff --git a/Tools/msi/common.wxs b/Tools/msi/common.wxs index d8f3cde99ab52..4554e80014a29 100644 --- a/Tools/msi/common.wxs +++ b/Tools/msi/common.wxs @@ -61,6 +61,7 @@ + @@ -69,6 +70,7 @@ + From webhook-mailer at python.org Tue Mar 15 21:30:15 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 16 Mar 2022 01:30:15 -0000 Subject: [Python-checkins] bpo-46948: Fix launcher installer build failure due to first part of fix (GH-31920) Message-ID: https://github.com/python/cpython/commit/70eb9db39817a8f9abef801a2a4a7bb2c7411654 commit: 70eb9db39817a8f9abef801a2a4a7bb2c7411654 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-15T18:30:11-07:00 summary: bpo-46948: Fix launcher installer build failure due to first part of fix (GH-31920) (cherry picked from commit 708812085355c92f32e547d1f1d1f29aefbbc27e) Co-authored-by: Steve Dower files: M Tools/msi/common.wxs diff --git a/Tools/msi/common.wxs b/Tools/msi/common.wxs index d8f3cde99ab52..4554e80014a29 100644 --- a/Tools/msi/common.wxs +++ b/Tools/msi/common.wxs @@ -61,6 +61,7 @@ + @@ -69,6 +70,7 @@ + From webhook-mailer at python.org Tue Mar 15 21:36:28 2022 From: webhook-mailer at python.org (zooba) Date: Wed, 16 Mar 2022 01:36:28 -0000 Subject: [Python-checkins] bpo-47032: Ensure Windows install builds fail correctly with a non-zero exit code when part of the build fails (GH-31921) Message-ID: https://github.com/python/cpython/commit/7c776521418676c074a483266339d31c950f516e commit: 7c776521418676c074a483266339d31c950f516e branch: main author: Steve Dower committer: zooba date: 2022-03-16T01:36:20Z summary: bpo-47032: Ensure Windows install builds fail correctly with a non-zero exit code when part of the build fails (GH-31921) files: A Misc/NEWS.d/next/Build/2022-03-16-00-37-40.bpo-47032.tsS9KE.rst M Tools/msi/build.bat M Tools/msi/buildrelease.bat diff --git a/Misc/NEWS.d/next/Build/2022-03-16-00-37-40.bpo-47032.tsS9KE.rst b/Misc/NEWS.d/next/Build/2022-03-16-00-37-40.bpo-47032.tsS9KE.rst new file mode 100644 index 0000000000000..4f2f1c8d0471a --- /dev/null +++ b/Misc/NEWS.d/next/Build/2022-03-16-00-37-40.bpo-47032.tsS9KE.rst @@ -0,0 +1,2 @@ +Ensure Windows install builds fail correctly with a non-zero exit code when +part of the build fails. diff --git a/Tools/msi/build.bat b/Tools/msi/build.bat index 755c8876cf99c..ded1cfb5b2d6f 100644 --- a/Tools/msi/build.bat +++ b/Tools/msi/build.bat @@ -30,30 +30,31 @@ if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & if defined BUILDX86 ( call "%PCBUILD%build.bat" -p Win32 -d -e %REBUILD% %BUILDTEST% - if errorlevel 1 goto :eof + if errorlevel 1 exit /B %ERRORLEVEL% call "%PCBUILD%build.bat" -p Win32 -e %REBUILD% %BUILDTEST% - if errorlevel 1 goto :eof + if errorlevel 1 exit /B %ERRORLEVEL% ) if defined BUILDX64 ( call "%PCBUILD%build.bat" -p x64 -d -e %REBUILD% %BUILDTEST% - if errorlevel 1 goto :eof + if errorlevel 1 exit /B %ERRORLEVEL% call "%PCBUILD%build.bat" -p x64 -e %REBUILD% %BUILDTEST% - if errorlevel 1 goto :eof + if errorlevel 1 exit /B %ERRORLEVEL% ) if defined BUILDARM64 ( call "%PCBUILD%build.bat" -p ARM64 -d -e %REBUILD% %BUILDTEST% - if errorlevel 1 goto :eof + if errorlevel 1 exit /B %ERRORLEVEL% call "%PCBUILD%build.bat" -p ARM64 -e %REBUILD% %BUILDTEST% - if errorlevel 1 goto :eof + if errorlevel 1 exit /B %ERRORLEVEL% ) if defined BUILDDOC ( call "%PCBUILD%..\Doc\make.bat" htmlhelp - if errorlevel 1 goto :eof + if errorlevel 1 exit /B %ERRORLEVEL% ) rem Build the launcher MSI separately %MSBUILD% "%D%launcher\launcher.wixproj" /p:Platform=x86 +if errorlevel 1 exit /B %ERRORLEVEL% set BUILD_CMD="%D%bundle\snapshot.wixproj" if defined BUILDTEST ( @@ -68,15 +69,15 @@ if defined REBUILD ( if defined BUILDX86 ( %MSBUILD% /p:Platform=x86 %BUILD_CMD% - if errorlevel 1 goto :eof + if errorlevel 1 exit /B %ERRORLEVEL% ) if defined BUILDX64 ( %MSBUILD% /p:Platform=x64 %BUILD_CMD% - if errorlevel 1 goto :eof + if errorlevel 1 exit /B %ERRORLEVEL% ) if defined BUILDARM64 ( %MSBUILD% /p:Platform=ARM64 %BUILD_CMD% - if errorlevel 1 goto :eof + if errorlevel 1 exit /B %ERRORLEVEL% ) exit /B 0 diff --git a/Tools/msi/buildrelease.bat b/Tools/msi/buildrelease.bat index 722298ff6137a..d057ca675363f 100644 --- a/Tools/msi/buildrelease.bat +++ b/Tools/msi/buildrelease.bat @@ -82,26 +82,27 @@ if "%SKIPBUILD%" EQU "1" goto skipdoc if "%SKIPDOC%" EQU "1" goto skipdoc call "%D%..\..\doc\make.bat" htmlhelp -if errorlevel 1 goto :eof +if errorlevel 1 exit /B %ERRORLEVEL% :skipdoc if defined BUILDX86 ( call :build x86 - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) if defined BUILDX64 ( call :build x64 "%PGO%" - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) if defined BUILDARM64 ( call :build ARM64 - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) if defined TESTTARGETDIR ( call "%D%testrelease.bat" -t "%TESTTARGETDIR%" + if errorlevel 1 exit /B %ERRORLEVEL% ) exit /B 0 @@ -136,19 +137,19 @@ if "%1" EQU "x86" ( if exist "%BUILD%en-us" ( echo Deleting %BUILD%en-us rmdir /q/s "%BUILD%en-us" - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) if exist "%D%obj\Debug_%OBJDIR_PLAT%" ( echo Deleting "%D%obj\Debug_%OBJDIR_PLAT%" rmdir /q/s "%D%obj\Debug_%OBJDIR_PLAT%" - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) if exist "%D%obj\Release_%OBJDIR_PLAT%" ( echo Deleting "%D%obj\Release_%OBJDIR_PLAT%" rmdir /q/s "%D%obj\Release_%OBJDIR_PLAT%" - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) if not "%CERTNAME%" EQU "" ( @@ -164,29 +165,29 @@ if not "%PGO%" EQU "" ( if not "%SKIPBUILD%" EQU "1" ( @echo call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -t %TARGET% %PGOOPTS% %CERTOPTS% @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -t %TARGET% %PGOOPTS% %CERTOPTS% - @if errorlevel 1 exit /B + @if errorlevel 1 exit /B %ERRORLEVEL% @rem build.bat turns echo back on, so we disable it again @echo off @echo call "%PCBUILD%build.bat" -d -e -p %BUILD_PLAT% -t %TARGET% @call "%PCBUILD%build.bat" -d -e -p %BUILD_PLAT% -t %TARGET% - @if errorlevel 1 exit /B + @if errorlevel 1 exit /B %ERRORLEVEL% @rem build.bat turns echo back on, so we disable it again @echo off ) if "%OUTDIR_PLAT%" EQU "win32" ( %MSBUILD% "%D%launcher\launcher.wixproj" /p:Platform=x86 %CERTOPTS% /p:ReleaseUri=%RELEASE_URI% - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) else if not exist "%Py_OutDir%win32\en-us\launcher.msi" ( %MSBUILD% "%D%launcher\launcher.wixproj" /p:Platform=x86 %CERTOPTS% /p:ReleaseUri=%RELEASE_URI% - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) set BUILDOPTS=/p:Platform=%1 /p:BuildForRelease=true /p:DownloadUrl=%DOWNLOAD_URL% /p:DownloadUrlBase=%DOWNLOAD_URL_BASE% /p:ReleaseUri=%RELEASE_URI% if defined BUILDMSI ( %MSBUILD% "%D%bundle\releaselocal.wixproj" /t:Rebuild %BUILDOPTS% %CERTOPTS% /p:RebuildAll=true - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) if defined BUILDZIP ( @@ -194,7 +195,7 @@ if defined BUILDZIP ( echo Skipping embeddable ZIP generation for ARM64 platform ) else ( %MSBUILD% "%D%make_zip.proj" /t:Build %BUILDOPTS% %CERTOPTS% /p:OutputPath="%BUILD%en-us" - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) ) @@ -203,7 +204,7 @@ if defined BUILDNUGET ( echo Skipping Nuget package generation for ARM64 platform ) else ( %MSBUILD% "%D%..\nuget\make_pkg.proj" /t:Build /p:Configuration=Release /p:Platform=%1 /p:OutputPath="%BUILD%en-us" - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) ) From webhook-mailer at python.org Tue Mar 15 22:00:39 2022 From: webhook-mailer at python.org (ned-deily) Date: Wed, 16 Mar 2022 02:00:39 -0000 Subject: [Python-checkins] bpo-46948: Fix launcher installer build failure due to first part of fix (GH-31920) (GH-31925) Message-ID: https://github.com/python/cpython/commit/4a1d65fe8528c3a6e0cf2f4f9d4b58249164589d commit: 4a1d65fe8528c3a6e0cf2f4f9d4b58249164589d branch: 3.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ned-deily date: 2022-03-15T22:00:23-04:00 summary: bpo-46948: Fix launcher installer build failure due to first part of fix (GH-31920) (GH-31925) (cherry picked from commit 708812085355c92f32e547d1f1d1f29aefbbc27e) Co-authored-by: Steve Dower files: M Tools/msi/common.wxs diff --git a/Tools/msi/common.wxs b/Tools/msi/common.wxs index d8f3cde99ab52..4554e80014a29 100644 --- a/Tools/msi/common.wxs +++ b/Tools/msi/common.wxs @@ -61,6 +61,7 @@ + @@ -69,6 +70,7 @@ + From webhook-mailer at python.org Tue Mar 15 22:07:54 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 16 Mar 2022 02:07:54 -0000 Subject: [Python-checkins] [3.10] bpo-47032: Ensure Windows install builds fail correctly with a non-zero exit code when part of the build fails (GH-31921) (GH-31926) Message-ID: https://github.com/python/cpython/commit/04fdbb4f7003a7399f7ba626cf548e2b9dac1045 commit: 04fdbb4f7003a7399f7ba626cf548e2b9dac1045 branch: 3.10 author: Steve Dower committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-15T19:07:42-07:00 summary: [3.10] bpo-47032: Ensure Windows install builds fail correctly with a non-zero exit code when part of the build fails (GH-31921) (GH-31926) Automerge-Triggered-By: GH:zooba files: A Misc/NEWS.d/next/Build/2022-03-16-00-37-40.bpo-47032.tsS9KE.rst M Tools/msi/build.bat M Tools/msi/buildrelease.bat diff --git a/Misc/NEWS.d/next/Build/2022-03-16-00-37-40.bpo-47032.tsS9KE.rst b/Misc/NEWS.d/next/Build/2022-03-16-00-37-40.bpo-47032.tsS9KE.rst new file mode 100644 index 0000000000000..4f2f1c8d0471a --- /dev/null +++ b/Misc/NEWS.d/next/Build/2022-03-16-00-37-40.bpo-47032.tsS9KE.rst @@ -0,0 +1,2 @@ +Ensure Windows install builds fail correctly with a non-zero exit code when +part of the build fails. diff --git a/Tools/msi/build.bat b/Tools/msi/build.bat index 532cebc5b5118..2bdaca23f95b8 100644 --- a/Tools/msi/build.bat +++ b/Tools/msi/build.bat @@ -27,25 +27,26 @@ call "%PCBUILD%find_msbuild.bat" %MSBUILD% if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) if defined BUILDX86 ( - call "%PCBUILD%build.bat" -d -e %REBUILD% %BUILDTEST% - if errorlevel 1 goto :eof - call "%PCBUILD%build.bat" -e %REBUILD% %BUILDTEST% - if errorlevel 1 goto :eof + call "%PCBUILD%build.bat" -p Win32 -d -e %REBUILD% %BUILDTEST% + if errorlevel 1 exit /B %ERRORLEVEL% + call "%PCBUILD%build.bat" -p Win32 -e %REBUILD% %BUILDTEST% + if errorlevel 1 exit /B %ERRORLEVEL% ) if defined BUILDX64 ( call "%PCBUILD%build.bat" -p x64 -d -e %REBUILD% %BUILDTEST% - if errorlevel 1 goto :eof + if errorlevel 1 exit /B %ERRORLEVEL% call "%PCBUILD%build.bat" -p x64 -e %REBUILD% %BUILDTEST% - if errorlevel 1 goto :eof + if errorlevel 1 exit /B %ERRORLEVEL% ) if defined BUILDDOC ( call "%PCBUILD%..\Doc\make.bat" htmlhelp - if errorlevel 1 goto :eof + if errorlevel 1 exit /B %ERRORLEVEL% ) rem Build the launcher MSI separately %MSBUILD% "%D%launcher\launcher.wixproj" /p:Platform=x86 +if errorlevel 1 exit /B %ERRORLEVEL% set BUILD_CMD="%D%bundle\snapshot.wixproj" if defined BUILDTEST ( @@ -59,12 +60,12 @@ if defined REBUILD ( ) if defined BUILDX86 ( - %MSBUILD% %BUILD_CMD% - if errorlevel 1 goto :eof + %MSBUILD% /p:Platform=x86 %BUILD_CMD% + if errorlevel 1 exit /B %ERRORLEVEL% ) if defined BUILDX64 ( %MSBUILD% /p:Platform=x64 %BUILD_CMD% - if errorlevel 1 goto :eof + if errorlevel 1 exit /B %ERRORLEVEL% ) exit /B 0 diff --git a/Tools/msi/buildrelease.bat b/Tools/msi/buildrelease.bat index 4fbaf2c99ba9b..69dd145aaf261 100644 --- a/Tools/msi/buildrelease.bat +++ b/Tools/msi/buildrelease.bat @@ -80,7 +80,7 @@ if "%SKIPBUILD%" EQU "1" goto skipdoc if "%SKIPDOC%" EQU "1" goto skipdoc call "%D%..\..\doc\make.bat" htmlhelp -if errorlevel 1 goto :eof +if errorlevel 1 exit /B %ERRORLEVEL% :skipdoc where dlltool /q && goto skipdlltoolsearch @@ -93,16 +93,17 @@ set _DLLTOOL_PATH= if defined BUILDX86 ( call :build x86 - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) if defined BUILDX64 ( call :build x64 "%PGO%" - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) if defined TESTTARGETDIR ( call "%D%testrelease.bat" -t "%TESTTARGETDIR%" + if errorlevel 1 exit /B %ERRORLEVEL% ) exit /B 0 @@ -128,19 +129,19 @@ if "%1" EQU "x86" ( if exist "%BUILD%en-us" ( echo Deleting %BUILD%en-us rmdir /q/s "%BUILD%en-us" - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) if exist "%D%obj\Debug_%OBJDIR_PLAT%" ( echo Deleting "%D%obj\Debug_%OBJDIR_PLAT%" rmdir /q/s "%D%obj\Debug_%OBJDIR_PLAT%" - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) if exist "%D%obj\Release_%OBJDIR_PLAT%" ( echo Deleting "%D%obj\Release_%OBJDIR_PLAT%" rmdir /q/s "%D%obj\Release_%OBJDIR_PLAT%" - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) if not "%CERTNAME%" EQU "" ( @@ -156,41 +157,41 @@ if not "%PGO%" EQU "" ( if not "%SKIPBUILD%" EQU "1" ( @echo call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -t %TARGET% %PGOOPTS% %CERTOPTS% @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -t %TARGET% %PGOOPTS% %CERTOPTS% - @if errorlevel 1 exit /B + @if errorlevel 1 exit /B %ERRORLEVEL% @rem build.bat turns echo back on, so we disable it again @echo off @echo call "%PCBUILD%build.bat" -d -e -p %BUILD_PLAT% -t %TARGET% @call "%PCBUILD%build.bat" -d -e -p %BUILD_PLAT% -t %TARGET% - @if errorlevel 1 exit /B + @if errorlevel 1 exit /B %ERRORLEVEL% @rem build.bat turns echo back on, so we disable it again @echo off ) if "%OUTDIR_PLAT%" EQU "win32" ( %MSBUILD% "%D%launcher\launcher.wixproj" /p:Platform=x86 %CERTOPTS% /p:ReleaseUri=%RELEASE_URI% - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) else if not exist "%Py_OutDir%win32\en-us\launcher.msi" ( %MSBUILD% "%D%launcher\launcher.wixproj" /p:Platform=x86 %CERTOPTS% /p:ReleaseUri=%RELEASE_URI% - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) set BUILDOPTS=/p:Platform=%1 /p:BuildForRelease=true /p:DownloadUrl=%DOWNLOAD_URL% /p:DownloadUrlBase=%DOWNLOAD_URL_BASE% /p:ReleaseUri=%RELEASE_URI% if defined BUILDMSI ( %MSBUILD% "%D%bundle\releaselocal.wixproj" /t:Rebuild %BUILDOPTS% %CERTOPTS% /p:RebuildAll=true - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% %MSBUILD% "%D%bundle\releaseweb.wixproj" /t:Rebuild %BUILDOPTS% %CERTOPTS% /p:RebuildAll=false - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) if defined BUILDZIP ( %MSBUILD% "%D%make_zip.proj" /t:Build %BUILDOPTS% %CERTOPTS% /p:OutputPath="%BUILD%en-us" - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) if defined BUILDNUGET ( %MSBUILD% "%D%..\nuget\make_pkg.proj" /t:Build /p:Configuration=Release /p:Platform=%1 /p:OutputPath="%BUILD%en-us" - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) if not "%OUTDIR%" EQU "" ( From webhook-mailer at python.org Tue Mar 15 22:12:10 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 16 Mar 2022 02:12:10 -0000 Subject: [Python-checkins] [3.9] bpo-47032: Ensure Windows install builds fail correctly with a non-zero exit code when part of the build fails (GH-31921) (GH-31927) Message-ID: https://github.com/python/cpython/commit/ad6ddd89006b9fa4836a944c99f8076f26faf299 commit: ad6ddd89006b9fa4836a944c99f8076f26faf299 branch: 3.9 author: Steve Dower committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-15T19:11:59-07:00 summary: [3.9] bpo-47032: Ensure Windows install builds fail correctly with a non-zero exit code when part of the build fails (GH-31921) (GH-31927) Automerge-Triggered-By: GH:zooba files: A Misc/NEWS.d/next/Build/2022-03-16-00-37-40.bpo-47032.tsS9KE.rst M Tools/msi/build.bat M Tools/msi/buildrelease.bat diff --git a/Misc/NEWS.d/next/Build/2022-03-16-00-37-40.bpo-47032.tsS9KE.rst b/Misc/NEWS.d/next/Build/2022-03-16-00-37-40.bpo-47032.tsS9KE.rst new file mode 100644 index 0000000000000..4f2f1c8d0471a --- /dev/null +++ b/Misc/NEWS.d/next/Build/2022-03-16-00-37-40.bpo-47032.tsS9KE.rst @@ -0,0 +1,2 @@ +Ensure Windows install builds fail correctly with a non-zero exit code when +part of the build fails. diff --git a/Tools/msi/build.bat b/Tools/msi/build.bat index 532cebc5b5118..2bdaca23f95b8 100644 --- a/Tools/msi/build.bat +++ b/Tools/msi/build.bat @@ -27,25 +27,26 @@ call "%PCBUILD%find_msbuild.bat" %MSBUILD% if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) if defined BUILDX86 ( - call "%PCBUILD%build.bat" -d -e %REBUILD% %BUILDTEST% - if errorlevel 1 goto :eof - call "%PCBUILD%build.bat" -e %REBUILD% %BUILDTEST% - if errorlevel 1 goto :eof + call "%PCBUILD%build.bat" -p Win32 -d -e %REBUILD% %BUILDTEST% + if errorlevel 1 exit /B %ERRORLEVEL% + call "%PCBUILD%build.bat" -p Win32 -e %REBUILD% %BUILDTEST% + if errorlevel 1 exit /B %ERRORLEVEL% ) if defined BUILDX64 ( call "%PCBUILD%build.bat" -p x64 -d -e %REBUILD% %BUILDTEST% - if errorlevel 1 goto :eof + if errorlevel 1 exit /B %ERRORLEVEL% call "%PCBUILD%build.bat" -p x64 -e %REBUILD% %BUILDTEST% - if errorlevel 1 goto :eof + if errorlevel 1 exit /B %ERRORLEVEL% ) if defined BUILDDOC ( call "%PCBUILD%..\Doc\make.bat" htmlhelp - if errorlevel 1 goto :eof + if errorlevel 1 exit /B %ERRORLEVEL% ) rem Build the launcher MSI separately %MSBUILD% "%D%launcher\launcher.wixproj" /p:Platform=x86 +if errorlevel 1 exit /B %ERRORLEVEL% set BUILD_CMD="%D%bundle\snapshot.wixproj" if defined BUILDTEST ( @@ -59,12 +60,12 @@ if defined REBUILD ( ) if defined BUILDX86 ( - %MSBUILD% %BUILD_CMD% - if errorlevel 1 goto :eof + %MSBUILD% /p:Platform=x86 %BUILD_CMD% + if errorlevel 1 exit /B %ERRORLEVEL% ) if defined BUILDX64 ( %MSBUILD% /p:Platform=x64 %BUILD_CMD% - if errorlevel 1 goto :eof + if errorlevel 1 exit /B %ERRORLEVEL% ) exit /B 0 diff --git a/Tools/msi/buildrelease.bat b/Tools/msi/buildrelease.bat index 4fbaf2c99ba9b..69dd145aaf261 100644 --- a/Tools/msi/buildrelease.bat +++ b/Tools/msi/buildrelease.bat @@ -80,7 +80,7 @@ if "%SKIPBUILD%" EQU "1" goto skipdoc if "%SKIPDOC%" EQU "1" goto skipdoc call "%D%..\..\doc\make.bat" htmlhelp -if errorlevel 1 goto :eof +if errorlevel 1 exit /B %ERRORLEVEL% :skipdoc where dlltool /q && goto skipdlltoolsearch @@ -93,16 +93,17 @@ set _DLLTOOL_PATH= if defined BUILDX86 ( call :build x86 - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) if defined BUILDX64 ( call :build x64 "%PGO%" - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) if defined TESTTARGETDIR ( call "%D%testrelease.bat" -t "%TESTTARGETDIR%" + if errorlevel 1 exit /B %ERRORLEVEL% ) exit /B 0 @@ -128,19 +129,19 @@ if "%1" EQU "x86" ( if exist "%BUILD%en-us" ( echo Deleting %BUILD%en-us rmdir /q/s "%BUILD%en-us" - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) if exist "%D%obj\Debug_%OBJDIR_PLAT%" ( echo Deleting "%D%obj\Debug_%OBJDIR_PLAT%" rmdir /q/s "%D%obj\Debug_%OBJDIR_PLAT%" - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) if exist "%D%obj\Release_%OBJDIR_PLAT%" ( echo Deleting "%D%obj\Release_%OBJDIR_PLAT%" rmdir /q/s "%D%obj\Release_%OBJDIR_PLAT%" - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) if not "%CERTNAME%" EQU "" ( @@ -156,41 +157,41 @@ if not "%PGO%" EQU "" ( if not "%SKIPBUILD%" EQU "1" ( @echo call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -t %TARGET% %PGOOPTS% %CERTOPTS% @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -t %TARGET% %PGOOPTS% %CERTOPTS% - @if errorlevel 1 exit /B + @if errorlevel 1 exit /B %ERRORLEVEL% @rem build.bat turns echo back on, so we disable it again @echo off @echo call "%PCBUILD%build.bat" -d -e -p %BUILD_PLAT% -t %TARGET% @call "%PCBUILD%build.bat" -d -e -p %BUILD_PLAT% -t %TARGET% - @if errorlevel 1 exit /B + @if errorlevel 1 exit /B %ERRORLEVEL% @rem build.bat turns echo back on, so we disable it again @echo off ) if "%OUTDIR_PLAT%" EQU "win32" ( %MSBUILD% "%D%launcher\launcher.wixproj" /p:Platform=x86 %CERTOPTS% /p:ReleaseUri=%RELEASE_URI% - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) else if not exist "%Py_OutDir%win32\en-us\launcher.msi" ( %MSBUILD% "%D%launcher\launcher.wixproj" /p:Platform=x86 %CERTOPTS% /p:ReleaseUri=%RELEASE_URI% - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) set BUILDOPTS=/p:Platform=%1 /p:BuildForRelease=true /p:DownloadUrl=%DOWNLOAD_URL% /p:DownloadUrlBase=%DOWNLOAD_URL_BASE% /p:ReleaseUri=%RELEASE_URI% if defined BUILDMSI ( %MSBUILD% "%D%bundle\releaselocal.wixproj" /t:Rebuild %BUILDOPTS% %CERTOPTS% /p:RebuildAll=true - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% %MSBUILD% "%D%bundle\releaseweb.wixproj" /t:Rebuild %BUILDOPTS% %CERTOPTS% /p:RebuildAll=false - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) if defined BUILDZIP ( %MSBUILD% "%D%make_zip.proj" /t:Build %BUILDOPTS% %CERTOPTS% /p:OutputPath="%BUILD%en-us" - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) if defined BUILDNUGET ( %MSBUILD% "%D%..\nuget\make_pkg.proj" /t:Build /p:Configuration=Release /p:Platform=%1 /p:OutputPath="%BUILD%en-us" - if errorlevel 1 exit /B + if errorlevel 1 exit /B %ERRORLEVEL% ) if not "%OUTDIR%" EQU "" ( From webhook-mailer at python.org Wed Mar 16 06:12:16 2022 From: webhook-mailer at python.org (ambv) Date: Wed, 16 Mar 2022 10:12:16 -0000 Subject: [Python-checkins] bpo-46948: Fix launcher installer build failure due to first part of fix (GH-31920) (GH-31924) Message-ID: https://github.com/python/cpython/commit/2b97cfdce8df9d0d455f65a22b1e0d34a29dc200 commit: 2b97cfdce8df9d0d455f65a22b1e0d34a29dc200 branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv date: 2022-03-16T11:11:36+01:00 summary: bpo-46948: Fix launcher installer build failure due to first part of fix (GH-31920) (GH-31924) (cherry picked from commit 708812085355c92f32e547d1f1d1f29aefbbc27e) Co-authored-by: Steve Dower files: M Tools/msi/common.wxs diff --git a/Tools/msi/common.wxs b/Tools/msi/common.wxs index d8f3cde99ab52..4554e80014a29 100644 --- a/Tools/msi/common.wxs +++ b/Tools/msi/common.wxs @@ -61,6 +61,7 @@ + @@ -69,6 +70,7 @@ + From webhook-mailer at python.org Wed Mar 16 06:13:00 2022 From: webhook-mailer at python.org (ambv) Date: Wed, 16 Mar 2022 10:13:00 -0000 Subject: [Python-checkins] bpo-31327: Update time documentation to reflect possible errors (GH-31460) (GH-31827) Message-ID: https://github.com/python/cpython/commit/4d8e08b21ce5d2cc08da82cf9f3ca50d9617cbdc commit: 4d8e08b21ce5d2cc08da82cf9f3ca50d9617cbdc branch: 3.8 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv date: 2022-03-16T11:12:50+01:00 summary: bpo-31327: Update time documentation to reflect possible errors (GH-31460) (GH-31827) As per the comments, this mirrors the [datetime documentation](https://docs.python.org/3/library/datetime.htmlGH-datetime.datetime.fromtimestamp). ``` >>> import time >>> time.localtime(999999999999999999999) Traceback (most recent call last): File "", line 1, in OverflowError: timestamp out of range for platform time_t >>> time.localtime(-3600) Traceback (most recent call last): File "", line 1, in OSError: [Errno 22] Invalid argument ``` (cherry picked from commit c83fc9c02c9846ec3a2d0123999c98e02f00b3f5) Co-authored-by: slateny <46876382+slateny at users.noreply.github.com> files: M Doc/library/time.rst diff --git a/Doc/library/time.rst b/Doc/library/time.rst index e8bb9ccb8e77c..9cdef1adec975 100644 --- a/Doc/library/time.rst +++ b/Doc/library/time.rst @@ -253,6 +253,12 @@ Functions :const:`None`, the current time as returned by :func:`.time` is used. The dst flag is set to ``1`` when DST applies to the given time. + :func:`localtime` may raise :exc:`OverflowError`, if the timestamp is + outside the range of values supported by the platform C :c:func:`localtime` + or :c:func:`gmtime` functions, and :exc:`OSError` on :c:func:`localtime` or + :c:func:`gmtime` failure. It's common for this to be restricted to years + between 1970 and 2038. + .. function:: mktime(t) From webhook-mailer at python.org Wed Mar 16 06:14:00 2022 From: webhook-mailer at python.org (ambv) Date: Wed, 16 Mar 2022 10:14:00 -0000 Subject: [Python-checkins] [3.10] bpo-45382: test.pythoninfo logs more Windows versions (GH-30891) (GH-30894) Message-ID: https://github.com/python/cpython/commit/0b0609d0d1a2f231c94bab2177095dd9a46fc137 commit: 0b0609d0d1a2f231c94bab2177095dd9a46fc137 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ambv date: 2022-03-16T11:13:55+01:00 summary: [3.10] bpo-45382: test.pythoninfo logs more Windows versions (GH-30891) (GH-30894) Add the following info to test.pythoninfo: * windows.ver: output of the shell "ver" command * windows.version and windows.version_caption: output of the "wmic os get Caption,Version /value" command. (cherry picked from commit b0898f4aa90d9397e23aef98a2d6b82445ee7455) * bpo-45382: test.pythoninfo: set wmic.exe encoding to OEM (GH-30890) (cherry picked from commit cef0a5458f254c2f8536b928dee25862ca90ffa6) (cherry picked from commit 4a57fa296b92125e41220ecd201eb2e432b79fb0) Co-authored-by: Victor Stinner files: M Lib/test/pythoninfo.py diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index cc228fb3b54c9..fd1b49ecc8af4 100644 --- a/Lib/test/pythoninfo.py +++ b/Lib/test/pythoninfo.py @@ -719,6 +719,48 @@ def collect_windows(info_add): except (ImportError, AttributeError): pass + import subprocess + try: + # When wmic.exe output is redirected to a pipe, + # it uses the OEM code page + proc = subprocess.Popen(["wmic", "os", "get", "Caption,Version", "/value"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + encoding="oem", + text=True) + output, stderr = proc.communicate() + if proc.returncode: + output = "" + except OSError: + pass + else: + for line in output.splitlines(): + line = line.strip() + if line.startswith('Caption='): + line = line.removeprefix('Caption=').strip() + if line: + info_add('windows.version_caption', line) + elif line.startswith('Version='): + line = line.removeprefix('Version=').strip() + if line: + info_add('windows.version', line) + + try: + proc = subprocess.Popen(["ver"], shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True) + output = proc.communicate()[0] + if proc.returncode: + output = "" + except OSError: + return + else: + output = output.strip() + line = output.splitlines()[0] + if line: + info_add('windows.ver', line) + def collect_fips(info_add): try: From webhook-mailer at python.org Wed Mar 16 09:29:28 2022 From: webhook-mailer at python.org (ambv) Date: Wed, 16 Mar 2022 13:29:28 -0000 Subject: [Python-checkins] Python 3.8.13, take two Message-ID: https://github.com/python/cpython/commit/ea673213dd30afd8cacb53927e7d86f6125e86c8 commit: ea673213dd30afd8cacb53927e7d86f6125e86c8 branch: 3.8 author: ?ukasz Langa committer: ambv date: 2022-03-16T13:22:54+01:00 summary: Python 3.8.13, take two This reverts commit e5f711f5eeb6db4290db1b747f42f5d723d12ed3. files: M Include/patchlevel.h diff --git a/Include/patchlevel.h b/Include/patchlevel.h index e4499050416f6..020cb189807c3 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -23,7 +23,7 @@ #define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "3.8.13+" +#define PY_VERSION "3.8.13" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. From webhook-mailer at python.org Wed Mar 16 10:32:16 2022 From: webhook-mailer at python.org (pablogsal) Date: Wed, 16 Mar 2022 14:32:16 -0000 Subject: [Python-checkins] Python 3.10.3 Message-ID: https://github.com/python/cpython/commit/a342a49189c16f01e7b95e0bf22ea2bd539222cd commit: a342a49189c16f01e7b95e0bf22ea2bd539222cd branch: 3.10 author: Pablo Galindo committer: pablogsal date: 2022-03-16T11:27:11Z summary: Python 3.10.3 files: A Misc/NEWS.d/3.10.3.rst D Misc/NEWS.d/next/Build/2022-01-08-12-43-31.bpo-45925.38F3NO.rst D Misc/NEWS.d/next/Build/2022-01-25-12-32-37.bpo-46513.mPm9B4.rst D Misc/NEWS.d/next/Build/2022-01-26-22-59-12.bpo-38472.RxfLho.rst D Misc/NEWS.d/next/Build/2022-03-15-09-28-55.bpo-47024.t7-dcu.rst D Misc/NEWS.d/next/Build/2022-03-16-00-37-40.bpo-47032.tsS9KE.rst D Misc/NEWS.d/next/C API/2020-09-11-02-50-41.bpo-14916.QN1Y03.rst D Misc/NEWS.d/next/C API/2022-01-19-16-51-54.bpo-46433.Er9ApS.rst D Misc/NEWS.d/next/Core and Builtins/2021-12-16-00-24-00.bpo-46091.rJ_e_e.rst D Misc/NEWS.d/next/Core and Builtins/2022-01-03-23-31-25.bpo-46240.8lGjeK.rst D Misc/NEWS.d/next/Core and Builtins/2022-01-11-11-50-19.bpo-46339.OVumDZ.rst D Misc/NEWS.d/next/Core and Builtins/2022-01-13-17-58-56.bpo-46070.q8IGth.rst D Misc/NEWS.d/next/Core and Builtins/2022-01-14-20-55-34.bpo-46383.v8MTl4.rst D Misc/NEWS.d/next/Core and Builtins/2022-01-22-14-39-23.bpo-46417.3U5SfN.rst D Misc/NEWS.d/next/Core and Builtins/2022-01-24-21-24-41.bpo-46503.4UrPsE.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-01-14-30-56.bpo-45773.Up77LD.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-04-04-33-18.bpo-46615.puArY9.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-06-23-08-30.bpo-40479.zED3Zu.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-10-03-13-18.bpo-46707.xeSEh0.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-12-11-16-40.bpo-46732.3Z_qxd.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-14-14-44-06.bpo-46724.jym_K6.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-15-20-26-46.bpo-46762.1H7vab.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-21-21-55-23.bpo-46820.4RfUZh.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-22-12-07-53.bpo-46794.6WvJ9o.rst D Misc/NEWS.d/next/Core and Builtins/2022-02-25-02-01-42.bpo-46852._3zg8D.rst D Misc/NEWS.d/next/Core and Builtins/2022-03-06-20-16-13.bpo-46940._X47Hx.rst D Misc/NEWS.d/next/Documentation/2022-01-21-21-33-48.bpo-46463.fBbdTG.rst D Misc/NEWS.d/next/IDLE/2021-10-14-16-55-03.bpo-45447.FhiH5P.rst D Misc/NEWS.d/next/IDLE/2022-01-26-19-33-55.bpo-45296.LzZKdU.rst D Misc/NEWS.d/next/IDLE/2022-02-03-15-47-53.bpo-46630.tREOjo.rst D Misc/NEWS.d/next/Library/2019-05-07-14-25-45.bpo-14156.0FaHXE.rst D Misc/NEWS.d/next/Library/2021-07-31-23-18-50.bpo-44791.4jFdpO.rst D Misc/NEWS.d/next/Library/2021-09-06-15-46-53.bpo-24959.UVFgiO.rst D Misc/NEWS.d/next/Library/2021-11-03-13-41-49.bpo-45703.35AagL.rst D Misc/NEWS.d/next/Library/2021-11-08-20-27-41.bpo-44439.I_8qro.rst D Misc/NEWS.d/next/Library/2021-12-15-06-29-00.bpo-46080.AuQpLt.rst D Misc/NEWS.d/next/Library/2021-12-22-12-02-27.bpo-20392.CLAFIp.rst D Misc/NEWS.d/next/Library/2021-12-28-11-55-10.bpo-21987.avBK-p.rst D Misc/NEWS.d/next/Library/2021-12-29-13-42-55.bpo-26552.1BqeAn.rst D Misc/NEWS.d/next/Library/2021-12-29-14-42-09.bpo-43118.BoVi_5.rst D Misc/NEWS.d/next/Library/2022-01-03-09-46-44.bpo-46232.s0KlyI.rst D Misc/NEWS.d/next/Library/2022-01-05-12-48-18.bpo-46266.ACQCgX.rst D Misc/NEWS.d/next/Library/2022-01-07-13-27-53.bpo-46246.CTLx32.rst D Misc/NEWS.d/next/Library/2022-01-11-15-54-15.bpo-46333.B1faiF.rst D Misc/NEWS.d/next/Library/2022-01-20-10-35-10.bpo-46434.geS-aP.rst D Misc/NEWS.d/next/Library/2022-01-22-05-05-08.bpo-46469.plUab5.rst D Misc/NEWS.d/next/Library/2022-01-22-14-49-10.bpo-46474.eKQhvx.rst D Misc/NEWS.d/next/Library/2022-01-23-18-04-45.bpo-41403.SgoHqV.rst D Misc/NEWS.d/next/Library/2022-01-23-19-37-00.bpo-46436.Biz1p9.rst D Misc/NEWS.d/next/Library/2022-01-24-23-55-30.bpo-46491.jmIKHo.rst D Misc/NEWS.d/next/Library/2022-01-26-20-36-30.bpo-46539.23iW1d.rst D Misc/NEWS.d/next/Library/2022-01-27-11-16-59.bpo-45173.wreRF2.rst D Misc/NEWS.d/next/Library/2022-01-27-12-24-38.bpo-46487.UDkN2z.rst D Misc/NEWS.d/next/Library/2022-01-30-15-16-12.bpo-46400.vweUiO.rst D Misc/NEWS.d/next/Library/2022-01-31-15-40-38.bpo-46591.prBD1M.rst D Misc/NEWS.d/next/Library/2022-02-01-11-32-47.bpo-46581.t7Zw65.rst D Misc/NEWS.d/next/Library/2022-02-01-19-34-28.bpo-46521.IMUIrs.rst D Misc/NEWS.d/next/Library/2022-02-05-18-22-05.bpo-45948.w4mCnE.rst D Misc/NEWS.d/next/Library/2022-02-06-08-54-03.bpo-46655.DiLzYv.rst D Misc/NEWS.d/next/Library/2022-02-07-13-15-16.bpo-46672.4swIjx.rst D Misc/NEWS.d/next/Library/2022-02-07-19-20-42.bpo-46676.3Aws1o.rst D Misc/NEWS.d/next/Library/2022-02-09-00-53-23.bpo-45863.zqQXVv.rst D Misc/NEWS.d/next/Library/2022-02-09-22-40-11.bpo-46643.aBlIx1.rst D Misc/NEWS.d/next/Library/2022-02-15-11-57-53.bpo-46756.AigSPi.rst D Misc/NEWS.d/next/Library/2022-02-17-13-10-50.bpo-39327.ytIT7Z.rst D Misc/NEWS.d/next/Library/2022-02-18-22-10-30.bpo-46784.SVOQJx.rst D Misc/NEWS.d/next/Library/2022-02-20-12-59-46.bpo-46252.KG1SqA.rst D Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst D Misc/NEWS.d/next/Library/2022-02-22-15-08-30.bpo-46827.hvj38S.rst D Misc/NEWS.d/next/Library/2022-02-23-00-55-59.bpo-44886.I40Mbr.rst D Misc/NEWS.d/next/Library/2022-03-05-09-43-53.bpo-25707.gTlclP.rst D Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst D Misc/NEWS.d/next/Library/2022-03-08-11-34-06.bpo-23325.3VQnfo.rst D Misc/NEWS.d/next/Library/2022-03-08-22-41-59.bpo-46955.IOoonN.rst D Misc/NEWS.d/next/Library/2022-03-10-14-51-11.bpo-46968.ym2QxL.rst D Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst D Misc/NEWS.d/next/Library/2022-03-13-15-04-05.bpo-47004.SyYpxd.rst D Misc/NEWS.d/next/Library/2022-03-15-07-53-45.bpo-43253.rjdLFj.rst D Misc/NEWS.d/next/Tests/2022-01-17-13-10-04.bpo-13886.5mZH4b.rst D Misc/NEWS.d/next/Tests/2022-01-28-01-17-10.bpo-46542.xRLTdj.rst D Misc/NEWS.d/next/Tests/2022-01-29-12-37-53.bpo-46576.-prRaV.rst D Misc/NEWS.d/next/Tests/2022-01-31-17-34-13.bpo-46542.RTMm1T.rst D Misc/NEWS.d/next/Tests/2022-02-02-02-24-04.bpo-44359.kPPSmN.rst D Misc/NEWS.d/next/Tests/2022-02-02-18-14-38.bpo-46616.URvBtE.rst D Misc/NEWS.d/next/Tests/2022-02-07-12-40-45.bpo-46678.zfOrgL.rst D Misc/NEWS.d/next/Tests/2022-02-10-14-33-47.bpo-46708.avLfCb.rst D Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst D Misc/NEWS.d/next/Windows/2022-02-04-18-02-33.bpo-46638.mSJOSX.rst D Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst D Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst D Misc/NEWS.d/next/macOS/2022-01-26-12-04-09.bpo-45925.yBSiYO.rst M Include/patchlevel.h M Lib/pydoc_data/topics.py M README.rst diff --git a/Include/patchlevel.h b/Include/patchlevel.h index ee537c7f34f9a..5bb246e9419d1 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -18,12 +18,12 @@ /*--start constants--*/ #define PY_MAJOR_VERSION 3 #define PY_MINOR_VERSION 10 -#define PY_MICRO_VERSION 2 +#define PY_MICRO_VERSION 3 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL #define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "3.10.2+" +#define PY_VERSION "3.10.3" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index 1b5cfe24001c5..ac7d16c346fe3 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Thu Jan 13 18:49:56 2022 +# Autogenerated by Sphinx on Wed Mar 16 11:26:55 2022 topics = {'assert': 'The "assert" statement\n' '**********************\n' '\n' @@ -6233,19 +6233,19 @@ '"\'0\'" no\n' 'longer affects the default alignment for strings.\n' '\n' - 'The *precision* is a decimal number indicating how many ' + 'The *precision* is a decimal integer indicating how many ' 'digits should\n' - 'be displayed after the decimal point for a floating point ' - 'value\n' - 'formatted with "\'f\'" and "\'F\'", or before and after the ' - 'decimal point\n' - 'for a floating point value formatted with "\'g\'" or ' - '"\'G\'". For non-\n' - 'number types the field indicates the maximum field size - ' - 'in other\n' - 'words, how many characters will be used from the field ' - 'content. The\n' - '*precision* is not allowed for integer values.\n' + 'be displayed after the decimal point for presentation types ' + '"\'f\'" and\n' + '"\'F\'", or before and after the decimal point for ' + 'presentation types\n' + '"\'g\'" or "\'G\'". For string presentation types the ' + 'field indicates the\n' + 'maximum field size - in other words, how many characters ' + 'will be used\n' + 'from the field content. The *precision* is not allowed for ' + 'integer\n' + 'presentation types.\n' '\n' 'Finally, the *type* determines how the data should be ' 'presented.\n' @@ -8384,12 +8384,12 @@ '\n' ' raise_stmt ::= "raise" [expression ["from" expression]]\n' '\n' - 'If no expressions are present, "raise" re-raises the last ' - 'exception\n' - 'that was active in the current scope. If no exception is active ' - 'in\n' - 'the current scope, a "RuntimeError" exception is raised indicating\n' - 'that this is an error.\n' + 'If no expressions are present, "raise" re-raises the exception that ' + 'is\n' + 'currently being handled, which is also known as the *active\n' + 'exception*. If there isn?t currently an active exception, a\n' + '"RuntimeError" exception is raised indicating that this is an ' + 'error.\n' '\n' 'Otherwise, "raise" evaluates the first expression as the exception\n' 'object. It must be either a subclass or an instance of\n' @@ -8444,11 +8444,14 @@ ' File "", line 4, in \n' ' RuntimeError: Something bad happened\n' '\n' - 'A similar mechanism works implicitly if an exception is raised ' - 'inside\n' - 'an exception handler or a "finally" clause: the previous exception ' - 'is\n' - 'then attached as the new exception?s "__context__" attribute:\n' + 'A similar mechanism works implicitly if a new exception is raised ' + 'when\n' + 'an exception is already being handled. An exception may be ' + 'handled\n' + 'when an "except" or "finally" clause, or a "with" statement, is ' + 'used.\n' + 'The previous exception is then attached as the new exception?s\n' + '"__context__" attribute:\n' '\n' ' >>> try:\n' ' ... print(1 / 0)\n' @@ -9916,14 +9919,14 @@ '\n' 'Whenever a class inherits from another class, ' '"__init_subclass__()" is\n' - 'called on that class. This way, it is possible to write ' - 'classes which\n' - 'change the behavior of subclasses. This is closely related ' - 'to class\n' - 'decorators, but where class decorators only affect the ' - 'specific class\n' - 'they?re applied to, "__init_subclass__" solely applies to ' - 'future\n' + 'called on the parent class. This way, it is possible to ' + 'write classes\n' + 'which change the behavior of subclasses. This is closely ' + 'related to\n' + 'class decorators, but where class decorators only affect the ' + 'specific\n' + 'class they?re applied to, "__init_subclass__" solely applies ' + 'to future\n' 'subclasses of the class defining the method.\n' '\n' 'classmethod object.__init_subclass__(cls)\n' @@ -12290,67 +12293,86 @@ 'subscriptions': 'Subscriptions\n' '*************\n' '\n' - 'Subscription of a sequence (string, tuple or list) or ' - 'mapping\n' - '(dictionary) object usually selects an item from the ' - 'collection:\n' + 'The subscription of an instance of a container class will ' + 'generally\n' + 'select an element from the container. The subscription of a ' + '*generic\n' + 'class* will generally return a GenericAlias object.\n' '\n' ' subscription ::= primary "[" expression_list "]"\n' '\n' + 'When an object is subscripted, the interpreter will ' + 'evaluate the\n' + 'primary and the expression list.\n' + '\n' 'The primary must evaluate to an object that supports ' - 'subscription\n' - '(lists or dictionaries for example). User-defined objects ' - 'can support\n' - 'subscription by defining a "__getitem__()" method.\n' + 'subscription. An\n' + 'object may support subscription through defining one or ' + 'both of\n' + '"__getitem__()" and "__class_getitem__()". When the primary ' + 'is\n' + 'subscripted, the evaluated result of the expression list ' + 'will be\n' + 'passed to one of these methods. For more details on when\n' + '"__class_getitem__" is called instead of "__getitem__", ' + 'see\n' + '__class_getitem__ versus __getitem__.\n' + '\n' + 'If the expression list contains at least one comma, it will ' + 'evaluate\n' + 'to a "tuple" containing the items of the expression list. ' + 'Otherwise,\n' + 'the expression list will evaluate to the value of the ' + 'list?s sole\n' + 'member.\n' '\n' 'For built-in objects, there are two types of objects that ' 'support\n' - 'subscription:\n' + 'subscription via "__getitem__()":\n' '\n' - 'If the primary is a mapping, the expression list must ' - 'evaluate to an\n' - 'object whose value is one of the keys of the mapping, and ' + '1. Mappings. If the primary is a *mapping*, the expression ' + 'list must\n' + ' evaluate to an object whose value is one of the keys of ' 'the\n' - 'subscription selects the value in the mapping that ' - 'corresponds to that\n' - 'key. (The expression list is a tuple except if it has ' - 'exactly one\n' - 'item.)\n' - '\n' - 'If the primary is a sequence, the expression list must ' - 'evaluate to an\n' - 'integer or a slice (as discussed in the following ' - 'section).\n' + ' mapping, and the subscription selects the value in the ' + 'mapping that\n' + ' corresponds to that key. An example of a builtin mapping ' + 'class is\n' + ' the "dict" class.\n' + '\n' + '2. Sequences. If the primary is a *sequence*, the ' + 'expression list must\n' + ' evaluate to an "int" or a "slice" (as discussed in the ' + 'following\n' + ' section). Examples of builtin sequence classes include ' + 'the "str",\n' + ' "list" and "tuple" classes.\n' '\n' 'The formal syntax makes no special provision for negative ' 'indices in\n' - 'sequences; however, built-in sequences all provide a ' + '*sequences*. However, built-in sequences all provide a ' '"__getitem__()"\n' 'method that interprets negative indices by adding the ' 'length of the\n' - 'sequence to the index (so that "x[-1]" selects the last ' - 'item of "x").\n' - 'The resulting value must be a nonnegative integer less than ' - 'the number\n' - 'of items in the sequence, and the subscription selects the ' - 'item whose\n' - 'index is that value (counting from zero). Since the support ' - 'for\n' - 'negative indices and slicing occurs in the object?s ' - '"__getitem__()"\n' - 'method, subclasses overriding this method will need to ' - 'explicitly add\n' - 'that support.\n' - '\n' - 'A string?s items are characters. A character is not a ' - 'separate data\n' - 'type but a string of exactly one character.\n' - '\n' - 'Subscription of certain *classes* or *types* creates a ' - 'generic alias.\n' - 'In this case, user-defined classes can support subscription ' - 'by\n' - 'providing a "__class_getitem__()" classmethod.\n', + 'sequence to the index so that, for example, "x[-1]" selects ' + 'the last\n' + 'item of "x". The resulting value must be a nonnegative ' + 'integer less\n' + 'than the number of items in the sequence, and the ' + 'subscription selects\n' + 'the item whose index is that value (counting from zero). ' + 'Since the\n' + 'support for negative indices and slicing occurs in the ' + 'object?s\n' + '"__getitem__()" method, subclasses overriding this method ' + 'will need to\n' + 'explicitly add that support.\n' + '\n' + 'A "string" is a special kind of sequence whose items are ' + '*characters*.\n' + 'A character is not a separate data type but a string of ' + 'exactly one\n' + 'character.\n', 'truth': 'Truth Value Testing\n' '*******************\n' '\n' diff --git a/Misc/NEWS.d/3.10.3.rst b/Misc/NEWS.d/3.10.3.rst new file mode 100644 index 0000000000000..eeaeda9c40bae --- /dev/null +++ b/Misc/NEWS.d/3.10.3.rst @@ -0,0 +1,945 @@ +.. bpo: 46940 +.. date: 2022-03-06-20-16-13 +.. nonce: _X47Hx +.. release date: 2022-03-16 +.. section: Core and Builtins + +Avoid overriding :exc:`AttributeError` metadata information for nested +attribute access calls. Patch by Pablo Galindo. + +.. + +.. bpo: 46852 +.. date: 2022-02-25-02-01-42 +.. nonce: _3zg8D +.. section: Core and Builtins + +Rename the private undocumented ``float.__set_format__()`` method to +``float.__setformat__()`` to fix a typo introduced in Python 3.7. The method +is only used by test_float. Patch by Victor Stinner. + +.. + +.. bpo: 46794 +.. date: 2022-02-22-12-07-53 +.. nonce: 6WvJ9o +.. section: Core and Builtins + +Bump up the libexpat version into 2.4.6 + +.. + +.. bpo: 46820 +.. date: 2022-02-21-21-55-23 +.. nonce: 4RfUZh +.. section: Core and Builtins + +Fix parsing a numeric literal immediately (without spaces) followed by "not +in" keywords, like in ``1not in x``. Now the parser only emits a warning, +not a syntax error. + +.. + +.. bpo: 46762 +.. date: 2022-02-15-20-26-46 +.. nonce: 1H7vab +.. section: Core and Builtins + +Fix an assert failure in debug builds when a '<', '>', or '=' is the last +character in an f-string that's missing a closing right brace. + +.. + +.. bpo: 46724 +.. date: 2022-02-14-14-44-06 +.. nonce: jym_K6 +.. section: Core and Builtins + +Make sure that all backwards jumps use the ``JUMP_ABSOLUTE`` instruction, +rather than ``JUMP_FORWARD`` with an argument of ``(2**32)+offset``. + +.. + +.. bpo: 46732 +.. date: 2022-02-12-11-16-40 +.. nonce: 3Z_qxd +.. section: Core and Builtins + +Correct the docstring for the :meth:`__bool__` method. Patch by Jelle +Zijlstra. + +.. + +.. bpo: 46707 +.. date: 2022-02-10-03-13-18 +.. nonce: xeSEh0 +.. section: Core and Builtins + +Avoid potential exponential backtracking when producing some syntax errors +involving lots of brackets. Patch by Pablo Galindo. + +.. + +.. bpo: 40479 +.. date: 2022-02-06-23-08-30 +.. nonce: zED3Zu +.. section: Core and Builtins + +Add a missing call to ``va_end()`` in ``Modules/_hashopenssl.c``. + +.. + +.. bpo: 46615 +.. date: 2022-02-04-04-33-18 +.. nonce: puArY9 +.. section: Core and Builtins + +When iterating over sets internally in ``setobject.c``, acquire strong +references to the resulting items from the set. This prevents crashes in +corner-cases of various set operations where the set gets mutated. + +.. + +.. bpo: 45773 +.. date: 2022-02-01-14-30-56 +.. nonce: Up77LD +.. section: Core and Builtins + +Remove two invalid "peephole" optimizations from the bytecode compiler. + +.. + +.. bpo: 43721 +.. date: 2022-02-01-10-05-27 +.. nonce: -1XAIo +.. section: Core and Builtins + +Fix docstrings of :attr:`~property.getter`, :attr:`~property.setter`, and +:attr:`~property.deleter` to clarify that they create a new copy of the +property. + +.. + +.. bpo: 46503 +.. date: 2022-01-24-21-24-41 +.. nonce: 4UrPsE +.. section: Core and Builtins + +Fix an assert when parsing some invalid \N escape sequences in f-strings. + +.. + +.. bpo: 46417 +.. date: 2022-01-22-14-39-23 +.. nonce: 3U5SfN +.. section: Core and Builtins + +Fix a race condition on setting a type ``__bases__`` attribute: the internal +function ``add_subclass()`` now gets the ``PyTypeObject.tp_subclasses`` +member after calling :c:func:`PyWeakref_NewRef` which can trigger a garbage +collection which can indirectly modify ``PyTypeObject.tp_subclasses``. Patch +by Victor Stinner. + +.. + +.. bpo: 46383 +.. date: 2022-01-14-20-55-34 +.. nonce: v8MTl4 +.. section: Core and Builtins + +Fix invalid signature of ``_zoneinfo``'s ``module_free`` function to resolve +a crash on wasm32-emscripten platform. + +.. + +.. bpo: 46070 +.. date: 2022-01-13-17-58-56 +.. nonce: q8IGth +.. section: Core and Builtins + +:c:func:`Py_EndInterpreter` now explicitly untracks all objects currently +tracked by the GC. Previously, if an object was used later by another +interpreter, calling :c:func:`PyObject_GC_UnTrack` on the object crashed if +the previous or the next object of the :c:type:`PyGC_Head` structure became +a dangling pointer. Patch by Victor Stinner. + +.. + +.. bpo: 46339 +.. date: 2022-01-11-11-50-19 +.. nonce: OVumDZ +.. section: Core and Builtins + +Fix a crash in the parser when retrieving the error text for multi-line +f-strings expressions that do not start in the first line of the string. +Patch by Pablo Galindo + +.. + +.. bpo: 46240 +.. date: 2022-01-03-23-31-25 +.. nonce: 8lGjeK +.. section: Core and Builtins + +Correct the error message for unclosed parentheses when the tokenizer +doesn't reach the end of the source when the error is reported. Patch by +Pablo Galindo + +.. + +.. bpo: 46091 +.. date: 2021-12-16-00-24-00 +.. nonce: rJ_e_e +.. section: Core and Builtins + +Correctly calculate indentation levels for lines with whitespace character +that are ended by line continuation characters. Patch by Pablo Galindo + +.. + +.. bpo: 43253 +.. date: 2022-03-15-07-53-45 +.. nonce: rjdLFj +.. section: Library + +Fix a crash when closing transports where the underlying socket handle is +already invalid on the Proactor event loop. + +.. + +.. bpo: 47004 +.. date: 2022-03-13-15-04-05 +.. nonce: SyYpxd +.. section: Library + +Apply bugfixes from importlib_metadata 4.11.3, including bugfix for +EntryPoint.extras, which was returning match objects and not the extras +strings. + +.. + +.. bpo: 46985 +.. date: 2022-03-11-13-34-16 +.. nonce: BgoMr2 +.. section: Library + +Upgrade pip wheel bundled with ensurepip (pip 22.0.4) + +.. + +.. bpo: 46968 +.. date: 2022-03-10-14-51-11 +.. nonce: ym2QxL +.. section: Library + +:mod:`faulthandler`: On Linux 5.14 and newer, dynamically determine size of +signal handler stack size CPython allocates using +``getauxval(AT_MINSIGSTKSZ)``. This changes allows for Python extension's +request to Linux kernel to use AMX_TILE instruction set on Sapphire Rapids +Xeon processor to succeed, unblocking use of the ISA in frameworks. + +.. + +.. bpo: 46955 +.. date: 2022-03-08-22-41-59 +.. nonce: IOoonN +.. section: Library + +Expose :class:`asyncio.base_events.Server` as :class:`asyncio.Server`. Patch +by Stefan Zabka. + +.. + +.. bpo: 23325 +.. date: 2022-03-08-11-34-06 +.. nonce: 3VQnfo +.. section: Library + +The :mod:`signal` module no longer assumes that :const:`~signal.SIG_IGN` and +:const:`~signal.SIG_DFL` are small int singletons. + +.. + +.. bpo: 46932 +.. date: 2022-03-07-20-20-34 +.. nonce: xbarAs +.. section: Library + +Update bundled libexpat to 2.4.7 + +.. + +.. bpo: 25707 +.. date: 2022-03-05-09-43-53 +.. nonce: gTlclP +.. section: Library + +Fixed a file leak in :func:`xml.etree.ElementTree.iterparse` when the +iterator is not exhausted. Patch by Jacob Walls. + +.. + +.. bpo: 44886 +.. date: 2022-02-23-00-55-59 +.. nonce: I40Mbr +.. section: Library + +Inherit asyncio proactor datagram transport from +:class:`asyncio.DatagramTransport`. + +.. + +.. bpo: 46827 +.. date: 2022-02-22-15-08-30 +.. nonce: hvj38S +.. section: Library + +Support UDP sockets in :meth:`asyncio.loop.sock_connect` for selector-based +event loops. Patch by Thomas Grainger. + +.. + +.. bpo: 46811 +.. date: 2022-02-20-21-03-31 +.. nonce: 8BxgdQ +.. section: Library + +Make test suite support Expat >=2.4.5 + +.. + +.. bpo: 46252 +.. date: 2022-02-20-12-59-46 +.. nonce: KG1SqA +.. section: Library + +Raise :exc:`TypeError` if :class:`ssl.SSLSocket` is passed to +transport-based APIs. + +.. + +.. bpo: 46784 +.. date: 2022-02-18-22-10-30 +.. nonce: SVOQJx +.. section: Library + +Fix libexpat symbols collisions with user dynamically loaded or statically +linked libexpat in embedded Python. + +.. + +.. bpo: 39327 +.. date: 2022-02-17-13-10-50 +.. nonce: ytIT7Z +.. section: Library + +:func:`shutil.rmtree` can now work with VirtualBox shared folders when +running from the guest operating-system. + +.. + +.. bpo: 46756 +.. date: 2022-02-15-11-57-53 +.. nonce: AigSPi +.. section: Library + +Fix a bug in :meth:`urllib.request.HTTPPasswordMgr.find_user_password` and +:meth:`urllib.request.HTTPPasswordMgrWithPriorAuth.is_authenticated` which +allowed to bypass authorization. For example, access to URI +``example.org/foobar`` was allowed if the user was authorized for URI +``example.org/foo``. + +.. + +.. bpo: 46643 +.. date: 2022-02-09-22-40-11 +.. nonce: aBlIx1 +.. section: Library + +In :func:`typing.get_type_hints`, support evaluating stringified +``ParamSpecArgs`` and ``ParamSpecKwargs`` annotations. Patch by Gregory +Beauregard. + +.. + +.. bpo: 45863 +.. date: 2022-02-09-00-53-23 +.. nonce: zqQXVv +.. section: Library + +When the :mod:`tarfile` module creates a pax format archive, it will put an +integer representation of timestamps in the ustar header (if possible) for +the benefit of older unarchivers, in addition to the existing full-precision +timestamps in the pax extended header. + +.. + +.. bpo: 46676 +.. date: 2022-02-07-19-20-42 +.. nonce: 3Aws1o +.. section: Library + +Make :data:`typing.ParamSpec` args and kwargs equal to themselves. Patch by +Gregory Beauregard. + +.. + +.. bpo: 46672 +.. date: 2022-02-07-13-15-16 +.. nonce: 4swIjx +.. section: Library + +Fix ``NameError`` in :func:`asyncio.gather` when initial type check fails. + +.. + +.. bpo: 46655 +.. date: 2022-02-06-08-54-03 +.. nonce: DiLzYv +.. section: Library + +In :func:`typing.get_type_hints`, support evaluating bare stringified +``TypeAlias`` annotations. Patch by Gregory Beauregard. + +.. + +.. bpo: 45948 +.. date: 2022-02-05-18-22-05 +.. nonce: w4mCnE +.. section: Library + +Fixed a discrepancy in the C implementation of the +:mod:`xml.etree.ElementTree` module. Now, instantiating an +:class:`xml.etree.ElementTree.XMLParser` with a ``target=None`` keyword +provides a default :class:`xml.etree.ElementTree.TreeBuilder` target as the +Python implementation does. + +.. + +.. bpo: 46521 +.. date: 2022-02-01-19-34-28 +.. nonce: IMUIrs +.. section: Library + +Fix a bug in the :mod:`codeop` module that was incorrectly identifying +invalid code involving string quotes as valid code. + +.. + +.. bpo: 46581 +.. date: 2022-02-01-11-32-47 +.. nonce: t7Zw65 +.. section: Library + +Brings :class:`ParamSpec` propagation for :class:`GenericAlias` in line with +:class:`Concatenate` (and others). + +.. + +.. bpo: 46591 +.. date: 2022-01-31-15-40-38 +.. nonce: prBD1M +.. section: Library + +Make the IDLE doc URL on the About IDLE dialog clickable. + +.. + +.. bpo: 46400 +.. date: 2022-01-30-15-16-12 +.. nonce: vweUiO +.. section: Library + +expat: Update libexpat from 2.4.1 to 2.4.4 + +.. + +.. bpo: 46487 +.. date: 2022-01-27-12-24-38 +.. nonce: UDkN2z +.. section: Library + +Add the ``get_write_buffer_limits`` method to +:class:`asyncio.transports.WriteTransport` and to the SSL transport. + +.. + +.. bpo: 45173 +.. date: 2022-01-27-11-16-59 +.. nonce: wreRF2 +.. section: Library + +Note the configparser deprecations will be removed in Python 3.12. + +.. + +.. bpo: 46539 +.. date: 2022-01-26-20-36-30 +.. nonce: 23iW1d +.. section: Library + +In :func:`typing.get_type_hints`, support evaluating stringified +``ClassVar`` and ``Final`` annotations inside ``Annotated``. Patch by +Gregory Beauregard. + +.. + +.. bpo: 46491 +.. date: 2022-01-24-23-55-30 +.. nonce: jmIKHo +.. section: Library + +Allow :data:`typing.Annotated` to wrap :data:`typing.Final` and +:data:`typing.ClassVar`. Patch by Gregory Beauregard. + +.. + +.. bpo: 46436 +.. date: 2022-01-23-19-37-00 +.. nonce: Biz1p9 +.. section: Library + +Fix command-line option ``-d``/``--directory`` in module :mod:`http.server` +which is ignored when combined with command-line option ``--cgi``. Patch by +G?ry Ogam. + +.. + +.. bpo: 41403 +.. date: 2022-01-23-18-04-45 +.. nonce: SgoHqV +.. section: Library + +Make :meth:`mock.patch` raise a :exc:`TypeError` with a relevant error +message on invalid arg. Previously it allowed a cryptic +:exc:`AttributeError` to escape. + +.. + +.. bpo: 46474 +.. date: 2022-01-22-14-49-10 +.. nonce: eKQhvx +.. section: Library + +In ``importlib.metadata.EntryPoint.pattern``, avoid potential REDoS by +limiting ambiguity in consecutive whitespace. + +.. + +.. bpo: 46469 +.. date: 2022-01-22-05-05-08 +.. nonce: plUab5 +.. section: Library + +:mod:`asyncio` generic classes now return :class:`types.GenericAlias` in +``__class_getitem__`` instead of the same class. + +.. + +.. bpo: 46434 +.. date: 2022-01-20-10-35-10 +.. nonce: geS-aP +.. section: Library + +:mod:`pdb` now gracefully handles ``help`` when :attr:`__doc__` is missing, +for example when run with pregenerated optimized ``.pyc`` files. + +.. + +.. bpo: 46333 +.. date: 2022-01-11-15-54-15 +.. nonce: B1faiF +.. section: Library + +The :meth:`__eq__` and :meth:`__hash__` methods of +:class:`typing.ForwardRef` now honor the ``module`` parameter of +:class:`typing.ForwardRef`. Forward references from different modules are +now differentiated. + +.. + +.. bpo: 46246 +.. date: 2022-01-07-13-27-53 +.. nonce: CTLx32 +.. section: Library + +Add missing ``__slots__`` to ``importlib.metadata.DeprecatedList``. Patch by +Arie Bovenberg. + +.. + +.. bpo: 46266 +.. date: 2022-01-05-12-48-18 +.. nonce: ACQCgX +.. section: Library + +Improve day constants in :mod:`calendar`. + +Now all constants (`MONDAY` ... `SUNDAY`) are documented, tested, and added +to ``__all__``. + +.. + +.. bpo: 46232 +.. date: 2022-01-03-09-46-44 +.. nonce: s0KlyI +.. section: Library + +The :mod:`ssl` module now handles certificates with bit strings in DN +correctly. + +.. + +.. bpo: 43118 +.. date: 2021-12-29-14-42-09 +.. nonce: BoVi_5 +.. section: Library + +Fix a bug in :func:`inspect.signature` that was causing it to fail on some +subclasses of classes with a ``__text_signature__`` referencing module +globals. Patch by Weipeng Hong. + +.. + +.. bpo: 26552 +.. date: 2021-12-29-13-42-55 +.. nonce: 1BqeAn +.. section: Library + +Fixed case where failing :func:`asyncio.ensure_future` did not close the +coroutine. Patch by Kumar Aditya. + +.. + +.. bpo: 21987 +.. date: 2021-12-28-11-55-10 +.. nonce: avBK-p +.. section: Library + +Fix an issue with :meth:`tarfile.TarFile.getmember` getting a directory name +with a trailing slash. + +.. + +.. bpo: 20392 +.. date: 2021-12-22-12-02-27 +.. nonce: CLAFIp +.. section: Library + +Fix inconsistency with uppercase file extensions in +:meth:`MimeTypes.guess_type`. Patch by Kumar Aditya. + +.. + +.. bpo: 46080 +.. date: 2021-12-15-06-29-00 +.. nonce: AuQpLt +.. section: Library + +Fix exception in argparse help text generation if a +:class:`argparse.BooleanOptionalAction` argument's default is +``argparse.SUPPRESS`` and it has ``help`` specified. Patch by Felix +Fontein. + +.. + +.. bpo: 44439 +.. date: 2021-11-08-20-27-41 +.. nonce: I_8qro +.. section: Library + +Fix ``.write()`` method of a member file in ``ZipFile``, when the input data +is an object that supports the buffer protocol, the file length may be +wrong. + +.. + +.. bpo: 45703 +.. date: 2021-11-03-13-41-49 +.. nonce: 35AagL +.. section: Library + +When a namespace package is imported before another module from the same +namespace is created/installed in a different :data:`sys.path` location +while the program is running, calling the +:func:`importlib.invalidate_caches` function will now also guarantee the new +module is noticed. + +.. + +.. bpo: 24959 +.. date: 2021-09-06-15-46-53 +.. nonce: UVFgiO +.. section: Library + +Fix bug where :mod:`unittest` sometimes drops frames from tracebacks of +exceptions raised in tests. + +.. + +.. bpo: 44791 +.. date: 2021-07-31-23-18-50 +.. nonce: 4jFdpO +.. section: Library + +Fix substitution of :class:`~typing.ParamSpec` in +:data:`~typing.Concatenate` with different parameter expressions. +Substitution with a list of types returns now a tuple of types. Substitution +with ``Concatenate`` returns now a ``Concatenate`` with concatenated lists +of arguments. + +.. + +.. bpo: 14156 +.. date: 2019-05-07-14-25-45 +.. nonce: 0FaHXE +.. section: Library + +argparse.FileType now supports an argument of '-' in binary mode, returning +the .buffer attribute of sys.stdin/sys.stdout as appropriate. Modes +including 'x' and 'a' are treated equivalently to 'w' when argument is '-'. +Patch contributed by Josh Rosenberg + +.. + +.. bpo: 46463 +.. date: 2022-01-21-21-33-48 +.. nonce: fBbdTG +.. section: Documentation + +Fixes :file:`escape4chm.py` script used when building the CHM documentation +file + +.. + +.. bpo: 46913 +.. date: 2022-03-03-17-36-24 +.. nonce: vxETIE +.. section: Tests + +Fix test_faulthandler.test_sigfpe() if Python is built with undefined +behavior sanitizer (UBSAN): disable UBSAN on the faulthandler_sigfpe() +function. Patch by Victor Stinner. + +.. + +.. bpo: 46708 +.. date: 2022-02-10-14-33-47 +.. nonce: avLfCb +.. section: Tests + +Prevent default asyncio event loop policy modification warning after +``test_asyncio`` execution. + +.. + +.. bpo: 46678 +.. date: 2022-02-07-12-40-45 +.. nonce: zfOrgL +.. section: Tests + +The function ``make_legacy_pyc`` in ``Lib/test/support/import_helper.py`` no +longer fails when ``PYTHONPYCACHEPREFIX`` is set to a directory on a +different device from where tempfiles are stored. + +.. + +.. bpo: 46616 +.. date: 2022-02-02-18-14-38 +.. nonce: URvBtE +.. section: Tests + +Ensures ``test_importlib.test_windows`` cleans up registry keys after +completion. + +.. + +.. bpo: 44359 +.. date: 2022-02-02-02-24-04 +.. nonce: kPPSmN +.. section: Tests + +test_ftplib now silently ignores socket errors to prevent logging unhandled +threading exceptions. Patch by Victor Stinner. + +.. + +.. bpo: 46542 +.. date: 2022-01-31-17-34-13 +.. nonce: RTMm1T +.. section: Tests + +Fix a Python crash in test_lib2to3 when using Python built in debug mode: +limit the recursion limit. Patch by Victor Stinner. + +.. + +.. bpo: 46576 +.. date: 2022-01-29-12-37-53 +.. nonce: -prRaV +.. section: Tests + +test_peg_generator now disables compiler optimization when testing +compilation of its own C extensions to significantly speed up the testing on +non-debug builds of CPython. + +.. + +.. bpo: 46542 +.. date: 2022-01-28-01-17-10 +.. nonce: xRLTdj +.. section: Tests + +Fix ``test_json`` tests checking for :exc:`RecursionError`: modify these +tests to use ``support.infinite_recursion()``. Patch by Victor Stinner. + +.. + +.. bpo: 13886 +.. date: 2022-01-17-13-10-04 +.. nonce: 5mZH4b +.. section: Tests + +Skip test_builtin PTY tests on non-ASCII characters if the readline module +is loaded. The readline module changes input() behavior, but test_builtin is +not intented to test the readline module. Patch by Victor Stinner. + +.. + +.. bpo: 47032 +.. date: 2022-03-16-00-37-40 +.. nonce: tsS9KE +.. section: Build + +Ensure Windows install builds fail correctly with a non-zero exit code when +part of the build fails. + +.. + +.. bpo: 47024 +.. date: 2022-03-15-09-28-55 +.. nonce: t7-dcu +.. section: Build + +Update OpenSSL to 1.1.1n for macOS installers and all Windows builds. + +.. + +.. bpo: 38472 +.. date: 2022-01-26-22-59-12 +.. nonce: RxfLho +.. section: Build + +Fix GCC detection in setup.py when cross-compiling. The C compiler is now +run with LC_ALL=C. Previously, the detection failed with a German locale. + +.. + +.. bpo: 46513 +.. date: 2022-01-25-12-32-37 +.. nonce: mPm9B4 +.. section: Build + +:program:`configure` no longer uses ``AC_C_CHAR_UNSIGNED`` macro and +``pyconfig.h`` no longer defines reserved symbol ``__CHAR_UNSIGNED__``. + +.. + +.. bpo: 45925 +.. date: 2022-01-08-12-43-31 +.. nonce: 38F3NO +.. section: Build + +Update Windows installer to use SQLite 3.37.2. + +.. + +.. bpo: 44549 +.. date: 2022-03-07-17-46-40 +.. nonce: SPrGS9 +.. section: Windows + +Update bzip2 to 1.0.8 in Windows builds to mitigate CVE-2016-3189 and +CVE-2019-12900 + +.. + +.. bpo: 46948 +.. date: 2022-03-07-16-34-11 +.. nonce: Ufd4tG +.. section: Windows + +Prevent CVE-2022-26488 by ensuring the Add to PATH option in the Windows +installer uses the correct path when being repaired. + +.. + +.. bpo: 46638 +.. date: 2022-02-04-18-02-33 +.. nonce: mSJOSX +.. section: Windows + +Ensures registry virtualization is consistently disabled. For 3.10 and +earlier, it remains enabled (some registry writes are protected), while for +3.11 and later it is disabled (registry modifications affect all +applications). + +.. + +.. bpo: 45925 +.. date: 2022-01-26-12-04-09 +.. nonce: yBSiYO +.. section: macOS + +Update macOS installer to SQLite 3.37.2. + +.. + +.. bpo: 46630 +.. date: 2022-02-03-15-47-53 +.. nonce: tREOjo +.. section: IDLE + +Make query dialogs on Windows start with a cursor in the entry box. + +.. + +.. bpo: 45296 +.. date: 2022-01-26-19-33-55 +.. nonce: LzZKdU +.. section: IDLE + +Clarify close, quit, and exit in IDLE. In the File menu, 'Close' and 'Exit' +are now 'Close Window' (the current one) and 'Exit' is now 'Exit IDLE' (by +closing all windows). In Shell, 'quit()' and 'exit()' mean 'close Shell'. +If there are no other windows, this also exits IDLE. + +.. + +.. bpo: 45447 +.. date: 2021-10-14-16-55-03 +.. nonce: FhiH5P +.. section: IDLE + +Apply IDLE syntax highlighting to `.pyi` files. Patch by Alex Waygood and +Terry Jan Reedy. + +.. + +.. bpo: 46433 +.. date: 2022-01-19-16-51-54 +.. nonce: Er9ApS +.. section: C API + +The internal function _PyType_GetModuleByDef now correctly handles +inheritance patterns involving static types. + +.. + +.. bpo: 14916 +.. date: 2020-09-11-02-50-41 +.. nonce: QN1Y03 +.. section: C API + +Fixed bug in the tokenizer that prevented ``PyRun_InteractiveOne`` from +parsing from the provided FD. diff --git a/Misc/NEWS.d/next/Build/2022-01-08-12-43-31.bpo-45925.38F3NO.rst b/Misc/NEWS.d/next/Build/2022-01-08-12-43-31.bpo-45925.38F3NO.rst deleted file mode 100644 index e802912bfcff7..0000000000000 --- a/Misc/NEWS.d/next/Build/2022-01-08-12-43-31.bpo-45925.38F3NO.rst +++ /dev/null @@ -1 +0,0 @@ -Update Windows installer to use SQLite 3.37.2. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Build/2022-01-25-12-32-37.bpo-46513.mPm9B4.rst b/Misc/NEWS.d/next/Build/2022-01-25-12-32-37.bpo-46513.mPm9B4.rst deleted file mode 100644 index b8986ae31a340..0000000000000 --- a/Misc/NEWS.d/next/Build/2022-01-25-12-32-37.bpo-46513.mPm9B4.rst +++ /dev/null @@ -1,2 +0,0 @@ -:program:`configure` no longer uses ``AC_C_CHAR_UNSIGNED`` macro and -``pyconfig.h`` no longer defines reserved symbol ``__CHAR_UNSIGNED__``. diff --git a/Misc/NEWS.d/next/Build/2022-01-26-22-59-12.bpo-38472.RxfLho.rst b/Misc/NEWS.d/next/Build/2022-01-26-22-59-12.bpo-38472.RxfLho.rst deleted file mode 100644 index 4e0ee70bdc513..0000000000000 --- a/Misc/NEWS.d/next/Build/2022-01-26-22-59-12.bpo-38472.RxfLho.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix GCC detection in setup.py when cross-compiling. The C compiler is now -run with LC_ALL=C. Previously, the detection failed with a German locale. diff --git a/Misc/NEWS.d/next/Build/2022-03-15-09-28-55.bpo-47024.t7-dcu.rst b/Misc/NEWS.d/next/Build/2022-03-15-09-28-55.bpo-47024.t7-dcu.rst deleted file mode 100644 index 1035cbab1ba61..0000000000000 --- a/Misc/NEWS.d/next/Build/2022-03-15-09-28-55.bpo-47024.t7-dcu.rst +++ /dev/null @@ -1 +0,0 @@ -Update OpenSSL to 1.1.1n for macOS installers and all Windows builds. diff --git a/Misc/NEWS.d/next/Build/2022-03-16-00-37-40.bpo-47032.tsS9KE.rst b/Misc/NEWS.d/next/Build/2022-03-16-00-37-40.bpo-47032.tsS9KE.rst deleted file mode 100644 index 4f2f1c8d0471a..0000000000000 --- a/Misc/NEWS.d/next/Build/2022-03-16-00-37-40.bpo-47032.tsS9KE.rst +++ /dev/null @@ -1,2 +0,0 @@ -Ensure Windows install builds fail correctly with a non-zero exit code when -part of the build fails. diff --git a/Misc/NEWS.d/next/C API/2020-09-11-02-50-41.bpo-14916.QN1Y03.rst b/Misc/NEWS.d/next/C API/2020-09-11-02-50-41.bpo-14916.QN1Y03.rst deleted file mode 100644 index 885cfc53aba38..0000000000000 --- a/Misc/NEWS.d/next/C API/2020-09-11-02-50-41.bpo-14916.QN1Y03.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed bug in the tokenizer that prevented ``PyRun_InteractiveOne`` from parsing from the provided FD. diff --git a/Misc/NEWS.d/next/C API/2022-01-19-16-51-54.bpo-46433.Er9ApS.rst b/Misc/NEWS.d/next/C API/2022-01-19-16-51-54.bpo-46433.Er9ApS.rst deleted file mode 100644 index e1987c4536b5c..0000000000000 --- a/Misc/NEWS.d/next/C API/2022-01-19-16-51-54.bpo-46433.Er9ApS.rst +++ /dev/null @@ -1,2 +0,0 @@ -The internal function _PyType_GetModuleByDef now correctly handles -inheritance patterns involving static types. diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-12-16-00-24-00.bpo-46091.rJ_e_e.rst b/Misc/NEWS.d/next/Core and Builtins/2021-12-16-00-24-00.bpo-46091.rJ_e_e.rst deleted file mode 100644 index a2eee0f3ebd51..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2021-12-16-00-24-00.bpo-46091.rJ_e_e.rst +++ /dev/null @@ -1,2 +0,0 @@ -Correctly calculate indentation levels for lines with whitespace character -that are ended by line continuation characters. Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-01-03-23-31-25.bpo-46240.8lGjeK.rst b/Misc/NEWS.d/next/Core and Builtins/2022-01-03-23-31-25.bpo-46240.8lGjeK.rst deleted file mode 100644 index a7702ebafbd46..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-01-03-23-31-25.bpo-46240.8lGjeK.rst +++ /dev/null @@ -1,3 +0,0 @@ -Correct the error message for unclosed parentheses when the tokenizer -doesn't reach the end of the source when the error is reported. Patch by -Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-01-11-11-50-19.bpo-46339.OVumDZ.rst b/Misc/NEWS.d/next/Core and Builtins/2022-01-11-11-50-19.bpo-46339.OVumDZ.rst deleted file mode 100644 index cd04f060826b2..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-01-11-11-50-19.bpo-46339.OVumDZ.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix a crash in the parser when retrieving the error text for multi-line -f-strings expressions that do not start in the first line of the string. -Patch by Pablo Galindo diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-01-13-17-58-56.bpo-46070.q8IGth.rst b/Misc/NEWS.d/next/Core and Builtins/2022-01-13-17-58-56.bpo-46070.q8IGth.rst deleted file mode 100644 index 4ed088f9898eb..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-01-13-17-58-56.bpo-46070.q8IGth.rst +++ /dev/null @@ -1,5 +0,0 @@ -:c:func:`Py_EndInterpreter` now explicitly untracks all objects currently -tracked by the GC. Previously, if an object was used later by another -interpreter, calling :c:func:`PyObject_GC_UnTrack` on the object crashed if the -previous or the next object of the :c:type:`PyGC_Head` structure became a -dangling pointer. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-01-14-20-55-34.bpo-46383.v8MTl4.rst b/Misc/NEWS.d/next/Core and Builtins/2022-01-14-20-55-34.bpo-46383.v8MTl4.rst deleted file mode 100644 index 8f8b12732a690..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-01-14-20-55-34.bpo-46383.v8MTl4.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix invalid signature of ``_zoneinfo``'s ``module_free`` function to resolve -a crash on wasm32-emscripten platform. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-01-22-14-39-23.bpo-46417.3U5SfN.rst b/Misc/NEWS.d/next/Core and Builtins/2022-01-22-14-39-23.bpo-46417.3U5SfN.rst deleted file mode 100644 index 54fe09b7ba454..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-01-22-14-39-23.bpo-46417.3U5SfN.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fix a race condition on setting a type ``__bases__`` attribute: the internal -function ``add_subclass()`` now gets the ``PyTypeObject.tp_subclasses`` -member after calling :c:func:`PyWeakref_NewRef` which can trigger a garbage -collection which can indirectly modify ``PyTypeObject.tp_subclasses``. Patch -by Victor Stinner. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-01-24-21-24-41.bpo-46503.4UrPsE.rst b/Misc/NEWS.d/next/Core and Builtins/2022-01-24-21-24-41.bpo-46503.4UrPsE.rst deleted file mode 100644 index e48028d72ca8e..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-01-24-21-24-41.bpo-46503.4UrPsE.rst +++ /dev/null @@ -1 +0,0 @@ -Fix an assert when parsing some invalid \N escape sequences in f-strings. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst deleted file mode 100644 index cd3df72664823..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-01-10-05-27.bpo-43721.-1XAIo.rst +++ /dev/null @@ -1 +0,0 @@ -Fix docstrings of :attr:`~property.getter`, :attr:`~property.setter`, and :attr:`~property.deleter` to clarify that they create a new copy of the property. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-01-14-30-56.bpo-45773.Up77LD.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-01-14-30-56.bpo-45773.Up77LD.rst deleted file mode 100644 index 45da5116fc940..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-01-14-30-56.bpo-45773.Up77LD.rst +++ /dev/null @@ -1 +0,0 @@ -Remove two invalid "peephole" optimizations from the bytecode compiler. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-04-04-33-18.bpo-46615.puArY9.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-04-04-33-18.bpo-46615.puArY9.rst deleted file mode 100644 index 6dee92a546e33..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-04-04-33-18.bpo-46615.puArY9.rst +++ /dev/null @@ -1 +0,0 @@ -When iterating over sets internally in ``setobject.c``, acquire strong references to the resulting items from the set. This prevents crashes in corner-cases of various set operations where the set gets mutated. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-06-23-08-30.bpo-40479.zED3Zu.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-06-23-08-30.bpo-40479.zED3Zu.rst deleted file mode 100644 index 52701d53d8fe2..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-06-23-08-30.bpo-40479.zED3Zu.rst +++ /dev/null @@ -1 +0,0 @@ -Add a missing call to ``va_end()`` in ``Modules/_hashopenssl.c``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-10-03-13-18.bpo-46707.xeSEh0.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-10-03-13-18.bpo-46707.xeSEh0.rst deleted file mode 100644 index 4b156c4d5f68b..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-10-03-13-18.bpo-46707.xeSEh0.rst +++ /dev/null @@ -1,2 +0,0 @@ -Avoid potential exponential backtracking when producing some syntax errors -involving lots of brackets. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-12-11-16-40.bpo-46732.3Z_qxd.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-12-11-16-40.bpo-46732.3Z_qxd.rst deleted file mode 100644 index 9937116bb2e7b..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-12-11-16-40.bpo-46732.3Z_qxd.rst +++ /dev/null @@ -1,2 +0,0 @@ -Correct the docstring for the :meth:`__bool__` method. Patch by Jelle -Zijlstra. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-14-14-44-06.bpo-46724.jym_K6.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-14-14-44-06.bpo-46724.jym_K6.rst deleted file mode 100644 index 7324182677abf..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-14-14-44-06.bpo-46724.jym_K6.rst +++ /dev/null @@ -1,2 +0,0 @@ -Make sure that all backwards jumps use the ``JUMP_ABSOLUTE`` instruction, rather -than ``JUMP_FORWARD`` with an argument of ``(2**32)+offset``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-15-20-26-46.bpo-46762.1H7vab.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-15-20-26-46.bpo-46762.1H7vab.rst deleted file mode 100644 index cd53eb4ffaddd..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-15-20-26-46.bpo-46762.1H7vab.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix an assert failure in debug builds when a '<', '>', or '=' is the last -character in an f-string that's missing a closing right brace. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-21-21-55-23.bpo-46820.4RfUZh.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-21-21-55-23.bpo-46820.4RfUZh.rst deleted file mode 100644 index 117a84d0cbfaf..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-21-21-55-23.bpo-46820.4RfUZh.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix parsing a numeric literal immediately (without spaces) followed by "not -in" keywords, like in ``1not in x``. Now the parser only emits a warning, -not a syntax error. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-22-12-07-53.bpo-46794.6WvJ9o.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-22-12-07-53.bpo-46794.6WvJ9o.rst deleted file mode 100644 index 127387d32cb7a..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-22-12-07-53.bpo-46794.6WvJ9o.rst +++ /dev/null @@ -1 +0,0 @@ -Bump up the libexpat version into 2.4.6 diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-25-02-01-42.bpo-46852._3zg8D.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-25-02-01-42.bpo-46852._3zg8D.rst deleted file mode 100644 index 65b826473b915..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-02-25-02-01-42.bpo-46852._3zg8D.rst +++ /dev/null @@ -1,3 +0,0 @@ -Rename the private undocumented ``float.__set_format__()`` method to -``float.__setformat__()`` to fix a typo introduced in Python 3.7. The method -is only used by test_float. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-06-20-16-13.bpo-46940._X47Hx.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-06-20-16-13.bpo-46940._X47Hx.rst deleted file mode 100644 index fabc946019758..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-03-06-20-16-13.bpo-46940._X47Hx.rst +++ /dev/null @@ -1,2 +0,0 @@ -Avoid overriding :exc:`AttributeError` metadata information for nested -attribute access calls. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Documentation/2022-01-21-21-33-48.bpo-46463.fBbdTG.rst b/Misc/NEWS.d/next/Documentation/2022-01-21-21-33-48.bpo-46463.fBbdTG.rst deleted file mode 100644 index d418190bb8fc8..0000000000000 --- a/Misc/NEWS.d/next/Documentation/2022-01-21-21-33-48.bpo-46463.fBbdTG.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixes :file:`escape4chm.py` script used when building the CHM documentation -file diff --git a/Misc/NEWS.d/next/IDLE/2021-10-14-16-55-03.bpo-45447.FhiH5P.rst b/Misc/NEWS.d/next/IDLE/2021-10-14-16-55-03.bpo-45447.FhiH5P.rst deleted file mode 100644 index 2b5170c7631d2..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2021-10-14-16-55-03.bpo-45447.FhiH5P.rst +++ /dev/null @@ -1,2 +0,0 @@ -Apply IDLE syntax highlighting to `.pyi` files. Patch by Alex Waygood -and Terry Jan Reedy. diff --git a/Misc/NEWS.d/next/IDLE/2022-01-26-19-33-55.bpo-45296.LzZKdU.rst b/Misc/NEWS.d/next/IDLE/2022-01-26-19-33-55.bpo-45296.LzZKdU.rst deleted file mode 100644 index a5b0f8b4ffa80..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2022-01-26-19-33-55.bpo-45296.LzZKdU.rst +++ /dev/null @@ -1,4 +0,0 @@ -Clarify close, quit, and exit in IDLE. In the File menu, 'Close' and 'Exit' -are now 'Close Window' (the current one) and 'Exit' is now 'Exit IDLE' -(by closing all windows). In Shell, 'quit()' and 'exit()' mean 'close Shell'. -If there are no other windows, this also exits IDLE. diff --git a/Misc/NEWS.d/next/IDLE/2022-02-03-15-47-53.bpo-46630.tREOjo.rst b/Misc/NEWS.d/next/IDLE/2022-02-03-15-47-53.bpo-46630.tREOjo.rst deleted file mode 100644 index 81e35486eaf21..0000000000000 --- a/Misc/NEWS.d/next/IDLE/2022-02-03-15-47-53.bpo-46630.tREOjo.rst +++ /dev/null @@ -1 +0,0 @@ -Make query dialogs on Windows start with a cursor in the entry box. diff --git a/Misc/NEWS.d/next/Library/2019-05-07-14-25-45.bpo-14156.0FaHXE.rst b/Misc/NEWS.d/next/Library/2019-05-07-14-25-45.bpo-14156.0FaHXE.rst deleted file mode 100644 index 7bfc917a2a750..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-07-14-25-45.bpo-14156.0FaHXE.rst +++ /dev/null @@ -1,4 +0,0 @@ -argparse.FileType now supports an argument of '-' in binary mode, returning -the .buffer attribute of sys.stdin/sys.stdout as appropriate. Modes -including 'x' and 'a' are treated equivalently to 'w' when argument is '-'. -Patch contributed by Josh Rosenberg diff --git a/Misc/NEWS.d/next/Library/2021-07-31-23-18-50.bpo-44791.4jFdpO.rst b/Misc/NEWS.d/next/Library/2021-07-31-23-18-50.bpo-44791.4jFdpO.rst deleted file mode 100644 index 8182aa4e5358a..0000000000000 --- a/Misc/NEWS.d/next/Library/2021-07-31-23-18-50.bpo-44791.4jFdpO.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fix substitution of :class:`~typing.ParamSpec` in -:data:`~typing.Concatenate` with different parameter expressions. -Substitution with a list of types returns now a tuple of types. Substitution -with ``Concatenate`` returns now a ``Concatenate`` with concatenated lists -of arguments. diff --git a/Misc/NEWS.d/next/Library/2021-09-06-15-46-53.bpo-24959.UVFgiO.rst b/Misc/NEWS.d/next/Library/2021-09-06-15-46-53.bpo-24959.UVFgiO.rst deleted file mode 100644 index b702986f9468a..0000000000000 --- a/Misc/NEWS.d/next/Library/2021-09-06-15-46-53.bpo-24959.UVFgiO.rst +++ /dev/null @@ -1 +0,0 @@ -Fix bug where :mod:`unittest` sometimes drops frames from tracebacks of exceptions raised in tests. diff --git a/Misc/NEWS.d/next/Library/2021-11-03-13-41-49.bpo-45703.35AagL.rst b/Misc/NEWS.d/next/Library/2021-11-03-13-41-49.bpo-45703.35AagL.rst deleted file mode 100644 index 9fa9be56b8327..0000000000000 --- a/Misc/NEWS.d/next/Library/2021-11-03-13-41-49.bpo-45703.35AagL.rst +++ /dev/null @@ -1,5 +0,0 @@ -When a namespace package is imported before another module from the same -namespace is created/installed in a different :data:`sys.path` location -while the program is running, calling the -:func:`importlib.invalidate_caches` function will now also guarantee the new -module is noticed. diff --git a/Misc/NEWS.d/next/Library/2021-11-08-20-27-41.bpo-44439.I_8qro.rst b/Misc/NEWS.d/next/Library/2021-11-08-20-27-41.bpo-44439.I_8qro.rst deleted file mode 100644 index f4e562c4236d2..0000000000000 --- a/Misc/NEWS.d/next/Library/2021-11-08-20-27-41.bpo-44439.I_8qro.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix ``.write()`` method of a member file in ``ZipFile``, when the input data is -an object that supports the buffer protocol, the file length may be wrong. diff --git a/Misc/NEWS.d/next/Library/2021-12-15-06-29-00.bpo-46080.AuQpLt.rst b/Misc/NEWS.d/next/Library/2021-12-15-06-29-00.bpo-46080.AuQpLt.rst deleted file mode 100644 index e42d84e31e759..0000000000000 --- a/Misc/NEWS.d/next/Library/2021-12-15-06-29-00.bpo-46080.AuQpLt.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix exception in argparse help text generation if a -:class:`argparse.BooleanOptionalAction` argument's default is -``argparse.SUPPRESS`` and it has ``help`` specified. Patch by Felix Fontein. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2021-12-22-12-02-27.bpo-20392.CLAFIp.rst b/Misc/NEWS.d/next/Library/2021-12-22-12-02-27.bpo-20392.CLAFIp.rst deleted file mode 100644 index 8973c4d433174..0000000000000 --- a/Misc/NEWS.d/next/Library/2021-12-22-12-02-27.bpo-20392.CLAFIp.rst +++ /dev/null @@ -1 +0,0 @@ -Fix inconsistency with uppercase file extensions in :meth:`MimeTypes.guess_type`. Patch by Kumar Aditya. diff --git a/Misc/NEWS.d/next/Library/2021-12-28-11-55-10.bpo-21987.avBK-p.rst b/Misc/NEWS.d/next/Library/2021-12-28-11-55-10.bpo-21987.avBK-p.rst deleted file mode 100644 index 305dd16d53b49..0000000000000 --- a/Misc/NEWS.d/next/Library/2021-12-28-11-55-10.bpo-21987.avBK-p.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix an issue with :meth:`tarfile.TarFile.getmember` getting a directory name -with a trailing slash. diff --git a/Misc/NEWS.d/next/Library/2021-12-29-13-42-55.bpo-26552.1BqeAn.rst b/Misc/NEWS.d/next/Library/2021-12-29-13-42-55.bpo-26552.1BqeAn.rst deleted file mode 100644 index 85b6a64ef53d1..0000000000000 --- a/Misc/NEWS.d/next/Library/2021-12-29-13-42-55.bpo-26552.1BqeAn.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed case where failing :func:`asyncio.ensure_future` did not close the coroutine. Patch by Kumar Aditya. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2021-12-29-14-42-09.bpo-43118.BoVi_5.rst b/Misc/NEWS.d/next/Library/2021-12-29-14-42-09.bpo-43118.BoVi_5.rst deleted file mode 100644 index a37c22cd78c09..0000000000000 --- a/Misc/NEWS.d/next/Library/2021-12-29-14-42-09.bpo-43118.BoVi_5.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix a bug in :func:`inspect.signature` that was causing it to fail on some -subclasses of classes with a ``__text_signature__`` referencing module -globals. Patch by Weipeng Hong. diff --git a/Misc/NEWS.d/next/Library/2022-01-03-09-46-44.bpo-46232.s0KlyI.rst b/Misc/NEWS.d/next/Library/2022-01-03-09-46-44.bpo-46232.s0KlyI.rst deleted file mode 100644 index e252449199a05..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-03-09-46-44.bpo-46232.s0KlyI.rst +++ /dev/null @@ -1,2 +0,0 @@ -The :mod:`ssl` module now handles certificates with bit strings in DN -correctly. diff --git a/Misc/NEWS.d/next/Library/2022-01-05-12-48-18.bpo-46266.ACQCgX.rst b/Misc/NEWS.d/next/Library/2022-01-05-12-48-18.bpo-46266.ACQCgX.rst deleted file mode 100644 index 354dcb0106595..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-05-12-48-18.bpo-46266.ACQCgX.rst +++ /dev/null @@ -1,4 +0,0 @@ -Improve day constants in :mod:`calendar`. - -Now all constants (`MONDAY` ... `SUNDAY`) are documented, tested, and added -to ``__all__``. diff --git a/Misc/NEWS.d/next/Library/2022-01-07-13-27-53.bpo-46246.CTLx32.rst b/Misc/NEWS.d/next/Library/2022-01-07-13-27-53.bpo-46246.CTLx32.rst deleted file mode 100644 index 4850171439459..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-07-13-27-53.bpo-46246.CTLx32.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add missing ``__slots__`` to ``importlib.metadata.DeprecatedList``. Patch by -Arie Bovenberg. diff --git a/Misc/NEWS.d/next/Library/2022-01-11-15-54-15.bpo-46333.B1faiF.rst b/Misc/NEWS.d/next/Library/2022-01-11-15-54-15.bpo-46333.B1faiF.rst deleted file mode 100644 index ec3c6d54ee499..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-11-15-54-15.bpo-46333.B1faiF.rst +++ /dev/null @@ -1,4 +0,0 @@ -The :meth:`__eq__` and :meth:`__hash__` methods of -:class:`typing.ForwardRef` now honor the ``module`` parameter of -:class:`typing.ForwardRef`. Forward references from different -modules are now differentiated. diff --git a/Misc/NEWS.d/next/Library/2022-01-20-10-35-10.bpo-46434.geS-aP.rst b/Misc/NEWS.d/next/Library/2022-01-20-10-35-10.bpo-46434.geS-aP.rst deleted file mode 100644 index 6000781fa5aea..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-20-10-35-10.bpo-46434.geS-aP.rst +++ /dev/null @@ -1,2 +0,0 @@ -:mod:`pdb` now gracefully handles ``help`` when :attr:`__doc__` is missing, -for example when run with pregenerated optimized ``.pyc`` files. diff --git a/Misc/NEWS.d/next/Library/2022-01-22-05-05-08.bpo-46469.plUab5.rst b/Misc/NEWS.d/next/Library/2022-01-22-05-05-08.bpo-46469.plUab5.rst deleted file mode 100644 index 0d0e4b5d3d735..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-22-05-05-08.bpo-46469.plUab5.rst +++ /dev/null @@ -1 +0,0 @@ -:mod:`asyncio` generic classes now return :class:`types.GenericAlias` in ``__class_getitem__`` instead of the same class. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2022-01-22-14-49-10.bpo-46474.eKQhvx.rst b/Misc/NEWS.d/next/Library/2022-01-22-14-49-10.bpo-46474.eKQhvx.rst deleted file mode 100644 index 156b7de4f6787..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-22-14-49-10.bpo-46474.eKQhvx.rst +++ /dev/null @@ -1,2 +0,0 @@ -In ``importlib.metadata.EntryPoint.pattern``, avoid potential REDoS by -limiting ambiguity in consecutive whitespace. diff --git a/Misc/NEWS.d/next/Library/2022-01-23-18-04-45.bpo-41403.SgoHqV.rst b/Misc/NEWS.d/next/Library/2022-01-23-18-04-45.bpo-41403.SgoHqV.rst deleted file mode 100644 index ede159b25641f..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-23-18-04-45.bpo-41403.SgoHqV.rst +++ /dev/null @@ -1,3 +0,0 @@ -Make :meth:`mock.patch` raise a :exc:`TypeError` with a relevant error -message on invalid arg. Previously it allowed a cryptic -:exc:`AttributeError` to escape. diff --git a/Misc/NEWS.d/next/Library/2022-01-23-19-37-00.bpo-46436.Biz1p9.rst b/Misc/NEWS.d/next/Library/2022-01-23-19-37-00.bpo-46436.Biz1p9.rst deleted file mode 100644 index ccfd949506443..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-23-19-37-00.bpo-46436.Biz1p9.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix command-line option ``-d``/``--directory`` in module :mod:`http.server` -which is ignored when combined with command-line option ``--cgi``. Patch by -G?ry Ogam. diff --git a/Misc/NEWS.d/next/Library/2022-01-24-23-55-30.bpo-46491.jmIKHo.rst b/Misc/NEWS.d/next/Library/2022-01-24-23-55-30.bpo-46491.jmIKHo.rst deleted file mode 100644 index f66e8868f753f..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-24-23-55-30.bpo-46491.jmIKHo.rst +++ /dev/null @@ -1 +0,0 @@ -Allow :data:`typing.Annotated` to wrap :data:`typing.Final` and :data:`typing.ClassVar`. Patch by Gregory Beauregard. diff --git a/Misc/NEWS.d/next/Library/2022-01-26-20-36-30.bpo-46539.23iW1d.rst b/Misc/NEWS.d/next/Library/2022-01-26-20-36-30.bpo-46539.23iW1d.rst deleted file mode 100644 index 2bdde21b6e58e..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-26-20-36-30.bpo-46539.23iW1d.rst +++ /dev/null @@ -1 +0,0 @@ -In :func:`typing.get_type_hints`, support evaluating stringified ``ClassVar`` and ``Final`` annotations inside ``Annotated``. Patch by Gregory Beauregard. diff --git a/Misc/NEWS.d/next/Library/2022-01-27-11-16-59.bpo-45173.wreRF2.rst b/Misc/NEWS.d/next/Library/2022-01-27-11-16-59.bpo-45173.wreRF2.rst deleted file mode 100644 index ee5a88f621498..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-27-11-16-59.bpo-45173.wreRF2.rst +++ /dev/null @@ -1 +0,0 @@ -Note the configparser deprecations will be removed in Python 3.12. diff --git a/Misc/NEWS.d/next/Library/2022-01-27-12-24-38.bpo-46487.UDkN2z.rst b/Misc/NEWS.d/next/Library/2022-01-27-12-24-38.bpo-46487.UDkN2z.rst deleted file mode 100644 index adbc50a4bf9b7..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-27-12-24-38.bpo-46487.UDkN2z.rst +++ /dev/null @@ -1 +0,0 @@ -Add the ``get_write_buffer_limits`` method to :class:`asyncio.transports.WriteTransport` and to the SSL transport. diff --git a/Misc/NEWS.d/next/Library/2022-01-30-15-16-12.bpo-46400.vweUiO.rst b/Misc/NEWS.d/next/Library/2022-01-30-15-16-12.bpo-46400.vweUiO.rst deleted file mode 100644 index 9c1f24c0e5171..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-30-15-16-12.bpo-46400.vweUiO.rst +++ /dev/null @@ -1 +0,0 @@ -expat: Update libexpat from 2.4.1 to 2.4.4 diff --git a/Misc/NEWS.d/next/Library/2022-01-31-15-40-38.bpo-46591.prBD1M.rst b/Misc/NEWS.d/next/Library/2022-01-31-15-40-38.bpo-46591.prBD1M.rst deleted file mode 100644 index 7785faa1c4cbf..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-31-15-40-38.bpo-46591.prBD1M.rst +++ /dev/null @@ -1 +0,0 @@ -Make the IDLE doc URL on the About IDLE dialog clickable. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2022-02-01-11-32-47.bpo-46581.t7Zw65.rst b/Misc/NEWS.d/next/Library/2022-02-01-11-32-47.bpo-46581.t7Zw65.rst deleted file mode 100644 index 1982c1d70093f..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-01-11-32-47.bpo-46581.t7Zw65.rst +++ /dev/null @@ -1,2 +0,0 @@ -Brings :class:`ParamSpec` propagation for :class:`GenericAlias` in line with -:class:`Concatenate` (and others). diff --git a/Misc/NEWS.d/next/Library/2022-02-01-19-34-28.bpo-46521.IMUIrs.rst b/Misc/NEWS.d/next/Library/2022-02-01-19-34-28.bpo-46521.IMUIrs.rst deleted file mode 100644 index 4e9fa08d4dfbc..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-01-19-34-28.bpo-46521.IMUIrs.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a bug in the :mod:`codeop` module that was incorrectly identifying -invalid code involving string quotes as valid code. diff --git a/Misc/NEWS.d/next/Library/2022-02-05-18-22-05.bpo-45948.w4mCnE.rst b/Misc/NEWS.d/next/Library/2022-02-05-18-22-05.bpo-45948.w4mCnE.rst deleted file mode 100644 index 42dc114b5ad60..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-05-18-22-05.bpo-45948.w4mCnE.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fixed a discrepancy in the C implementation of the -:mod:`xml.etree.ElementTree` module. Now, instantiating an -:class:`xml.etree.ElementTree.XMLParser` with a ``target=None`` -keyword provides a default :class:`xml.etree.ElementTree.TreeBuilder` -target as the Python implementation does. diff --git a/Misc/NEWS.d/next/Library/2022-02-06-08-54-03.bpo-46655.DiLzYv.rst b/Misc/NEWS.d/next/Library/2022-02-06-08-54-03.bpo-46655.DiLzYv.rst deleted file mode 100644 index 4f0de9519a00e..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-06-08-54-03.bpo-46655.DiLzYv.rst +++ /dev/null @@ -1 +0,0 @@ -In :func:`typing.get_type_hints`, support evaluating bare stringified ``TypeAlias`` annotations. Patch by Gregory Beauregard. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2022-02-07-13-15-16.bpo-46672.4swIjx.rst b/Misc/NEWS.d/next/Library/2022-02-07-13-15-16.bpo-46672.4swIjx.rst deleted file mode 100644 index 9a76c29a334d8..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-07-13-15-16.bpo-46672.4swIjx.rst +++ /dev/null @@ -1 +0,0 @@ -Fix ``NameError`` in :func:`asyncio.gather` when initial type check fails. diff --git a/Misc/NEWS.d/next/Library/2022-02-07-19-20-42.bpo-46676.3Aws1o.rst b/Misc/NEWS.d/next/Library/2022-02-07-19-20-42.bpo-46676.3Aws1o.rst deleted file mode 100644 index 408412e6ff15d..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-07-19-20-42.bpo-46676.3Aws1o.rst +++ /dev/null @@ -1 +0,0 @@ -Make :data:`typing.ParamSpec` args and kwargs equal to themselves. Patch by Gregory Beauregard. diff --git a/Misc/NEWS.d/next/Library/2022-02-09-00-53-23.bpo-45863.zqQXVv.rst b/Misc/NEWS.d/next/Library/2022-02-09-00-53-23.bpo-45863.zqQXVv.rst deleted file mode 100644 index 3a1335cc77b9d..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-09-00-53-23.bpo-45863.zqQXVv.rst +++ /dev/null @@ -1 +0,0 @@ -When the :mod:`tarfile` module creates a pax format archive, it will put an integer representation of timestamps in the ustar header (if possible) for the benefit of older unarchivers, in addition to the existing full-precision timestamps in the pax extended header. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2022-02-09-22-40-11.bpo-46643.aBlIx1.rst b/Misc/NEWS.d/next/Library/2022-02-09-22-40-11.bpo-46643.aBlIx1.rst deleted file mode 100644 index e8b4d66e943f6..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-09-22-40-11.bpo-46643.aBlIx1.rst +++ /dev/null @@ -1 +0,0 @@ -In :func:`typing.get_type_hints`, support evaluating stringified ``ParamSpecArgs`` and ``ParamSpecKwargs`` annotations. Patch by Gregory Beauregard. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2022-02-15-11-57-53.bpo-46756.AigSPi.rst b/Misc/NEWS.d/next/Library/2022-02-15-11-57-53.bpo-46756.AigSPi.rst deleted file mode 100644 index 1660640c5d3fb..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-15-11-57-53.bpo-46756.AigSPi.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fix a bug in :meth:`urllib.request.HTTPPasswordMgr.find_user_password` and -:meth:`urllib.request.HTTPPasswordMgrWithPriorAuth.is_authenticated` which -allowed to bypass authorization. For example, access to URI -``example.org/foobar`` was allowed if the user was authorized for URI -``example.org/foo``. diff --git a/Misc/NEWS.d/next/Library/2022-02-17-13-10-50.bpo-39327.ytIT7Z.rst b/Misc/NEWS.d/next/Library/2022-02-17-13-10-50.bpo-39327.ytIT7Z.rst deleted file mode 100644 index fc6e8250922ff..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-17-13-10-50.bpo-39327.ytIT7Z.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`shutil.rmtree` can now work with VirtualBox shared folders when -running from the guest operating-system. diff --git a/Misc/NEWS.d/next/Library/2022-02-18-22-10-30.bpo-46784.SVOQJx.rst b/Misc/NEWS.d/next/Library/2022-02-18-22-10-30.bpo-46784.SVOQJx.rst deleted file mode 100644 index d190816637ae8..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-18-22-10-30.bpo-46784.SVOQJx.rst +++ /dev/null @@ -1 +0,0 @@ -Fix libexpat symbols collisions with user dynamically loaded or statically linked libexpat in embedded Python. diff --git a/Misc/NEWS.d/next/Library/2022-02-20-12-59-46.bpo-46252.KG1SqA.rst b/Misc/NEWS.d/next/Library/2022-02-20-12-59-46.bpo-46252.KG1SqA.rst deleted file mode 100644 index a15e7aaaa3389..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-20-12-59-46.bpo-46252.KG1SqA.rst +++ /dev/null @@ -1,2 +0,0 @@ -Raise :exc:`TypeError` if :class:`ssl.SSLSocket` is passed to -transport-based APIs. diff --git a/Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst b/Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst deleted file mode 100644 index 6969bd1898f65..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst +++ /dev/null @@ -1 +0,0 @@ -Make test suite support Expat >=2.4.5 diff --git a/Misc/NEWS.d/next/Library/2022-02-22-15-08-30.bpo-46827.hvj38S.rst b/Misc/NEWS.d/next/Library/2022-02-22-15-08-30.bpo-46827.hvj38S.rst deleted file mode 100644 index 259686ab1ddda..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-22-15-08-30.bpo-46827.hvj38S.rst +++ /dev/null @@ -1 +0,0 @@ -Support UDP sockets in :meth:`asyncio.loop.sock_connect` for selector-based event loops. Patch by Thomas Grainger. diff --git a/Misc/NEWS.d/next/Library/2022-02-23-00-55-59.bpo-44886.I40Mbr.rst b/Misc/NEWS.d/next/Library/2022-02-23-00-55-59.bpo-44886.I40Mbr.rst deleted file mode 100644 index be223ddd58ba1..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-23-00-55-59.bpo-44886.I40Mbr.rst +++ /dev/null @@ -1,2 +0,0 @@ -Inherit asyncio proactor datagram transport from -:class:`asyncio.DatagramTransport`. diff --git a/Misc/NEWS.d/next/Library/2022-03-05-09-43-53.bpo-25707.gTlclP.rst b/Misc/NEWS.d/next/Library/2022-03-05-09-43-53.bpo-25707.gTlclP.rst deleted file mode 100644 index a59f0a7657ff2..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-05-09-43-53.bpo-25707.gTlclP.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fixed a file leak in :func:`xml.etree.ElementTree.iterparse` when the -iterator is not exhausted. Patch by Jacob Walls. diff --git a/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst b/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst deleted file mode 100644 index 8545c656eab89..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst +++ /dev/null @@ -1 +0,0 @@ -Update bundled libexpat to 2.4.7 diff --git a/Misc/NEWS.d/next/Library/2022-03-08-11-34-06.bpo-23325.3VQnfo.rst b/Misc/NEWS.d/next/Library/2022-03-08-11-34-06.bpo-23325.3VQnfo.rst deleted file mode 100644 index 0801cbb448225..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-08-11-34-06.bpo-23325.3VQnfo.rst +++ /dev/null @@ -1,2 +0,0 @@ -The :mod:`signal` module no longer assumes that :const:`~signal.SIG_IGN` and -:const:`~signal.SIG_DFL` are small int singletons. diff --git a/Misc/NEWS.d/next/Library/2022-03-08-22-41-59.bpo-46955.IOoonN.rst b/Misc/NEWS.d/next/Library/2022-03-08-22-41-59.bpo-46955.IOoonN.rst deleted file mode 100644 index 75fee1240d3cd..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-08-22-41-59.bpo-46955.IOoonN.rst +++ /dev/null @@ -1,2 +0,0 @@ -Expose :class:`asyncio.base_events.Server` as :class:`asyncio.Server`. Patch -by Stefan Zabka. diff --git a/Misc/NEWS.d/next/Library/2022-03-10-14-51-11.bpo-46968.ym2QxL.rst b/Misc/NEWS.d/next/Library/2022-03-10-14-51-11.bpo-46968.ym2QxL.rst deleted file mode 100644 index 0da5ae76572ba..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-10-14-51-11.bpo-46968.ym2QxL.rst +++ /dev/null @@ -1,5 +0,0 @@ -:mod:`faulthandler`: On Linux 5.14 and newer, dynamically determine size of -signal handler stack size CPython allocates using ``getauxval(AT_MINSIGSTKSZ)``. -This changes allows for Python extension's request to Linux kernel to use -AMX_TILE instruction set on Sapphire Rapids Xeon processor to succeed, -unblocking use of the ISA in frameworks. diff --git a/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst b/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst deleted file mode 100644 index 2e08ee837f583..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst +++ /dev/null @@ -1 +0,0 @@ -Upgrade pip wheel bundled with ensurepip (pip 22.0.4) diff --git a/Misc/NEWS.d/next/Library/2022-03-13-15-04-05.bpo-47004.SyYpxd.rst b/Misc/NEWS.d/next/Library/2022-03-13-15-04-05.bpo-47004.SyYpxd.rst deleted file mode 100644 index 3cb3b212d89e9..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-13-15-04-05.bpo-47004.SyYpxd.rst +++ /dev/null @@ -1,3 +0,0 @@ -Apply bugfixes from importlib_metadata 4.11.3, including bugfix for -EntryPoint.extras, which was returning match objects and not the extras -strings. diff --git a/Misc/NEWS.d/next/Library/2022-03-15-07-53-45.bpo-43253.rjdLFj.rst b/Misc/NEWS.d/next/Library/2022-03-15-07-53-45.bpo-43253.rjdLFj.rst deleted file mode 100644 index b9920cb821b35..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-15-07-53-45.bpo-43253.rjdLFj.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a crash when closing transports where the underlying socket handle is already invalid on the Proactor event loop. diff --git a/Misc/NEWS.d/next/Tests/2022-01-17-13-10-04.bpo-13886.5mZH4b.rst b/Misc/NEWS.d/next/Tests/2022-01-17-13-10-04.bpo-13886.5mZH4b.rst deleted file mode 100644 index cd19dce37d5c8..0000000000000 --- a/Misc/NEWS.d/next/Tests/2022-01-17-13-10-04.bpo-13886.5mZH4b.rst +++ /dev/null @@ -1,3 +0,0 @@ -Skip test_builtin PTY tests on non-ASCII characters if the readline module -is loaded. The readline module changes input() behavior, but test_builtin is -not intented to test the readline module. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Tests/2022-01-28-01-17-10.bpo-46542.xRLTdj.rst b/Misc/NEWS.d/next/Tests/2022-01-28-01-17-10.bpo-46542.xRLTdj.rst deleted file mode 100644 index c6b64ce017b6c..0000000000000 --- a/Misc/NEWS.d/next/Tests/2022-01-28-01-17-10.bpo-46542.xRLTdj.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix ``test_json`` tests checking for :exc:`RecursionError`: modify these tests -to use ``support.infinite_recursion()``. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Tests/2022-01-29-12-37-53.bpo-46576.-prRaV.rst b/Misc/NEWS.d/next/Tests/2022-01-29-12-37-53.bpo-46576.-prRaV.rst deleted file mode 100644 index be50fc8cbe0a5..0000000000000 --- a/Misc/NEWS.d/next/Tests/2022-01-29-12-37-53.bpo-46576.-prRaV.rst +++ /dev/null @@ -1,3 +0,0 @@ -test_peg_generator now disables compiler optimization when testing -compilation of its own C extensions to significantly speed up the -testing on non-debug builds of CPython. diff --git a/Misc/NEWS.d/next/Tests/2022-01-31-17-34-13.bpo-46542.RTMm1T.rst b/Misc/NEWS.d/next/Tests/2022-01-31-17-34-13.bpo-46542.RTMm1T.rst deleted file mode 100644 index 5596498724930..0000000000000 --- a/Misc/NEWS.d/next/Tests/2022-01-31-17-34-13.bpo-46542.RTMm1T.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a Python crash in test_lib2to3 when using Python built in debug mode: -limit the recursion limit. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Tests/2022-02-02-02-24-04.bpo-44359.kPPSmN.rst b/Misc/NEWS.d/next/Tests/2022-02-02-02-24-04.bpo-44359.kPPSmN.rst deleted file mode 100644 index 00c29b1ca4089..0000000000000 --- a/Misc/NEWS.d/next/Tests/2022-02-02-02-24-04.bpo-44359.kPPSmN.rst +++ /dev/null @@ -1,2 +0,0 @@ -test_ftplib now silently ignores socket errors to prevent logging unhandled -threading exceptions. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Tests/2022-02-02-18-14-38.bpo-46616.URvBtE.rst b/Misc/NEWS.d/next/Tests/2022-02-02-18-14-38.bpo-46616.URvBtE.rst deleted file mode 100644 index 31c63c3d8f181..0000000000000 --- a/Misc/NEWS.d/next/Tests/2022-02-02-18-14-38.bpo-46616.URvBtE.rst +++ /dev/null @@ -1,2 +0,0 @@ -Ensures ``test_importlib.test_windows`` cleans up registry keys after -completion. diff --git a/Misc/NEWS.d/next/Tests/2022-02-07-12-40-45.bpo-46678.zfOrgL.rst b/Misc/NEWS.d/next/Tests/2022-02-07-12-40-45.bpo-46678.zfOrgL.rst deleted file mode 100644 index e369cb1f67baf..0000000000000 --- a/Misc/NEWS.d/next/Tests/2022-02-07-12-40-45.bpo-46678.zfOrgL.rst +++ /dev/null @@ -1,3 +0,0 @@ -The function ``make_legacy_pyc`` in ``Lib/test/support/import_helper.py`` no -longer fails when ``PYTHONPYCACHEPREFIX`` is set to a directory on a -different device from where tempfiles are stored. diff --git a/Misc/NEWS.d/next/Tests/2022-02-10-14-33-47.bpo-46708.avLfCb.rst b/Misc/NEWS.d/next/Tests/2022-02-10-14-33-47.bpo-46708.avLfCb.rst deleted file mode 100644 index 119107a8fb96c..0000000000000 --- a/Misc/NEWS.d/next/Tests/2022-02-10-14-33-47.bpo-46708.avLfCb.rst +++ /dev/null @@ -1,2 +0,0 @@ -Prevent default asyncio event loop policy modification warning after -``test_asyncio`` execution. diff --git a/Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst b/Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst deleted file mode 100644 index 65fed1c249d87..0000000000000 --- a/Misc/NEWS.d/next/Tests/2022-03-03-17-36-24.bpo-46913.vxETIE.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix test_faulthandler.test_sigfpe() if Python is built with undefined -behavior sanitizer (UBSAN): disable UBSAN on the faulthandler_sigfpe() -function. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/next/Windows/2022-02-04-18-02-33.bpo-46638.mSJOSX.rst b/Misc/NEWS.d/next/Windows/2022-02-04-18-02-33.bpo-46638.mSJOSX.rst deleted file mode 100644 index 536aae68f8329..0000000000000 --- a/Misc/NEWS.d/next/Windows/2022-02-04-18-02-33.bpo-46638.mSJOSX.rst +++ /dev/null @@ -1,4 +0,0 @@ -Ensures registry virtualization is consistently disabled. For 3.10 and -earlier, it remains enabled (some registry writes are protected), while for -3.11 and later it is disabled (registry modifications affect all -applications). diff --git a/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst b/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst deleted file mode 100644 index cfc4827882ded..0000000000000 --- a/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst +++ /dev/null @@ -1,2 +0,0 @@ -Prevent CVE-2022-26488 by ensuring the Add to PATH option in the Windows -installer uses the correct path when being repaired. diff --git a/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst b/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst deleted file mode 100644 index 0f1ef9af6c617..0000000000000 --- a/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst +++ /dev/null @@ -1,2 +0,0 @@ -Update bzip2 to 1.0.8 in Windows builds to mitigate CVE-2016-3189 and -CVE-2019-12900 diff --git a/Misc/NEWS.d/next/macOS/2022-01-26-12-04-09.bpo-45925.yBSiYO.rst b/Misc/NEWS.d/next/macOS/2022-01-26-12-04-09.bpo-45925.yBSiYO.rst deleted file mode 100644 index 3705266c154b7..0000000000000 --- a/Misc/NEWS.d/next/macOS/2022-01-26-12-04-09.bpo-45925.yBSiYO.rst +++ /dev/null @@ -1 +0,0 @@ -Update macOS installer to SQLite 3.37.2. \ No newline at end of file diff --git a/README.rst b/README.rst index ae35928628bb0..9b708f10a2f71 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -This is Python version 3.10.2 +This is Python version 3.10.3 ============================= .. image:: https://travis-ci.com/python/cpython.svg?branch=master From webhook-mailer at python.org Wed Mar 16 11:02:03 2022 From: webhook-mailer at python.org (asvetlov) Date: Wed, 16 Mar 2022 15:02:03 -0000 Subject: [Python-checkins] Rewrite asyncio.Queue tests with IsolatedAsyncioTestCace (#31935) Message-ID: https://github.com/python/cpython/commit/e707ceb6e464b24ddc9fdbdac7bfe15f7eeb43fd commit: e707ceb6e464b24ddc9fdbdac7bfe15f7eeb43fd branch: main author: Andrew Svetlov committer: asvetlov date: 2022-03-16T16:59:12+02:00 summary: Rewrite asyncio.Queue tests with IsolatedAsyncioTestCace (#31935) files: M Lib/test/test_asyncio/test_queues.py diff --git a/Lib/test/test_asyncio/test_queues.py b/Lib/test/test_asyncio/test_queues.py index b1a53b859c5cc..55588e8b729e1 100644 --- a/Lib/test/test_asyncio/test_queues.py +++ b/Lib/test/test_asyncio/test_queues.py @@ -1,118 +1,94 @@ """Tests for queues.py""" -import unittest import asyncio +import unittest from types import GenericAlias -from test.test_asyncio import utils as test_utils def tearDownModule(): asyncio.set_event_loop_policy(None) -class _QueueTestBase(test_utils.TestCase): - - def setUp(self): - super().setUp() - self.loop = self.new_test_loop() +class QueueBasicTests(unittest.IsolatedAsyncioTestCase): - -class QueueBasicTests(_QueueTestBase): - - def _test_repr_or_str(self, fn, expect_id): + async def _test_repr_or_str(self, fn, expect_id): """Test Queue's repr or str. fn is repr or str. expect_id is True if we expect the Queue's id to appear in fn(Queue()). """ - def gen(): - when = yield - self.assertAlmostEqual(0.1, when) - when = yield 0.1 - self.assertAlmostEqual(0.2, when) - yield 0.1 - - loop = self.new_test_loop(gen) - q = asyncio.Queue() self.assertTrue(fn(q).startswith(' https://github.com/python/cpython/commit/2de452f8bf2f78417e04bcf7919beb502c53a0e2 commit: 2de452f8bf2f78417e04bcf7919beb502c53a0e2 branch: 3.9 author: ?ukasz Langa committer: ambv date: 2022-03-16T14:03:13+01:00 summary: Python 3.9.11, take two files: D Misc/NEWS.d/next/Build/2022-03-16-00-37-40.bpo-47032.tsS9KE.rst M Include/patchlevel.h M Misc/NEWS.d/3.9.11.rst diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 10792996992af..bf343ad960b8c 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -23,7 +23,7 @@ #define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "3.9.11+" +#define PY_VERSION "3.9.11" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Misc/NEWS.d/3.9.11.rst b/Misc/NEWS.d/3.9.11.rst index 5efbb4bfc6db9..b25cbe95dbfdb 100644 --- a/Misc/NEWS.d/3.9.11.rst +++ b/Misc/NEWS.d/3.9.11.rst @@ -1,7 +1,7 @@ .. bpo: 46852 .. date: 2022-02-25-02-01-42 .. nonce: _3zg8D -.. release date: 2022-03-15 +.. release date: 2022-03-16 .. section: Core and Builtins Rename the private undocumented ``float.__set_format__()`` method to @@ -601,6 +601,16 @@ Update Windows installer to use SQLite 3.37.2. .. +.. bpo: 47032 +.. date: 2022-03-16-00-37-40 +.. nonce: tsS9KE +.. section: Build + +Ensure Windows install builds fail correctly with a non-zero exit code +when part of the build fails. + +.. + .. bpo: 44549 .. date: 2022-03-07-17-46-40 .. nonce: SPrGS9 diff --git a/Misc/NEWS.d/next/Build/2022-03-16-00-37-40.bpo-47032.tsS9KE.rst b/Misc/NEWS.d/next/Build/2022-03-16-00-37-40.bpo-47032.tsS9KE.rst deleted file mode 100644 index 4f2f1c8d0471a..0000000000000 --- a/Misc/NEWS.d/next/Build/2022-03-16-00-37-40.bpo-47032.tsS9KE.rst +++ /dev/null @@ -1,2 +0,0 @@ -Ensure Windows install builds fail correctly with a non-zero exit code when -part of the build fails. From webhook-mailer at python.org Wed Mar 16 11:26:24 2022 From: webhook-mailer at python.org (zooba) Date: Wed, 16 Mar 2022 15:26:24 -0000 Subject: [Python-checkins] Fix some Windows release build script issues (GH-31931) Message-ID: https://github.com/python/cpython/commit/d56a237e160b8e38fc9bd29c6be272b9d92eb67a commit: d56a237e160b8e38fc9bd29c6be272b9d92eb67a branch: main author: Steve Dower committer: zooba date: 2022-03-16T15:23:35Z summary: Fix some Windows release build script issues (GH-31931) * Fix the condition used when excluding ARM64 packages from publish * Do not publish anything unless the traditional installer works * Fix disabling of MSI build * Add override conditions for publish steps * Allow overriding the Nuget version number during build files: M .azure-pipelines/windows-release.yml M .azure-pipelines/windows-release/stage-pack-nuget.yml M .azure-pipelines/windows-release/stage-publish-nugetorg.yml M .azure-pipelines/windows-release/stage-publish-pythonorg.yml M .azure-pipelines/windows-release/stage-publish-store.yml diff --git a/.azure-pipelines/windows-release.yml b/.azure-pipelines/windows-release.yml index ae2d1b9da1321..096ecadc79eb7 100644 --- a/.azure-pipelines/windows-release.yml +++ b/.azure-pipelines/windows-release.yml @@ -136,69 +136,80 @@ stages: - template: windows-release/stage-test-embed.yml - template: windows-release/stage-test-nuget.yml - - stage: Layout_MSIX - displayName: Generate MSIX layouts - dependsOn: Sign - condition: and(succeeded(), eq(variables['DoMSIX'], 'true')) - jobs: - - template: windows-release/stage-layout-msix.yml - parameters: - ARM64TclTk: ${{ parameters.ARM64TclTk }} - - - stage: Pack_MSIX - displayName: Package MSIX - dependsOn: Layout_MSIX - jobs: - - template: windows-release/stage-pack-msix.yml - - - stage: Build_MSI - displayName: Build MSI installer - dependsOn: Sign - condition: and(succeeded(), eq(variables['DoMSI'], 'true')) - jobs: - - template: windows-release/stage-msi.yml - parameters: - ARM64TclTk: ${{ parameters.ARM64TclTk }} - - - stage: Test_MSI - displayName: Test MSI installer - dependsOn: Build_MSI - jobs: - - template: windows-release/stage-test-msi.yml + - ${{ if eq(parameters.DoMSIX, 'true') }}: + - stage: Layout_MSIX + displayName: Generate MSIX layouts + dependsOn: Sign + jobs: + - template: windows-release/stage-layout-msix.yml + parameters: + ARM64TclTk: ${{ parameters.ARM64TclTk }} - - ${{ if eq(parameters.DoPublish, 'true') }}: - - stage: PublishPyDotOrg - displayName: Publish to python.org - dependsOn: ['Test_MSI', 'Test'] + - stage: Pack_MSIX + displayName: Package MSIX + dependsOn: Layout_MSIX jobs: - - template: windows-release/stage-publish-pythonorg.yml + - template: windows-release/stage-pack-msix.yml - - stage: PublishNuget - displayName: Publish to nuget.org - dependsOn: Test + - ${{ if eq(parameters.DoMSI, 'true') }}: + - stage: Build_MSI + displayName: Build MSI installer + dependsOn: Sign jobs: - - template: windows-release/stage-publish-nugetorg.yml + - template: windows-release/stage-msi.yml + parameters: + ARM64TclTk: ${{ parameters.ARM64TclTk }} - - stage: PublishStore - displayName: Publish to Store - dependsOn: Pack_MSIX + - stage: Test_MSI + displayName: Test MSI installer + dependsOn: Build_MSI jobs: - - template: windows-release/stage-publish-store.yml + - template: windows-release/stage-test-msi.yml + + - ${{ if eq(parameters.DoPublish, 'true') }}: + - ${{ if eq(parameters.DoMSI, 'true') }}: + - stage: PublishPyDotOrg + displayName: Publish to python.org + dependsOn: ['Test_MSI', 'Test'] + jobs: + - template: windows-release/stage-publish-pythonorg.yml + + - ${{ if eq(parameters.DoNuget, 'true') }}: + - stage: PublishNuget + displayName: Publish to nuget.org + ${{ if eq(parameters.DoMSI, 'true') }}: + dependsOn: ['Test_MSI', 'Test'] + ${{ else }}: + dependsOn: 'Test' + jobs: + - template: windows-release/stage-publish-nugetorg.yml + + - ${{ if eq(parameters.DoMSIX, 'true') }}: + - stage: PublishStore + displayName: Publish to Store + ${{ if eq(parameters.DoMSI, 'true') }}: + dependsOn: ['Test_MSI', 'Pack_MSIX'] + ${{ else }}: + dependsOn: 'Pack_MSIX' + jobs: + - template: windows-release/stage-publish-store.yml - ${{ else }}: - stage: PublishExisting displayName: Publish existing build dependsOn: [] - condition: and(succeeded(), eq(variables['DoPublish'], 'true')) jobs: - - template: windows-release/stage-publish-pythonorg.yml - parameters: - BuildToPublish: ${{ parameters.BuildToPublish }} + - ${{ if eq(parameters.DoMSI, 'true') }}: + - template: windows-release/stage-publish-pythonorg.yml + parameters: + BuildToPublish: ${{ parameters.BuildToPublish }} - - template: windows-release/stage-publish-nugetorg.yml - parameters: - BuildToPublish: ${{ parameters.BuildToPublish }} + - ${{ if eq(parameters.DoNuget, 'true') }}: + - template: windows-release/stage-publish-nugetorg.yml + parameters: + BuildToPublish: ${{ parameters.BuildToPublish }} - - template: windows-release/stage-publish-store.yml - parameters: - BuildToPublish: ${{ parameters.BuildToPublish }} + - ${{ if eq(parameters.DoMSIX, 'true') }}: + - template: windows-release/stage-publish-store.yml + parameters: + BuildToPublish: ${{ parameters.BuildToPublish }} diff --git a/.azure-pipelines/windows-release/stage-pack-nuget.yml b/.azure-pipelines/windows-release/stage-pack-nuget.yml index 8dfea382c3562..85b44e389ab5d 100644 --- a/.azure-pipelines/windows-release/stage-pack-nuget.yml +++ b/.azure-pipelines/windows-release/stage-pack-nuget.yml @@ -32,8 +32,23 @@ jobs: inputs: versionSpec: '>=5.0' - - powershell: | - nuget pack "$(Build.BinariesDirectory)\layout\python.nuspec" -OutputDirectory $(Build.ArtifactStagingDirectory) -NoPackageAnalysis -NonInteractive + - powershell: > + nuget pack + "$(Build.BinariesDirectory)\layout\python.nuspec" + -OutputDirectory $(Build.ArtifactStagingDirectory) + -NoPackageAnalysis + -NonInteractive + condition: and(succeeded(), not(variables['OverrideNugetVersion'])) + displayName: 'Create nuget package' + + - powershell: > + nuget pack + "$(Build.BinariesDirectory)\layout\python.nuspec" + -OutputDirectory $(Build.ArtifactStagingDirectory) + -NoPackageAnalysis + -NonInteractive + -Version "$(OverrideNugetVersion)" + condition: and(succeeded(), variables['OverrideNugetVersion']) displayName: 'Create nuget package' - powershell: | diff --git a/.azure-pipelines/windows-release/stage-publish-nugetorg.yml b/.azure-pipelines/windows-release/stage-publish-nugetorg.yml index a8855f0ace8f5..abb9d0f0fd485 100644 --- a/.azure-pipelines/windows-release/stage-publish-nugetorg.yml +++ b/.azure-pipelines/windows-release/stage-publish-nugetorg.yml @@ -4,7 +4,7 @@ parameters: jobs: - job: Publish_Nuget displayName: Publish Nuget packages - condition: and(succeeded(), eq(variables['DoNuget'], 'true')) + condition: and(succeeded(), eq(variables['DoNuget'], 'true'), ne(variables['SkipNugetPublish'], 'true')) pool: vmImage: windows-2022 @@ -38,7 +38,7 @@ jobs: - powershell: 'gci pythonarm*.nupkg | %{ Write-Host "Not publishing: $($_.Name)"; gi $_ } | del' displayName: 'Prevent publishing ARM64 packages' workingDirectory: '$(Build.BinariesDirectory)\nuget' - condition: and(succeeded(), eq(variables['PublishARM64'], 'true')) + condition: and(succeeded(), ne(variables['PublishARM64'], 'true')) - task: NuGetCommand at 2 displayName: Push packages diff --git a/.azure-pipelines/windows-release/stage-publish-pythonorg.yml b/.azure-pipelines/windows-release/stage-publish-pythonorg.yml index be4ef9e0cca89..953f728ade381 100644 --- a/.azure-pipelines/windows-release/stage-publish-pythonorg.yml +++ b/.azure-pipelines/windows-release/stage-publish-pythonorg.yml @@ -4,7 +4,7 @@ parameters: jobs: - job: Publish_Python displayName: Publish python.org packages - condition: and(succeeded(), and(eq(variables['DoMSI'], 'true'), eq(variables['DoEmbed'], 'true'))) + condition: and(succeeded(), eq(variables['DoMSI'], 'true'), eq(variables['DoEmbed'], 'true'), ne(variables['SkipPythonOrgPublish'], 'true')) pool: #vmImage: windows-2022 @@ -81,7 +81,7 @@ jobs: - powershell: 'gci *embed-arm*.zip | %{ Write-Host "Not publishing: $($_.Name)"; gi $_ } | del' displayName: 'Prevent publishing ARM64 packages' workingDirectory: '$(Build.BinariesDirectory)\embed' - condition: and(succeeded(), eq(variables['PublishARM64'], 'true')) + condition: and(succeeded(), ne(variables['PublishARM64'], 'true')) - template: ./gpg-sign.yml diff --git a/.azure-pipelines/windows-release/stage-publish-store.yml b/.azure-pipelines/windows-release/stage-publish-store.yml index f3d4c80be9138..0eae21edaa7f8 100644 --- a/.azure-pipelines/windows-release/stage-publish-store.yml +++ b/.azure-pipelines/windows-release/stage-publish-store.yml @@ -4,7 +4,7 @@ parameters: jobs: - job: Publish_Store displayName: Publish Store packages - condition: and(succeeded(), eq(variables['DoMSIX'], 'true')) + condition: and(succeeded(), eq(variables['DoMSIX'], 'true'), ne(variables['SkipMSIXPublish'], 'true')) pool: vmImage: windows-2022 From webhook-mailer at python.org Wed Mar 16 11:31:38 2022 From: webhook-mailer at python.org (ned-deily) Date: Wed, 16 Mar 2022 15:31:38 -0000 Subject: [Python-checkins] 3.7.13 Message-ID: https://github.com/python/cpython/commit/000593c0f97ac9b75b56064a957b84a3aaa60674 commit: 000593c0f97ac9b75b56064a957b84a3aaa60674 branch: 3.7 author: Ned Deily committer: ned-deily date: 2022-03-16T09:27:21-04:00 summary: 3.7.13 files: A Misc/NEWS.d/3.7.13.rst D Misc/NEWS.d/next/Build/2021-10-11-16-27-38.bpo-45405.iSfdW5.rst D Misc/NEWS.d/next/Build/2022-03-15-11-53-10.bpo-47024.p3PjRy.rst D Misc/NEWS.d/next/Library/2022-02-15-11-57-53.bpo-46756.AigSPi.rst D Misc/NEWS.d/next/Library/2022-02-18-22-10-30.bpo-46784.SVOQJx.rst D Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst D Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst D Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst D Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst D Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst M Include/patchlevel.h M Lib/pydoc_data/topics.py M README.rst diff --git a/Include/patchlevel.h b/Include/patchlevel.h index dc9c74cc66fc6..a57783501e487 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -18,12 +18,12 @@ /*--start constants--*/ #define PY_MAJOR_VERSION 3 #define PY_MINOR_VERSION 7 -#define PY_MICRO_VERSION 12 +#define PY_MICRO_VERSION 13 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL #define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "3.7.12+" +#define PY_VERSION "3.7.13" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index f0e0f6db6e9e6..b532fec0d1b54 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Fri Sep 3 23:33:01 2021 +# Autogenerated by Sphinx on Wed Mar 16 09:24:05 2022 topics = {'assert': 'The "assert" statement\n' '**********************\n' '\n' diff --git a/Misc/NEWS.d/3.7.13.rst b/Misc/NEWS.d/3.7.13.rst new file mode 100644 index 0000000000000..c8d61cae97d9a --- /dev/null +++ b/Misc/NEWS.d/3.7.13.rst @@ -0,0 +1,87 @@ +.. bpo: 46985 +.. date: 2022-03-11-13-34-16 +.. nonce: BgoMr2 +.. release date: 2022-03-16 +.. section: Library + +Upgrade pip wheel bundled with ensurepip (pip 22.0.4) + +.. + +.. bpo: 46932 +.. date: 2022-03-07-20-20-34 +.. nonce: xbarAs +.. section: Library + +Update bundled libexpat to 2.4.7 + +.. + +.. bpo: 46811 +.. date: 2022-02-20-21-03-31 +.. nonce: 8BxgdQ +.. section: Library + +Make test suite support Expat >=2.4.5 + +.. + +.. bpo: 46784 +.. date: 2022-02-18-22-10-30 +.. nonce: SVOQJx +.. section: Library + +Fix libexpat symbols collisions with user dynamically loaded or statically +linked libexpat in embedded Python. + +.. + +.. bpo: 46756 +.. date: 2022-02-15-11-57-53 +.. nonce: AigSPi +.. section: Library + +Fix a bug in :meth:`urllib.request.HTTPPasswordMgr.find_user_password` and +:meth:`urllib.request.HTTPPasswordMgrWithPriorAuth.is_authenticated` which +allowed to bypass authorization. For example, access to URI +``example.org/foobar`` was allowed if the user was authorized for URI +``example.org/foo``. + +.. + +.. bpo: 47024 +.. date: 2022-03-15-11-53-10 +.. nonce: p3PjRy +.. section: Build + +Update Windows builds and macOS installer build to use OpenSSL 1.1.1n. + +.. + +.. bpo: 45405 +.. date: 2021-10-11-16-27-38 +.. nonce: iSfdW5 +.. section: Build + +Prevent ``internal configure error`` when running ``configure`` with recent +versions of clang. Patch by David Bohman. + +.. + +.. bpo: 44549 +.. date: 2022-03-07-17-46-40 +.. nonce: SPrGS9 +.. section: Windows + +Update bzip2 to 1.0.8 in Windows builds to mitigate CVE-2016-3189 and +CVE-2019-12900 + +.. + +.. bpo: 46948 +.. date: 2022-03-07-16-34-11 +.. nonce: Ufd4tG +.. section: Windows + +Prevent CVE-2022-26488 by ensuring the Add to PATH option in the Windows +installer uses the correct path when being repaired. diff --git a/Misc/NEWS.d/next/Build/2021-10-11-16-27-38.bpo-45405.iSfdW5.rst b/Misc/NEWS.d/next/Build/2021-10-11-16-27-38.bpo-45405.iSfdW5.rst deleted file mode 100644 index 13c93d1b8a571..0000000000000 --- a/Misc/NEWS.d/next/Build/2021-10-11-16-27-38.bpo-45405.iSfdW5.rst +++ /dev/null @@ -1,2 +0,0 @@ -Prevent ``internal configure error`` when running ``configure`` -with recent versions of clang. Patch by David Bohman. diff --git a/Misc/NEWS.d/next/Build/2022-03-15-11-53-10.bpo-47024.p3PjRy.rst b/Misc/NEWS.d/next/Build/2022-03-15-11-53-10.bpo-47024.p3PjRy.rst deleted file mode 100644 index 235ece3c3d2ef..0000000000000 --- a/Misc/NEWS.d/next/Build/2022-03-15-11-53-10.bpo-47024.p3PjRy.rst +++ /dev/null @@ -1 +0,0 @@ -Update Windows builds and macOS installer build to use OpenSSL 1.1.1n. diff --git a/Misc/NEWS.d/next/Library/2022-02-15-11-57-53.bpo-46756.AigSPi.rst b/Misc/NEWS.d/next/Library/2022-02-15-11-57-53.bpo-46756.AigSPi.rst deleted file mode 100644 index 1660640c5d3fb..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-15-11-57-53.bpo-46756.AigSPi.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fix a bug in :meth:`urllib.request.HTTPPasswordMgr.find_user_password` and -:meth:`urllib.request.HTTPPasswordMgrWithPriorAuth.is_authenticated` which -allowed to bypass authorization. For example, access to URI -``example.org/foobar`` was allowed if the user was authorized for URI -``example.org/foo``. diff --git a/Misc/NEWS.d/next/Library/2022-02-18-22-10-30.bpo-46784.SVOQJx.rst b/Misc/NEWS.d/next/Library/2022-02-18-22-10-30.bpo-46784.SVOQJx.rst deleted file mode 100644 index d190816637ae8..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-18-22-10-30.bpo-46784.SVOQJx.rst +++ /dev/null @@ -1 +0,0 @@ -Fix libexpat symbols collisions with user dynamically loaded or statically linked libexpat in embedded Python. diff --git a/Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst b/Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst deleted file mode 100644 index 6969bd1898f65..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst +++ /dev/null @@ -1 +0,0 @@ -Make test suite support Expat >=2.4.5 diff --git a/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst b/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst deleted file mode 100644 index 8545c656eab89..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-07-20-20-34.bpo-46932.xbarAs.rst +++ /dev/null @@ -1 +0,0 @@ -Update bundled libexpat to 2.4.7 diff --git a/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst b/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst deleted file mode 100644 index 2e08ee837f583..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-11-13-34-16.bpo-46985.BgoMr2.rst +++ /dev/null @@ -1 +0,0 @@ -Upgrade pip wheel bundled with ensurepip (pip 22.0.4) diff --git a/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst b/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst deleted file mode 100644 index cfc4827882ded..0000000000000 --- a/Misc/NEWS.d/next/Windows/2022-03-07-16-34-11.bpo-46948.Ufd4tG.rst +++ /dev/null @@ -1,2 +0,0 @@ -Prevent CVE-2022-26488 by ensuring the Add to PATH option in the Windows -installer uses the correct path when being repaired. diff --git a/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst b/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst deleted file mode 100644 index 0f1ef9af6c617..0000000000000 --- a/Misc/NEWS.d/next/Windows/2022-03-07-17-46-40.bpo-44549.SPrGS9.rst +++ /dev/null @@ -1,2 +0,0 @@ -Update bzip2 to 1.0.8 in Windows builds to mitigate CVE-2016-3189 and -CVE-2019-12900 diff --git a/README.rst b/README.rst index 5fa20143336f9..9a1af7f071422 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,5 @@ -This is Python version 3.7.12+ -============================== +This is Python version 3.7.13 +============================= .. image:: https://travis-ci.org/python/cpython.svg?branch=3.7 :alt: CPython build status on Travis CI From webhook-mailer at python.org Wed Mar 16 11:56:37 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Wed, 16 Mar 2022 15:56:37 -0000 Subject: [Python-checkins] bpo-46769: Improve documentation for `typing.TypeVar` (GH-31712) Message-ID: https://github.com/python/cpython/commit/81b425d4dc43b60dd11a3e9abc5c84a4b8b384db commit: 81b425d4dc43b60dd11a3e9abc5c84a4b8b384db branch: main author: Alex Waygood committer: JelleZijlstra date: 2022-03-16T08:51:26-07:00 summary: bpo-46769: Improve documentation for `typing.TypeVar` (GH-31712) Co-authored-by: Jelle Zijlstra files: M Doc/library/typing.rst diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 0c23a233c0d7d..c7c2cd6866b70 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -249,7 +249,7 @@ subscription to denote expected types for container elements. def notify_by_email(employees: Sequence[Employee], overrides: Mapping[str, str]) -> None: ... -Generics can be parameterized by using a new factory available in typing +Generics can be parameterized by using a factory available in typing called :class:`TypeVar`. :: @@ -306,16 +306,16 @@ that ``LoggedVar[t]`` is valid as a type:: for var in vars: var.set(0) -A generic type can have any number of type variables, and type variables may -be constrained:: +A generic type can have any number of type variables. All varieties of +:class:`TypeVar` are permissible as parameters for a generic type:: - from typing import TypeVar, Generic - ... + from typing import TypeVar, Generic, Sequence - T = TypeVar('T') + T = TypeVar('T', contravariant=True) + B = TypeVar('B', bound=Sequence[bytes], covariant=True) S = TypeVar('S', int, str) - class StrangePair(Generic[T, S]): + class WeirdTrio(Generic[T, B, S]): ... Each type variable argument to :class:`Generic` must be distinct. @@ -1165,7 +1165,8 @@ These are not used in annotations. They are building blocks for creating generic Usage:: T = TypeVar('T') # Can be anything - A = TypeVar('A', str, bytes) # Must be str or bytes + S = TypeVar('S', bound=str) # Can be any subtype of str + A = TypeVar('A', str, bytes) # Must be exactly str or bytes Type variables exist primarily for the benefit of static type checkers. They serve as the parameters for generic types as well @@ -1176,25 +1177,58 @@ These are not used in annotations. They are building blocks for creating generic """Return a list containing n references to x.""" return [x]*n - def longest(x: A, y: A) -> A: - """Return the longest of two strings.""" - return x if len(x) >= len(y) else y - The latter example's signature is essentially the overloading - of ``(str, str) -> str`` and ``(bytes, bytes) -> bytes``. Also note - that if the arguments are instances of some subclass of :class:`str`, - the return type is still plain :class:`str`. + def print_capitalized(x: S) -> S: + """Print x capitalized, and return x.""" + print(x.capitalize()) + return x + + + def concatenate(x: A, y: A) -> A: + """Add two strings or bytes objects together.""" + return x + y + + Note that type variables can be *bound*, *constrained*, or neither, but + cannot be both bound *and* constrained. + + Bound type variables and constrained type variables have different + semantics in several important ways. Using a *bound* type variable means + that the ``TypeVar`` will be solved using the most specific type possible:: + + x = print_capitalized('a string') + reveal_type(x) # revealed type is str + + class StringSubclass(str): + pass + + y = print_capitalized(StringSubclass('another string')) + reveal_type(y) # revealed type is StringSubclass + + z = print_capitalized(45) # error: int is not a subtype of str + + Type variables can be bound to concrete types, abstract types (ABCs or + protocols), and even unions of types:: + + U = TypeVar('U', bound=str|bytes) # Can be any subtype of the union str|bytes + V = TypeVar('V', bound=SupportsAbs) # Can be anything with an __abs__ method + + Using a *constrained* type variable, however, means that the ``TypeVar`` + can only ever be solved as being exactly one of the constraints given:: + + a = concatenate('one', 'two') + reveal_type(a) # revealed type is str + + b = concatenate(StringSubclass('one'), StringSubclass('two')) + reveal_type(b) # revealed type is str, despite StringSubclass being passed in + + c = concatenate('one', b'two') # error: type variable 'A' can be either str or bytes in a function call, but not both At runtime, ``isinstance(x, T)`` will raise :exc:`TypeError`. In general, :func:`isinstance` and :func:`issubclass` should not be used with types. Type variables may be marked covariant or contravariant by passing ``covariant=True`` or ``contravariant=True``. See :pep:`484` for more - details. By default type variables are invariant. Alternatively, - a type variable may specify an upper bound using ``bound=``. - This means that an actual type substituted (explicitly or implicitly) - for the type variable must be a subclass of the boundary type, - see :pep:`484`. + details. By default, type variables are invariant. .. class:: ParamSpec(name, *, bound=None, covariant=False, contravariant=False) @@ -1296,7 +1330,7 @@ These are not used in annotations. They are building blocks for creating generic .. data:: AnyStr - ``AnyStr`` is a type variable defined as + ``AnyStr`` is a :class:`constrained type variable ` defined as ``AnyStr = TypeVar('AnyStr', str, bytes)``. It is meant to be used for functions that may accept any kind of string From webhook-mailer at python.org Wed Mar 16 13:39:23 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Wed, 16 Mar 2022 17:39:23 -0000 Subject: [Python-checkins] bpo-45979: Fix Tkinter tests with old Tk (>= 8.5.12) (GH-31938) Message-ID: https://github.com/python/cpython/commit/dbbe4d2d0075fa0e95b069fb4780d79aae3514c7 commit: dbbe4d2d0075fa0e95b069fb4780d79aae3514c7 branch: main author: Serhiy Storchaka committer: serhiy-storchaka date: 2022-03-16T19:39:00+02:00 summary: bpo-45979: Fix Tkinter tests with old Tk (>= 8.5.12) (GH-31938) files: M Lib/tkinter/test/test_tkinter/test_widgets.py M Lib/tkinter/test/test_ttk/test_style.py diff --git a/Lib/tkinter/test/test_tkinter/test_widgets.py b/Lib/tkinter/test/test_tkinter/test_widgets.py index cc227e579679b..c0b92bf3b1921 100644 --- a/Lib/tkinter/test/test_tkinter/test_widgets.py +++ b/Lib/tkinter/test/test_tkinter/test_widgets.py @@ -800,7 +800,7 @@ def test_configure_activestyle(self): self.checkEnumParam(widget, 'activestyle', 'dotbox', 'none', 'underline') - test_justify = requires_tcl(8, 6, 5)(StandardOptionsTests.test_configure_justify) + test_configure_justify = requires_tcl(8, 6, 5)(StandardOptionsTests.test_configure_justify) def test_configure_listvariable(self): widget = self.create() @@ -939,7 +939,7 @@ def test_configure_digits(self): def test_configure_from(self): widget = self.create() - conv = False if get_tk_patchlevel() >= (8, 6, 10) else float_round + conv = float if get_tk_patchlevel() >= (8, 6, 10) else float_round self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=conv) def test_configure_label(self): diff --git a/Lib/tkinter/test/test_ttk/test_style.py b/Lib/tkinter/test/test_ttk/test_style.py index a33c24ac55bee..54ad3437168fe 100644 --- a/Lib/tkinter/test/test_ttk/test_style.py +++ b/Lib/tkinter/test/test_ttk/test_style.py @@ -4,7 +4,7 @@ from tkinter import ttk from test import support from test.support import requires -from tkinter.test.support import AbstractTkTest +from tkinter.test.support import AbstractTkTest, get_tk_patchlevel requires('gui') @@ -170,6 +170,8 @@ def test_map_custom_copy(self): newname = f'C.{name}' self.assertEqual(style.map(newname), {}) style.map(newname, **default) + if theme == 'alt' and name == '.' and get_tk_patchlevel() < (8, 6, 1): + default['embossed'] = [('disabled', '1')] self.assertEqual(style.map(newname), default) for key, value in default.items(): self.assertEqual(style.map(newname, key), value) From webhook-mailer at python.org Wed Mar 16 15:49:23 2022 From: webhook-mailer at python.org (asvetlov) Date: Wed, 16 Mar 2022 19:49:23 -0000 Subject: [Python-checkins] bpo-47038: Rewrite asyncio.wait_for test to use IsolatedAsyncioTestCase (GH-31942) Message-ID: https://github.com/python/cpython/commit/dd0082c627713634c7fd88ad33d18b5cc9f4a7b8 commit: dd0082c627713634c7fd88ad33d18b5cc9f4a7b8 branch: main author: Andrew Svetlov committer: asvetlov date: 2022-03-16T21:49:18+02:00 summary: bpo-47038: Rewrite asyncio.wait_for test to use IsolatedAsyncioTestCase (GH-31942) files: A Lib/test/test_asyncio/test_waitfor.py D Lib/test/test_asyncio/test_asyncio_waitfor.py M Lib/test/test_asyncio/test_tasks.py diff --git a/Lib/test/test_asyncio/test_asyncio_waitfor.py b/Lib/test/test_asyncio/test_asyncio_waitfor.py deleted file mode 100644 index 2ca64abbeb527..0000000000000 --- a/Lib/test/test_asyncio/test_asyncio_waitfor.py +++ /dev/null @@ -1,61 +0,0 @@ -import asyncio -import unittest -import time - -def tearDownModule(): - asyncio.set_event_loop_policy(None) - - -class SlowTask: - """ Task will run for this defined time, ignoring cancel requests """ - TASK_TIMEOUT = 0.2 - - def __init__(self): - self.exited = False - - async def run(self): - exitat = time.monotonic() + self.TASK_TIMEOUT - - while True: - tosleep = exitat - time.monotonic() - if tosleep <= 0: - break - - try: - await asyncio.sleep(tosleep) - except asyncio.CancelledError: - pass - - self.exited = True - -class AsyncioWaitForTest(unittest.TestCase): - - async def atest_asyncio_wait_for_cancelled(self): - t = SlowTask() - - waitfortask = asyncio.create_task(asyncio.wait_for(t.run(), t.TASK_TIMEOUT * 2)) - await asyncio.sleep(0) - waitfortask.cancel() - await asyncio.wait({waitfortask}) - - self.assertTrue(t.exited) - - def test_asyncio_wait_for_cancelled(self): - asyncio.run(self.atest_asyncio_wait_for_cancelled()) - - async def atest_asyncio_wait_for_timeout(self): - t = SlowTask() - - try: - await asyncio.wait_for(t.run(), t.TASK_TIMEOUT / 2) - except asyncio.TimeoutError: - pass - - self.assertTrue(t.exited) - - def test_asyncio_wait_for_timeout(self): - asyncio.run(self.atest_asyncio_wait_for_timeout()) - - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index b6ef62725166d..44ec8425b7f80 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -84,12 +84,6 @@ def __await__(self): return self -# The following value can be used as a very small timeout: -# it passes check "timeout > 0", but has almost -# no effect on the test performance -_EPSILON = 0.0001 - - class BaseTaskTests: Task = None @@ -107,7 +101,6 @@ def setUp(self): self.loop.set_task_factory(self.new_task) self.loop.create_future = lambda: self.new_future(self.loop) - def test_generic_alias(self): task = self.__class__.Task[str] self.assertEqual(task.__args__, (str,)) @@ -971,251 +964,6 @@ async def coro(): task._log_traceback = True self.loop.run_until_complete(task) - def test_wait_for_timeout_less_then_0_or_0_future_done(self): - def gen(): - when = yield - self.assertAlmostEqual(0, when) - - loop = self.new_test_loop(gen) - - fut = self.new_future(loop) - fut.set_result('done') - - ret = loop.run_until_complete(asyncio.wait_for(fut, 0)) - - self.assertEqual(ret, 'done') - self.assertTrue(fut.done()) - self.assertAlmostEqual(0, loop.time()) - - def test_wait_for_timeout_less_then_0_or_0_coroutine_do_not_started(self): - def gen(): - when = yield - self.assertAlmostEqual(0, when) - - loop = self.new_test_loop(gen) - - foo_started = False - - async def foo(): - nonlocal foo_started - foo_started = True - - with self.assertRaises(asyncio.TimeoutError): - loop.run_until_complete(asyncio.wait_for(foo(), 0)) - - self.assertAlmostEqual(0, loop.time()) - self.assertEqual(foo_started, False) - - def test_wait_for_timeout_less_then_0_or_0(self): - def gen(): - when = yield - self.assertAlmostEqual(0.2, when) - when = yield 0 - self.assertAlmostEqual(0, when) - - for timeout in [0, -1]: - with self.subTest(timeout=timeout): - loop = self.new_test_loop(gen) - - foo_running = None - - async def foo(): - nonlocal foo_running - foo_running = True - try: - await asyncio.sleep(0.2) - finally: - foo_running = False - return 'done' - - fut = self.new_task(loop, foo()) - - with self.assertRaises(asyncio.TimeoutError): - loop.run_until_complete(asyncio.wait_for(fut, timeout)) - self.assertTrue(fut.done()) - # it should have been cancelled due to the timeout - self.assertTrue(fut.cancelled()) - self.assertAlmostEqual(0, loop.time()) - self.assertEqual(foo_running, False) - - def test_wait_for(self): - - def gen(): - when = yield - self.assertAlmostEqual(0.2, when) - when = yield 0 - self.assertAlmostEqual(0.1, when) - when = yield 0.1 - - loop = self.new_test_loop(gen) - - foo_running = None - - async def foo(): - nonlocal foo_running - foo_running = True - try: - await asyncio.sleep(0.2) - finally: - foo_running = False - return 'done' - - fut = self.new_task(loop, foo()) - - with self.assertRaises(asyncio.TimeoutError): - loop.run_until_complete(asyncio.wait_for(fut, 0.1)) - self.assertTrue(fut.done()) - # it should have been cancelled due to the timeout - self.assertTrue(fut.cancelled()) - self.assertAlmostEqual(0.1, loop.time()) - self.assertEqual(foo_running, False) - - def test_wait_for_blocking(self): - loop = self.new_test_loop() - - async def coro(): - return 'done' - - res = loop.run_until_complete(asyncio.wait_for(coro(), timeout=None)) - self.assertEqual(res, 'done') - - def test_wait_for_race_condition(self): - - def gen(): - yield 0.1 - yield 0.1 - yield 0.1 - - loop = self.new_test_loop(gen) - - fut = self.new_future(loop) - task = asyncio.wait_for(fut, timeout=0.2) - loop.call_later(0.1, fut.set_result, "ok") - res = loop.run_until_complete(task) - self.assertEqual(res, "ok") - - def test_wait_for_cancellation_race_condition(self): - async def inner(): - with contextlib.suppress(asyncio.CancelledError): - await asyncio.sleep(1) - return 1 - - async def main(): - result = await asyncio.wait_for(inner(), timeout=.01) - self.assertEqual(result, 1) - - asyncio.run(main()) - - def test_wait_for_waits_for_task_cancellation(self): - loop = asyncio.new_event_loop() - self.addCleanup(loop.close) - - task_done = False - - async def foo(): - async def inner(): - nonlocal task_done - try: - await asyncio.sleep(0.2) - except asyncio.CancelledError: - await asyncio.sleep(_EPSILON) - raise - finally: - task_done = True - - inner_task = self.new_task(loop, inner()) - - await asyncio.wait_for(inner_task, timeout=_EPSILON) - - with self.assertRaises(asyncio.TimeoutError) as cm: - loop.run_until_complete(foo()) - - self.assertTrue(task_done) - chained = cm.exception.__context__ - self.assertEqual(type(chained), asyncio.CancelledError) - - def test_wait_for_waits_for_task_cancellation_w_timeout_0(self): - loop = asyncio.new_event_loop() - self.addCleanup(loop.close) - - task_done = False - - async def foo(): - async def inner(): - nonlocal task_done - try: - await asyncio.sleep(10) - except asyncio.CancelledError: - await asyncio.sleep(_EPSILON) - raise - finally: - task_done = True - - inner_task = self.new_task(loop, inner()) - await asyncio.sleep(_EPSILON) - await asyncio.wait_for(inner_task, timeout=0) - - with self.assertRaises(asyncio.TimeoutError) as cm: - loop.run_until_complete(foo()) - - self.assertTrue(task_done) - chained = cm.exception.__context__ - self.assertEqual(type(chained), asyncio.CancelledError) - - def test_wait_for_reraises_exception_during_cancellation(self): - loop = asyncio.new_event_loop() - self.addCleanup(loop.close) - - class FooException(Exception): - pass - - async def foo(): - async def inner(): - try: - await asyncio.sleep(0.2) - finally: - raise FooException - - inner_task = self.new_task(loop, inner()) - - await asyncio.wait_for(inner_task, timeout=_EPSILON) - - with self.assertRaises(FooException): - loop.run_until_complete(foo()) - - def test_wait_for_self_cancellation(self): - loop = asyncio.new_event_loop() - self.addCleanup(loop.close) - - async def foo(): - async def inner(): - try: - await asyncio.sleep(0.3) - except asyncio.CancelledError: - try: - await asyncio.sleep(0.3) - except asyncio.CancelledError: - await asyncio.sleep(0.3) - - return 42 - - inner_task = self.new_task(loop, inner()) - - wait = asyncio.wait_for(inner_task, timeout=0.1) - - # Test that wait_for itself is properly cancellable - # even when the initial task holds up the initial cancellation. - task = self.new_task(loop, wait) - await asyncio.sleep(0.2) - task.cancel() - - with self.assertRaises(asyncio.CancelledError): - await task - - self.assertEqual(await inner_task, 42) - - loop.run_until_complete(foo()) - def test_wait(self): def gen(): diff --git a/Lib/test/test_asyncio/test_waitfor.py b/Lib/test/test_asyncio/test_waitfor.py new file mode 100644 index 0000000000000..b00815e153110 --- /dev/null +++ b/Lib/test/test_asyncio/test_waitfor.py @@ -0,0 +1,270 @@ +import asyncio +import unittest +import time + + +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + +# The following value can be used as a very small timeout: +# it passes check "timeout > 0", but has almost +# no effect on the test performance +_EPSILON = 0.0001 + + +class SlowTask: + """ Task will run for this defined time, ignoring cancel requests """ + TASK_TIMEOUT = 0.2 + + def __init__(self): + self.exited = False + + async def run(self): + exitat = time.monotonic() + self.TASK_TIMEOUT + + while True: + tosleep = exitat - time.monotonic() + if tosleep <= 0: + break + + try: + await asyncio.sleep(tosleep) + except asyncio.CancelledError: + pass + + self.exited = True + + +class AsyncioWaitForTest(unittest.IsolatedAsyncioTestCase): + + async def test_asyncio_wait_for_cancelled(self): + t = SlowTask() + + waitfortask = asyncio.create_task( + asyncio.wait_for(t.run(), t.TASK_TIMEOUT * 2)) + await asyncio.sleep(0) + waitfortask.cancel() + await asyncio.wait({waitfortask}) + + self.assertTrue(t.exited) + + async def test_asyncio_wait_for_timeout(self): + t = SlowTask() + + try: + await asyncio.wait_for(t.run(), t.TASK_TIMEOUT / 2) + except asyncio.TimeoutError: + pass + + self.assertTrue(t.exited) + + async def test_wait_for_timeout_less_then_0_or_0_future_done(self): + loop = asyncio.get_running_loop() + + 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(): + nonlocal foo_started + 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() + + for timeout in [0, -1]: + with self.subTest(timeout=timeout): + foo_running = None + started = loop.create_future() + + async def foo(): + nonlocal foo_running + foo_running = True + started.set_result(None) + try: + await asyncio.sleep(10) + finally: + foo_running = False + return 'done' + + fut = asyncio.create_task(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) + finally: + foo_running = False + return 'done' + + 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.2) + self.assertEqual(foo_running, False) + + async def test_wait_for_blocking(self): + async def coro(): + return 'done' + + res = await asyncio.wait_for(coro(), timeout=None) + self.assertEqual(res, 'done') + + async def test_wait_for_race_condition(self): + loop = asyncio.get_running_loop() + + fut = loop.create_future() + task = asyncio.wait_for(fut, timeout=0.2) + loop.call_later(0.1, fut.set_result, "ok") + res = await task + self.assertEqual(res, "ok") + + async def test_wait_for_cancellation_race_condition(self): + async def inner(): + with self.assertRaises(asyncio.CancelledError): + await asyncio.sleep(1) + return 1 + + result = await asyncio.wait_for(inner(), timeout=.01) + self.assertEqual(result, 1) + + async def test_wait_for_waits_for_task_cancellation(self): + task_done = False + + async def inner(): + nonlocal task_done + try: + await asyncio.sleep(10) + except asyncio.CancelledError: + await asyncio.sleep(_EPSILON) + raise + finally: + task_done = True + + inner_task = asyncio.create_task(inner()) + + with self.assertRaises(asyncio.TimeoutError) as cm: + await asyncio.wait_for(inner_task, timeout=_EPSILON) + + self.assertTrue(task_done) + chained = cm.exception.__context__ + self.assertEqual(type(chained), asyncio.CancelledError) + + async def test_wait_for_waits_for_task_cancellation_w_timeout_0(self): + task_done = False + + async def foo(): + async def inner(): + nonlocal task_done + try: + await asyncio.sleep(10) + except asyncio.CancelledError: + await asyncio.sleep(_EPSILON) + raise + finally: + task_done = True + + inner_task = asyncio.create_task(inner()) + await asyncio.sleep(_EPSILON) + await asyncio.wait_for(inner_task, timeout=0) + + with self.assertRaises(asyncio.TimeoutError) as cm: + await foo() + + self.assertTrue(task_done) + chained = cm.exception.__context__ + self.assertEqual(type(chained), asyncio.CancelledError) + + async def test_wait_for_reraises_exception_during_cancellation(self): + class FooException(Exception): + pass + + async def foo(): + async def inner(): + try: + await asyncio.sleep(0.2) + finally: + raise FooException + + inner_task = asyncio.create_task(inner()) + + await asyncio.wait_for(inner_task, timeout=_EPSILON) + + with self.assertRaises(FooException): + await foo() + + async def test_wait_for_self_cancellation(self): + async def inner(): + try: + await asyncio.sleep(0.3) + except asyncio.CancelledError: + try: + await asyncio.sleep(0.3) + except asyncio.CancelledError: + await asyncio.sleep(0.3) + + return 42 + + inner_task = asyncio.create_task(inner()) + + wait = asyncio.wait_for(inner_task, timeout=0.1) + + # Test that wait_for itself is properly cancellable + # even when the initial task holds up the initial cancellation. + task = asyncio.create_task(wait) + await asyncio.sleep(0.2) + task.cancel() + + with self.assertRaises(asyncio.CancelledError): + await task + + self.assertEqual(await inner_task, 42) + + + +if __name__ == '__main__': + unittest.main() From webhook-mailer at python.org Wed Mar 16 16:15:20 2022 From: webhook-mailer at python.org (asvetlov) Date: Wed, 16 Mar 2022 20:15:20 -0000 Subject: [Python-checkins] bpo-47038: Rewrite asyncio.wait_for test to use IsolatedAsyncioTestCase (GH-31942) (GH-31943) Message-ID: https://github.com/python/cpython/commit/4186dd662cf22613b21af948163978af4243a8d6 commit: 4186dd662cf22613b21af948163978af4243a8d6 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: asvetlov date: 2022-03-16T22:15:08+02:00 summary: bpo-47038: Rewrite asyncio.wait_for test to use IsolatedAsyncioTestCase (GH-31942) (GH-31943) (cherry picked from commit dd0082c627713634c7fd88ad33d18b5cc9f4a7b8) Co-authored-by: Andrew Svetlov Co-authored-by: Andrew Svetlov files: A Lib/test/test_asyncio/test_waitfor.py D Lib/test/test_asyncio/test_asyncio_waitfor.py M Lib/test/test_asyncio/test_tasks.py diff --git a/Lib/test/test_asyncio/test_asyncio_waitfor.py b/Lib/test/test_asyncio/test_asyncio_waitfor.py deleted file mode 100644 index 2ca64abbeb527..0000000000000 --- a/Lib/test/test_asyncio/test_asyncio_waitfor.py +++ /dev/null @@ -1,61 +0,0 @@ -import asyncio -import unittest -import time - -def tearDownModule(): - asyncio.set_event_loop_policy(None) - - -class SlowTask: - """ Task will run for this defined time, ignoring cancel requests """ - TASK_TIMEOUT = 0.2 - - def __init__(self): - self.exited = False - - async def run(self): - exitat = time.monotonic() + self.TASK_TIMEOUT - - while True: - tosleep = exitat - time.monotonic() - if tosleep <= 0: - break - - try: - await asyncio.sleep(tosleep) - except asyncio.CancelledError: - pass - - self.exited = True - -class AsyncioWaitForTest(unittest.TestCase): - - async def atest_asyncio_wait_for_cancelled(self): - t = SlowTask() - - waitfortask = asyncio.create_task(asyncio.wait_for(t.run(), t.TASK_TIMEOUT * 2)) - await asyncio.sleep(0) - waitfortask.cancel() - await asyncio.wait({waitfortask}) - - self.assertTrue(t.exited) - - def test_asyncio_wait_for_cancelled(self): - asyncio.run(self.atest_asyncio_wait_for_cancelled()) - - async def atest_asyncio_wait_for_timeout(self): - t = SlowTask() - - try: - await asyncio.wait_for(t.run(), t.TASK_TIMEOUT / 2) - except asyncio.TimeoutError: - pass - - self.assertTrue(t.exited) - - def test_asyncio_wait_for_timeout(self): - asyncio.run(self.atest_asyncio_wait_for_timeout()) - - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 398b143d2d0c6..7f3cf8b56ba66 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -98,12 +98,6 @@ def __await__(self): return self -# The following value can be used as a very small timeout: -# it passes check "timeout > 0", but has almost -# no effect on the test performance -_EPSILON = 0.0001 - - class BaseTaskTests: Task = None @@ -121,7 +115,6 @@ def setUp(self): self.loop.set_task_factory(self.new_task) self.loop.create_future = lambda: self.new_future(self.loop) - def test_generic_alias(self): task = self.__class__.Task[str] self.assertEqual(task.__args__, (str,)) @@ -1031,251 +1024,6 @@ async def coro(): task._log_traceback = True self.loop.run_until_complete(task) - def test_wait_for_timeout_less_then_0_or_0_future_done(self): - def gen(): - when = yield - self.assertAlmostEqual(0, when) - - loop = self.new_test_loop(gen) - - fut = self.new_future(loop) - fut.set_result('done') - - ret = loop.run_until_complete(asyncio.wait_for(fut, 0)) - - self.assertEqual(ret, 'done') - self.assertTrue(fut.done()) - self.assertAlmostEqual(0, loop.time()) - - def test_wait_for_timeout_less_then_0_or_0_coroutine_do_not_started(self): - def gen(): - when = yield - self.assertAlmostEqual(0, when) - - loop = self.new_test_loop(gen) - - foo_started = False - - async def foo(): - nonlocal foo_started - foo_started = True - - with self.assertRaises(asyncio.TimeoutError): - loop.run_until_complete(asyncio.wait_for(foo(), 0)) - - self.assertAlmostEqual(0, loop.time()) - self.assertEqual(foo_started, False) - - def test_wait_for_timeout_less_then_0_or_0(self): - def gen(): - when = yield - self.assertAlmostEqual(0.2, when) - when = yield 0 - self.assertAlmostEqual(0, when) - - for timeout in [0, -1]: - with self.subTest(timeout=timeout): - loop = self.new_test_loop(gen) - - foo_running = None - - async def foo(): - nonlocal foo_running - foo_running = True - try: - await asyncio.sleep(0.2) - finally: - foo_running = False - return 'done' - - fut = self.new_task(loop, foo()) - - with self.assertRaises(asyncio.TimeoutError): - loop.run_until_complete(asyncio.wait_for(fut, timeout)) - self.assertTrue(fut.done()) - # it should have been cancelled due to the timeout - self.assertTrue(fut.cancelled()) - self.assertAlmostEqual(0, loop.time()) - self.assertEqual(foo_running, False) - - def test_wait_for(self): - - def gen(): - when = yield - self.assertAlmostEqual(0.2, when) - when = yield 0 - self.assertAlmostEqual(0.1, when) - when = yield 0.1 - - loop = self.new_test_loop(gen) - - foo_running = None - - async def foo(): - nonlocal foo_running - foo_running = True - try: - await asyncio.sleep(0.2) - finally: - foo_running = False - return 'done' - - fut = self.new_task(loop, foo()) - - with self.assertRaises(asyncio.TimeoutError): - loop.run_until_complete(asyncio.wait_for(fut, 0.1)) - self.assertTrue(fut.done()) - # it should have been cancelled due to the timeout - self.assertTrue(fut.cancelled()) - self.assertAlmostEqual(0.1, loop.time()) - self.assertEqual(foo_running, False) - - def test_wait_for_blocking(self): - loop = self.new_test_loop() - - async def coro(): - return 'done' - - res = loop.run_until_complete(asyncio.wait_for(coro(), timeout=None)) - self.assertEqual(res, 'done') - - def test_wait_for_race_condition(self): - - def gen(): - yield 0.1 - yield 0.1 - yield 0.1 - - loop = self.new_test_loop(gen) - - fut = self.new_future(loop) - task = asyncio.wait_for(fut, timeout=0.2) - loop.call_later(0.1, fut.set_result, "ok") - res = loop.run_until_complete(task) - self.assertEqual(res, "ok") - - def test_wait_for_cancellation_race_condition(self): - async def inner(): - with contextlib.suppress(asyncio.CancelledError): - await asyncio.sleep(1) - return 1 - - async def main(): - result = await asyncio.wait_for(inner(), timeout=.01) - self.assertEqual(result, 1) - - asyncio.run(main()) - - def test_wait_for_waits_for_task_cancellation(self): - loop = asyncio.new_event_loop() - self.addCleanup(loop.close) - - task_done = False - - async def foo(): - async def inner(): - nonlocal task_done - try: - await asyncio.sleep(0.2) - except asyncio.CancelledError: - await asyncio.sleep(_EPSILON) - raise - finally: - task_done = True - - inner_task = self.new_task(loop, inner()) - - await asyncio.wait_for(inner_task, timeout=_EPSILON) - - with self.assertRaises(asyncio.TimeoutError) as cm: - loop.run_until_complete(foo()) - - self.assertTrue(task_done) - chained = cm.exception.__context__ - self.assertEqual(type(chained), asyncio.CancelledError) - - def test_wait_for_waits_for_task_cancellation_w_timeout_0(self): - loop = asyncio.new_event_loop() - self.addCleanup(loop.close) - - task_done = False - - async def foo(): - async def inner(): - nonlocal task_done - try: - await asyncio.sleep(10) - except asyncio.CancelledError: - await asyncio.sleep(_EPSILON) - raise - finally: - task_done = True - - inner_task = self.new_task(loop, inner()) - await asyncio.sleep(_EPSILON) - await asyncio.wait_for(inner_task, timeout=0) - - with self.assertRaises(asyncio.TimeoutError) as cm: - loop.run_until_complete(foo()) - - self.assertTrue(task_done) - chained = cm.exception.__context__ - self.assertEqual(type(chained), asyncio.CancelledError) - - def test_wait_for_reraises_exception_during_cancellation(self): - loop = asyncio.new_event_loop() - self.addCleanup(loop.close) - - class FooException(Exception): - pass - - async def foo(): - async def inner(): - try: - await asyncio.sleep(0.2) - finally: - raise FooException - - inner_task = self.new_task(loop, inner()) - - await asyncio.wait_for(inner_task, timeout=_EPSILON) - - with self.assertRaises(FooException): - loop.run_until_complete(foo()) - - def test_wait_for_self_cancellation(self): - loop = asyncio.new_event_loop() - self.addCleanup(loop.close) - - async def foo(): - async def inner(): - try: - await asyncio.sleep(0.3) - except asyncio.CancelledError: - try: - await asyncio.sleep(0.3) - except asyncio.CancelledError: - await asyncio.sleep(0.3) - - return 42 - - inner_task = self.new_task(loop, inner()) - - wait = asyncio.wait_for(inner_task, timeout=0.1) - - # Test that wait_for itself is properly cancellable - # even when the initial task holds up the initial cancellation. - task = self.new_task(loop, wait) - await asyncio.sleep(0.2) - task.cancel() - - with self.assertRaises(asyncio.CancelledError): - await task - - self.assertEqual(await inner_task, 42) - - loop.run_until_complete(foo()) - def test_wait(self): def gen(): diff --git a/Lib/test/test_asyncio/test_waitfor.py b/Lib/test/test_asyncio/test_waitfor.py new file mode 100644 index 0000000000000..b00815e153110 --- /dev/null +++ b/Lib/test/test_asyncio/test_waitfor.py @@ -0,0 +1,270 @@ +import asyncio +import unittest +import time + + +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + +# The following value can be used as a very small timeout: +# it passes check "timeout > 0", but has almost +# no effect on the test performance +_EPSILON = 0.0001 + + +class SlowTask: + """ Task will run for this defined time, ignoring cancel requests """ + TASK_TIMEOUT = 0.2 + + def __init__(self): + self.exited = False + + async def run(self): + exitat = time.monotonic() + self.TASK_TIMEOUT + + while True: + tosleep = exitat - time.monotonic() + if tosleep <= 0: + break + + try: + await asyncio.sleep(tosleep) + except asyncio.CancelledError: + pass + + self.exited = True + + +class AsyncioWaitForTest(unittest.IsolatedAsyncioTestCase): + + async def test_asyncio_wait_for_cancelled(self): + t = SlowTask() + + waitfortask = asyncio.create_task( + asyncio.wait_for(t.run(), t.TASK_TIMEOUT * 2)) + await asyncio.sleep(0) + waitfortask.cancel() + await asyncio.wait({waitfortask}) + + self.assertTrue(t.exited) + + async def test_asyncio_wait_for_timeout(self): + t = SlowTask() + + try: + await asyncio.wait_for(t.run(), t.TASK_TIMEOUT / 2) + except asyncio.TimeoutError: + pass + + self.assertTrue(t.exited) + + async def test_wait_for_timeout_less_then_0_or_0_future_done(self): + loop = asyncio.get_running_loop() + + 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(): + nonlocal foo_started + 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() + + for timeout in [0, -1]: + with self.subTest(timeout=timeout): + foo_running = None + started = loop.create_future() + + async def foo(): + nonlocal foo_running + foo_running = True + started.set_result(None) + try: + await asyncio.sleep(10) + finally: + foo_running = False + return 'done' + + fut = asyncio.create_task(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) + finally: + foo_running = False + return 'done' + + 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.2) + self.assertEqual(foo_running, False) + + async def test_wait_for_blocking(self): + async def coro(): + return 'done' + + res = await asyncio.wait_for(coro(), timeout=None) + self.assertEqual(res, 'done') + + async def test_wait_for_race_condition(self): + loop = asyncio.get_running_loop() + + fut = loop.create_future() + task = asyncio.wait_for(fut, timeout=0.2) + loop.call_later(0.1, fut.set_result, "ok") + res = await task + self.assertEqual(res, "ok") + + async def test_wait_for_cancellation_race_condition(self): + async def inner(): + with self.assertRaises(asyncio.CancelledError): + await asyncio.sleep(1) + return 1 + + result = await asyncio.wait_for(inner(), timeout=.01) + self.assertEqual(result, 1) + + async def test_wait_for_waits_for_task_cancellation(self): + task_done = False + + async def inner(): + nonlocal task_done + try: + await asyncio.sleep(10) + except asyncio.CancelledError: + await asyncio.sleep(_EPSILON) + raise + finally: + task_done = True + + inner_task = asyncio.create_task(inner()) + + with self.assertRaises(asyncio.TimeoutError) as cm: + await asyncio.wait_for(inner_task, timeout=_EPSILON) + + self.assertTrue(task_done) + chained = cm.exception.__context__ + self.assertEqual(type(chained), asyncio.CancelledError) + + async def test_wait_for_waits_for_task_cancellation_w_timeout_0(self): + task_done = False + + async def foo(): + async def inner(): + nonlocal task_done + try: + await asyncio.sleep(10) + except asyncio.CancelledError: + await asyncio.sleep(_EPSILON) + raise + finally: + task_done = True + + inner_task = asyncio.create_task(inner()) + await asyncio.sleep(_EPSILON) + await asyncio.wait_for(inner_task, timeout=0) + + with self.assertRaises(asyncio.TimeoutError) as cm: + await foo() + + self.assertTrue(task_done) + chained = cm.exception.__context__ + self.assertEqual(type(chained), asyncio.CancelledError) + + async def test_wait_for_reraises_exception_during_cancellation(self): + class FooException(Exception): + pass + + async def foo(): + async def inner(): + try: + await asyncio.sleep(0.2) + finally: + raise FooException + + inner_task = asyncio.create_task(inner()) + + await asyncio.wait_for(inner_task, timeout=_EPSILON) + + with self.assertRaises(FooException): + await foo() + + async def test_wait_for_self_cancellation(self): + async def inner(): + try: + await asyncio.sleep(0.3) + except asyncio.CancelledError: + try: + await asyncio.sleep(0.3) + except asyncio.CancelledError: + await asyncio.sleep(0.3) + + return 42 + + inner_task = asyncio.create_task(inner()) + + wait = asyncio.wait_for(inner_task, timeout=0.1) + + # Test that wait_for itself is properly cancellable + # even when the initial task holds up the initial cancellation. + task = asyncio.create_task(wait) + await asyncio.sleep(0.2) + task.cancel() + + with self.assertRaises(asyncio.CancelledError): + await task + + self.assertEqual(await inner_task, 42) + + + +if __name__ == '__main__': + unittest.main() From webhook-mailer at python.org Wed Mar 16 16:45:51 2022 From: webhook-mailer at python.org (asvetlov) Date: Wed, 16 Mar 2022 20:45:51 -0000 Subject: [Python-checkins] [3.9] bpo-47038: Rewrite asyncio.wait_for test to use IsolatedAsyncioTestCase (GH-31942). (GH-31944) Message-ID: https://github.com/python/cpython/commit/3244659521798417810100904f39ae5dabe60a7f commit: 3244659521798417810100904f39ae5dabe60a7f branch: 3.9 author: Andrew Svetlov committer: asvetlov date: 2022-03-16T22:45:39+02:00 summary: [3.9] bpo-47038: Rewrite asyncio.wait_for test to use IsolatedAsyncioTestCase (GH-31942). (GH-31944) (cherry picked from commit dd0082c627713634c7fd88ad33d18b5cc9f4a7b8) Co-authored-by: Andrew Svetlov files: A Lib/test/test_asyncio/test_waitfor.py D Lib/test/test_asyncio/test_asyncio_waitfor.py M Lib/test/test_asyncio/test_tasks.py diff --git a/Lib/test/test_asyncio/test_asyncio_waitfor.py b/Lib/test/test_asyncio/test_asyncio_waitfor.py deleted file mode 100644 index 2ca64abbeb527..0000000000000 --- a/Lib/test/test_asyncio/test_asyncio_waitfor.py +++ /dev/null @@ -1,61 +0,0 @@ -import asyncio -import unittest -import time - -def tearDownModule(): - asyncio.set_event_loop_policy(None) - - -class SlowTask: - """ Task will run for this defined time, ignoring cancel requests """ - TASK_TIMEOUT = 0.2 - - def __init__(self): - self.exited = False - - async def run(self): - exitat = time.monotonic() + self.TASK_TIMEOUT - - while True: - tosleep = exitat - time.monotonic() - if tosleep <= 0: - break - - try: - await asyncio.sleep(tosleep) - except asyncio.CancelledError: - pass - - self.exited = True - -class AsyncioWaitForTest(unittest.TestCase): - - async def atest_asyncio_wait_for_cancelled(self): - t = SlowTask() - - waitfortask = asyncio.create_task(asyncio.wait_for(t.run(), t.TASK_TIMEOUT * 2)) - await asyncio.sleep(0) - waitfortask.cancel() - await asyncio.wait({waitfortask}) - - self.assertTrue(t.exited) - - def test_asyncio_wait_for_cancelled(self): - asyncio.run(self.atest_asyncio_wait_for_cancelled()) - - async def atest_asyncio_wait_for_timeout(self): - t = SlowTask() - - try: - await asyncio.wait_for(t.run(), t.TASK_TIMEOUT / 2) - except asyncio.TimeoutError: - pass - - self.assertTrue(t.exited) - - def test_asyncio_wait_for_timeout(self): - asyncio.run(self.atest_asyncio_wait_for_timeout()) - - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 0e538edcd9678..58f8d49d02b77 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -98,12 +98,6 @@ def __await__(self): return self -# The following value can be used as a very small timeout: -# it passes check "timeout > 0", but has almost -# no effect on the test performance -_EPSILON = 0.0001 - - class BaseTaskTests: Task = None @@ -121,7 +115,6 @@ def setUp(self): self.loop.set_task_factory(self.new_task) self.loop.create_future = lambda: self.new_future(self.loop) - def test_generic_alias(self): task = self.__class__.Task[str] self.assertEqual(task.__args__, (str,)) @@ -977,278 +970,6 @@ async def coro(): task._log_traceback = True self.loop.run_until_complete(task) - def test_wait_for_timeout_less_then_0_or_0_future_done(self): - def gen(): - when = yield - self.assertAlmostEqual(0, when) - - loop = self.new_test_loop(gen) - - fut = self.new_future(loop) - fut.set_result('done') - - ret = loop.run_until_complete(asyncio.wait_for(fut, 0)) - - self.assertEqual(ret, 'done') - self.assertTrue(fut.done()) - self.assertAlmostEqual(0, loop.time()) - - def test_wait_for_timeout_less_then_0_or_0_coroutine_do_not_started(self): - def gen(): - when = yield - self.assertAlmostEqual(0, when) - - loop = self.new_test_loop(gen) - - foo_started = False - - async def foo(): - nonlocal foo_started - foo_started = True - - with self.assertRaises(asyncio.TimeoutError): - loop.run_until_complete(asyncio.wait_for(foo(), 0)) - - self.assertAlmostEqual(0, loop.time()) - self.assertEqual(foo_started, False) - - def test_wait_for_timeout_less_then_0_or_0(self): - def gen(): - when = yield - self.assertAlmostEqual(0.2, when) - when = yield 0 - self.assertAlmostEqual(0, when) - - for timeout in [0, -1]: - with self.subTest(timeout=timeout): - loop = self.new_test_loop(gen) - - foo_running = None - - async def foo(): - nonlocal foo_running - foo_running = True - try: - await asyncio.sleep(0.2) - finally: - foo_running = False - return 'done' - - fut = self.new_task(loop, foo()) - - with self.assertRaises(asyncio.TimeoutError): - loop.run_until_complete(asyncio.wait_for(fut, timeout)) - self.assertTrue(fut.done()) - # it should have been cancelled due to the timeout - self.assertTrue(fut.cancelled()) - self.assertAlmostEqual(0, loop.time()) - self.assertEqual(foo_running, False) - - def test_wait_for(self): - - def gen(): - when = yield - self.assertAlmostEqual(0.2, when) - when = yield 0 - self.assertAlmostEqual(0.1, when) - when = yield 0.1 - - loop = self.new_test_loop(gen) - - foo_running = None - - async def foo(): - nonlocal foo_running - foo_running = True - try: - await asyncio.sleep(0.2) - finally: - foo_running = False - return 'done' - - fut = self.new_task(loop, foo()) - - with self.assertRaises(asyncio.TimeoutError): - loop.run_until_complete(asyncio.wait_for(fut, 0.1)) - self.assertTrue(fut.done()) - # it should have been cancelled due to the timeout - self.assertTrue(fut.cancelled()) - self.assertAlmostEqual(0.1, loop.time()) - self.assertEqual(foo_running, False) - - def test_wait_for_blocking(self): - loop = self.new_test_loop() - - async def coro(): - return 'done' - - res = loop.run_until_complete(asyncio.wait_for(coro(), timeout=None)) - self.assertEqual(res, 'done') - - def test_wait_for_with_global_loop(self): - - def gen(): - when = yield - self.assertAlmostEqual(0.2, when) - when = yield 0 - self.assertAlmostEqual(0.01, when) - yield 0.01 - - loop = self.new_test_loop(gen) - - async def foo(): - await asyncio.sleep(0.2) - return 'done' - - asyncio.set_event_loop(loop) - try: - fut = self.new_task(loop, foo()) - with self.assertRaises(asyncio.TimeoutError): - loop.run_until_complete(asyncio.wait_for(fut, 0.01)) - finally: - asyncio.set_event_loop(None) - - self.assertAlmostEqual(0.01, loop.time()) - self.assertTrue(fut.done()) - self.assertTrue(fut.cancelled()) - - def test_wait_for_race_condition(self): - - def gen(): - yield 0.1 - yield 0.1 - yield 0.1 - - loop = self.new_test_loop(gen) - - fut = self.new_future(loop) - task = asyncio.wait_for(fut, timeout=0.2) - loop.call_later(0.1, fut.set_result, "ok") - res = loop.run_until_complete(task) - self.assertEqual(res, "ok") - - def test_wait_for_cancellation_race_condition(self): - async def inner(): - with contextlib.suppress(asyncio.CancelledError): - await asyncio.sleep(1) - return 1 - - async def main(): - result = await asyncio.wait_for(inner(), timeout=.01) - assert result == 1 - - asyncio.run(main()) - - def test_wait_for_waits_for_task_cancellation(self): - loop = asyncio.new_event_loop() - self.addCleanup(loop.close) - - task_done = False - - async def foo(): - async def inner(): - nonlocal task_done - try: - await asyncio.sleep(0.2) - except asyncio.CancelledError: - await asyncio.sleep(_EPSILON) - raise - finally: - task_done = True - - inner_task = self.new_task(loop, inner()) - - await asyncio.wait_for(inner_task, timeout=_EPSILON) - - with self.assertRaises(asyncio.TimeoutError) as cm: - loop.run_until_complete(foo()) - - self.assertTrue(task_done) - chained = cm.exception.__context__ - self.assertEqual(type(chained), asyncio.CancelledError) - - def test_wait_for_waits_for_task_cancellation_w_timeout_0(self): - loop = asyncio.new_event_loop() - self.addCleanup(loop.close) - - task_done = False - - async def foo(): - async def inner(): - nonlocal task_done - try: - await asyncio.sleep(10) - except asyncio.CancelledError: - await asyncio.sleep(_EPSILON) - raise - finally: - task_done = True - - inner_task = self.new_task(loop, inner()) - await asyncio.sleep(_EPSILON) - await asyncio.wait_for(inner_task, timeout=0) - - with self.assertRaises(asyncio.TimeoutError) as cm: - loop.run_until_complete(foo()) - - self.assertTrue(task_done) - chained = cm.exception.__context__ - self.assertEqual(type(chained), asyncio.CancelledError) - - def test_wait_for_reraises_exception_during_cancellation(self): - loop = asyncio.new_event_loop() - self.addCleanup(loop.close) - - class FooException(Exception): - pass - - async def foo(): - async def inner(): - try: - await asyncio.sleep(0.2) - finally: - raise FooException - - inner_task = self.new_task(loop, inner()) - - await asyncio.wait_for(inner_task, timeout=_EPSILON) - - with self.assertRaises(FooException): - loop.run_until_complete(foo()) - - def test_wait_for_self_cancellation(self): - loop = asyncio.new_event_loop() - self.addCleanup(loop.close) - - async def foo(): - async def inner(): - try: - await asyncio.sleep(0.3) - except asyncio.CancelledError: - try: - await asyncio.sleep(0.3) - except asyncio.CancelledError: - await asyncio.sleep(0.3) - - return 42 - - inner_task = self.new_task(loop, inner()) - - wait = asyncio.wait_for(inner_task, timeout=0.1) - - # Test that wait_for itself is properly cancellable - # even when the initial task holds up the initial cancellation. - task = self.new_task(loop, wait) - await asyncio.sleep(0.2) - task.cancel() - - with self.assertRaises(asyncio.CancelledError): - await task - - self.assertEqual(await inner_task, 42) - - loop.run_until_complete(foo()) - def test_wait(self): def gen(): diff --git a/Lib/test/test_asyncio/test_waitfor.py b/Lib/test/test_asyncio/test_waitfor.py new file mode 100644 index 0000000000000..b00815e153110 --- /dev/null +++ b/Lib/test/test_asyncio/test_waitfor.py @@ -0,0 +1,270 @@ +import asyncio +import unittest +import time + + +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + +# The following value can be used as a very small timeout: +# it passes check "timeout > 0", but has almost +# no effect on the test performance +_EPSILON = 0.0001 + + +class SlowTask: + """ Task will run for this defined time, ignoring cancel requests """ + TASK_TIMEOUT = 0.2 + + def __init__(self): + self.exited = False + + async def run(self): + exitat = time.monotonic() + self.TASK_TIMEOUT + + while True: + tosleep = exitat - time.monotonic() + if tosleep <= 0: + break + + try: + await asyncio.sleep(tosleep) + except asyncio.CancelledError: + pass + + self.exited = True + + +class AsyncioWaitForTest(unittest.IsolatedAsyncioTestCase): + + async def test_asyncio_wait_for_cancelled(self): + t = SlowTask() + + waitfortask = asyncio.create_task( + asyncio.wait_for(t.run(), t.TASK_TIMEOUT * 2)) + await asyncio.sleep(0) + waitfortask.cancel() + await asyncio.wait({waitfortask}) + + self.assertTrue(t.exited) + + async def test_asyncio_wait_for_timeout(self): + t = SlowTask() + + try: + await asyncio.wait_for(t.run(), t.TASK_TIMEOUT / 2) + except asyncio.TimeoutError: + pass + + self.assertTrue(t.exited) + + async def test_wait_for_timeout_less_then_0_or_0_future_done(self): + loop = asyncio.get_running_loop() + + 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(): + nonlocal foo_started + 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() + + for timeout in [0, -1]: + with self.subTest(timeout=timeout): + foo_running = None + started = loop.create_future() + + async def foo(): + nonlocal foo_running + foo_running = True + started.set_result(None) + try: + await asyncio.sleep(10) + finally: + foo_running = False + return 'done' + + fut = asyncio.create_task(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) + finally: + foo_running = False + return 'done' + + 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.2) + self.assertEqual(foo_running, False) + + async def test_wait_for_blocking(self): + async def coro(): + return 'done' + + res = await asyncio.wait_for(coro(), timeout=None) + self.assertEqual(res, 'done') + + async def test_wait_for_race_condition(self): + loop = asyncio.get_running_loop() + + fut = loop.create_future() + task = asyncio.wait_for(fut, timeout=0.2) + loop.call_later(0.1, fut.set_result, "ok") + res = await task + self.assertEqual(res, "ok") + + async def test_wait_for_cancellation_race_condition(self): + async def inner(): + with self.assertRaises(asyncio.CancelledError): + await asyncio.sleep(1) + return 1 + + result = await asyncio.wait_for(inner(), timeout=.01) + self.assertEqual(result, 1) + + async def test_wait_for_waits_for_task_cancellation(self): + task_done = False + + async def inner(): + nonlocal task_done + try: + await asyncio.sleep(10) + except asyncio.CancelledError: + await asyncio.sleep(_EPSILON) + raise + finally: + task_done = True + + inner_task = asyncio.create_task(inner()) + + with self.assertRaises(asyncio.TimeoutError) as cm: + await asyncio.wait_for(inner_task, timeout=_EPSILON) + + self.assertTrue(task_done) + chained = cm.exception.__context__ + self.assertEqual(type(chained), asyncio.CancelledError) + + async def test_wait_for_waits_for_task_cancellation_w_timeout_0(self): + task_done = False + + async def foo(): + async def inner(): + nonlocal task_done + try: + await asyncio.sleep(10) + except asyncio.CancelledError: + await asyncio.sleep(_EPSILON) + raise + finally: + task_done = True + + inner_task = asyncio.create_task(inner()) + await asyncio.sleep(_EPSILON) + await asyncio.wait_for(inner_task, timeout=0) + + with self.assertRaises(asyncio.TimeoutError) as cm: + await foo() + + self.assertTrue(task_done) + chained = cm.exception.__context__ + self.assertEqual(type(chained), asyncio.CancelledError) + + async def test_wait_for_reraises_exception_during_cancellation(self): + class FooException(Exception): + pass + + async def foo(): + async def inner(): + try: + await asyncio.sleep(0.2) + finally: + raise FooException + + inner_task = asyncio.create_task(inner()) + + await asyncio.wait_for(inner_task, timeout=_EPSILON) + + with self.assertRaises(FooException): + await foo() + + async def test_wait_for_self_cancellation(self): + async def inner(): + try: + await asyncio.sleep(0.3) + except asyncio.CancelledError: + try: + await asyncio.sleep(0.3) + except asyncio.CancelledError: + await asyncio.sleep(0.3) + + return 42 + + inner_task = asyncio.create_task(inner()) + + wait = asyncio.wait_for(inner_task, timeout=0.1) + + # Test that wait_for itself is properly cancellable + # even when the initial task holds up the initial cancellation. + task = asyncio.create_task(wait) + await asyncio.sleep(0.2) + task.cancel() + + with self.assertRaises(asyncio.CancelledError): + await task + + self.assertEqual(await inner_task, 42) + + + +if __name__ == '__main__': + unittest.main() From webhook-mailer at python.org Wed Mar 16 19:20:35 2022 From: webhook-mailer at python.org (asvetlov) Date: Wed, 16 Mar 2022 23:20:35 -0000 Subject: [Python-checkins] bpo-47038: Rewrite missed asyncio.wait_for test to use IsolatedAnsyncioTestCase (GH-31946) Message-ID: https://github.com/python/cpython/commit/3dd9bfac04d3dcdbfd3f8011a6c9d4b9ac8c116a commit: 3dd9bfac04d3dcdbfd3f8011a6c9d4b9ac8c116a branch: main author: Andrew Svetlov committer: asvetlov date: 2022-03-17T01:20:29+02:00 summary: bpo-47038: Rewrite missed asyncio.wait_for test to use IsolatedAnsyncioTestCase (GH-31946) files: M Lib/test/test_asyncio/test_tasks.py M Lib/test/test_asyncio/test_waitfor.py diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 44ec8425b7f80..141c019dcb9cc 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -1990,32 +1990,6 @@ def test_task_source_traceback(self): 'test_task_source_traceback')) self.loop.run_until_complete(task) - def _test_cancel_wait_for(self, timeout): - loop = asyncio.new_event_loop() - self.addCleanup(loop.close) - - async def blocking_coroutine(): - fut = self.new_future(loop) - # Block: fut result is never set - await fut - - task = loop.create_task(blocking_coroutine()) - - wait = loop.create_task(asyncio.wait_for(task, timeout)) - loop.call_soon(wait.cancel) - - self.assertRaises(asyncio.CancelledError, - loop.run_until_complete, wait) - - # Python issue #23219: cancelling the wait must also cancel the task - self.assertTrue(task.cancelled()) - - def test_cancel_blocking_wait_for(self): - self._test_cancel_wait_for(None) - - def test_cancel_wait_for(self): - self._test_cancel_wait_for(60.0) - def test_cancel_gather_1(self): """Ensure that a gathering future refuses to be cancelled once all children are done""" diff --git a/Lib/test/test_asyncio/test_waitfor.py b/Lib/test/test_asyncio/test_waitfor.py index b00815e153110..874aabf9bd715 100644 --- a/Lib/test/test_asyncio/test_waitfor.py +++ b/Lib/test/test_asyncio/test_waitfor.py @@ -264,6 +264,30 @@ async def inner(): self.assertEqual(await inner_task, 42) + async def _test_cancel_wait_for(self, timeout): + loop = asyncio.get_running_loop() + + async def blocking_coroutine(): + fut = loop.create_future() + # Block: fut result is never set + await fut + + task = asyncio.create_task(blocking_coroutine()) + + wait = asyncio.create_task(asyncio.wait_for(task, timeout)) + loop.call_soon(wait.cancel) + + with self.assertRaises(asyncio.CancelledError): + await wait + + # Python issue #23219: cancelling the wait must also cancel the task + self.assertTrue(task.cancelled()) + + async def test_cancel_blocking_wait_for(self): + await self._test_cancel_wait_for(None) + + async def test_cancel_wait_for(self): + await self._test_cancel_wait_for(60.0) if __name__ == '__main__': From webhook-mailer at python.org Wed Mar 16 19:44:31 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 16 Mar 2022 23:44:31 -0000 Subject: [Python-checkins] bpo-47038: Rewrite missed asyncio.wait_for test to use IsolatedAnsyncioTestCase (GH-31946) Message-ID: https://github.com/python/cpython/commit/0412e3ae03a694af1e27d4af61ca503a6513394d commit: 0412e3ae03a694af1e27d4af61ca503a6513394d branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-16T16:44:22-07:00 summary: bpo-47038: Rewrite missed asyncio.wait_for test to use IsolatedAnsyncioTestCase (GH-31946) (cherry picked from commit 3dd9bfac04d3dcdbfd3f8011a6c9d4b9ac8c116a) Co-authored-by: Andrew Svetlov files: M Lib/test/test_asyncio/test_tasks.py M Lib/test/test_asyncio/test_waitfor.py diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 58f8d49d02b77..f311876acdeb3 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -2188,32 +2188,6 @@ def test_task_source_traceback(self): 'test_task_source_traceback')) self.loop.run_until_complete(task) - def _test_cancel_wait_for(self, timeout): - loop = asyncio.new_event_loop() - self.addCleanup(loop.close) - - async def blocking_coroutine(): - fut = self.new_future(loop) - # Block: fut result is never set - await fut - - task = loop.create_task(blocking_coroutine()) - - wait = loop.create_task(asyncio.wait_for(task, timeout)) - loop.call_soon(wait.cancel) - - self.assertRaises(asyncio.CancelledError, - loop.run_until_complete, wait) - - # Python issue #23219: cancelling the wait must also cancel the task - self.assertTrue(task.cancelled()) - - def test_cancel_blocking_wait_for(self): - self._test_cancel_wait_for(None) - - def test_cancel_wait_for(self): - self._test_cancel_wait_for(60.0) - def test_cancel_gather_1(self): """Ensure that a gathering future refuses to be cancelled once all children are done""" diff --git a/Lib/test/test_asyncio/test_waitfor.py b/Lib/test/test_asyncio/test_waitfor.py index b00815e153110..874aabf9bd715 100644 --- a/Lib/test/test_asyncio/test_waitfor.py +++ b/Lib/test/test_asyncio/test_waitfor.py @@ -264,6 +264,30 @@ async def inner(): self.assertEqual(await inner_task, 42) + async def _test_cancel_wait_for(self, timeout): + loop = asyncio.get_running_loop() + + async def blocking_coroutine(): + fut = loop.create_future() + # Block: fut result is never set + await fut + + task = asyncio.create_task(blocking_coroutine()) + + wait = asyncio.create_task(asyncio.wait_for(task, timeout)) + loop.call_soon(wait.cancel) + + with self.assertRaises(asyncio.CancelledError): + await wait + + # Python issue #23219: cancelling the wait must also cancel the task + self.assertTrue(task.cancelled()) + + async def test_cancel_blocking_wait_for(self): + await self._test_cancel_wait_for(None) + + async def test_cancel_wait_for(self): + await self._test_cancel_wait_for(60.0) if __name__ == '__main__': From webhook-mailer at python.org Wed Mar 16 20:19:56 2022 From: webhook-mailer at python.org (asvetlov) Date: Thu, 17 Mar 2022 00:19:56 -0000 Subject: [Python-checkins] bpo-47038: Rewrite missed asyncio.wait_for test to use IsolatedAnsyncioTestCase (GH-31946) (#31948) Message-ID: https://github.com/python/cpython/commit/36f62c55759c4246f969f60f7470ba756f77b268 commit: 36f62c55759c4246f969f60f7470ba756f77b268 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: asvetlov date: 2022-03-17T02:19:51+02:00 summary: bpo-47038: Rewrite missed asyncio.wait_for test to use IsolatedAnsyncioTestCase (GH-31946) (#31948) (cherry picked from commit 3dd9bfac04d3dcdbfd3f8011a6c9d4b9ac8c116a) Co-authored-by: Andrew Svetlov Co-authored-by: Andrew Svetlov files: M Lib/test/test_asyncio/test_tasks.py M Lib/test/test_asyncio/test_waitfor.py diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 7f3cf8b56ba66..0007b44a220c4 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -2292,32 +2292,6 @@ def test_task_source_traceback(self): 'test_task_source_traceback')) self.loop.run_until_complete(task) - def _test_cancel_wait_for(self, timeout): - loop = asyncio.new_event_loop() - self.addCleanup(loop.close) - - async def blocking_coroutine(): - fut = self.new_future(loop) - # Block: fut result is never set - await fut - - task = loop.create_task(blocking_coroutine()) - - wait = loop.create_task(asyncio.wait_for(task, timeout)) - loop.call_soon(wait.cancel) - - self.assertRaises(asyncio.CancelledError, - loop.run_until_complete, wait) - - # Python issue #23219: cancelling the wait must also cancel the task - self.assertTrue(task.cancelled()) - - def test_cancel_blocking_wait_for(self): - self._test_cancel_wait_for(None) - - def test_cancel_wait_for(self): - self._test_cancel_wait_for(60.0) - def test_cancel_gather_1(self): """Ensure that a gathering future refuses to be cancelled once all children are done""" diff --git a/Lib/test/test_asyncio/test_waitfor.py b/Lib/test/test_asyncio/test_waitfor.py index b00815e153110..874aabf9bd715 100644 --- a/Lib/test/test_asyncio/test_waitfor.py +++ b/Lib/test/test_asyncio/test_waitfor.py @@ -264,6 +264,30 @@ async def inner(): self.assertEqual(await inner_task, 42) + async def _test_cancel_wait_for(self, timeout): + loop = asyncio.get_running_loop() + + async def blocking_coroutine(): + fut = loop.create_future() + # Block: fut result is never set + await fut + + task = asyncio.create_task(blocking_coroutine()) + + wait = asyncio.create_task(asyncio.wait_for(task, timeout)) + loop.call_soon(wait.cancel) + + with self.assertRaises(asyncio.CancelledError): + await wait + + # Python issue #23219: cancelling the wait must also cancel the task + self.assertTrue(task.cancelled()) + + async def test_cancel_blocking_wait_for(self): + await self._test_cancel_wait_for(None) + + async def test_cancel_wait_for(self): + await self._test_cancel_wait_for(60.0) if __name__ == '__main__': From webhook-mailer at python.org Wed Mar 16 20:54:45 2022 From: webhook-mailer at python.org (asvetlov) Date: Thu, 17 Mar 2022 00:54:45 -0000 Subject: [Python-checkins] bpo-47038: Increase a test timeout for slow CI machines (GH-31951) Message-ID: https://github.com/python/cpython/commit/a7c54148322781cb0f332d440a3454d550ef6414 commit: a7c54148322781cb0f332d440a3454d550ef6414 branch: main author: Andrew Svetlov committer: asvetlov date: 2022-03-17T02:54:36+02:00 summary: bpo-47038: Increase a test timeout for slow CI machines (GH-31951) files: M Lib/test/test_asyncio/test_waitfor.py diff --git a/Lib/test/test_asyncio/test_waitfor.py b/Lib/test/test_asyncio/test_waitfor.py index 874aabf9bd715..45498fa097f6b 100644 --- a/Lib/test/test_asyncio/test_waitfor.py +++ b/Lib/test/test_asyncio/test_waitfor.py @@ -144,7 +144,7 @@ async def foo(): self.assertTrue(fut.done()) # it should have been cancelled due to the timeout self.assertTrue(fut.cancelled()) - self.assertLess(t1 - t0, 0.2) + self.assertLess(t1 - t0, 0.5) self.assertEqual(foo_running, False) async def test_wait_for_blocking(self): From webhook-mailer at python.org Wed Mar 16 21:03:16 2022 From: webhook-mailer at python.org (asvetlov) Date: Thu, 17 Mar 2022 01:03:16 -0000 Subject: [Python-checkins] bpo-47039: Normalize repr() of asyncio future and task objects (GH-31950) Message-ID: https://github.com/python/cpython/commit/30b5d41fabad04f9f34d603f1ce2249452c18c71 commit: 30b5d41fabad04f9f34d603f1ce2249452c18c71 branch: main author: Andrew Svetlov committer: asvetlov date: 2022-03-17T03:03:09+02:00 summary: bpo-47039: Normalize repr() of asyncio future and task objects (GH-31950) files: A Misc/NEWS.d/next/Library/2022-03-17-01-54-13.bpo-47039.0Yxv0K.rst M Lib/asyncio/base_futures.py M Lib/asyncio/base_tasks.py M Lib/asyncio/futures.py M Lib/asyncio/tasks.py M Modules/_asynciomodule.c M Modules/clinic/_asynciomodule.c.h diff --git a/Lib/asyncio/base_futures.py b/Lib/asyncio/base_futures.py index 2c01ac98e10fc..cd811a788cb6d 100644 --- a/Lib/asyncio/base_futures.py +++ b/Lib/asyncio/base_futures.py @@ -42,16 +42,6 @@ def format_cb(callback): return f'cb=[{cb}]' -# bpo-42183: _repr_running is needed for repr protection -# when a Future or Task result contains itself directly or indirectly. -# The logic is borrowed from @reprlib.recursive_repr decorator. -# Unfortunately, the direct decorator usage is impossible because of -# AttributeError: '_asyncio.Task' object has no attribute '__module__' error. -# -# After fixing this thing we can return to the decorator based approach. -_repr_running = set() - - def _future_repr_info(future): # (Future) -> str """helper function for Future.__repr__""" @@ -60,17 +50,9 @@ def _future_repr_info(future): if future._exception is not None: info.append(f'exception={future._exception!r}') else: - key = id(future), get_ident() - if key in _repr_running: - result = '...' - else: - _repr_running.add(key) - try: - # use reprlib to limit the length of the output, especially - # for very long strings - result = reprlib.repr(future._result) - finally: - _repr_running.discard(key) + # use reprlib to limit the length of the output, especially + # for very long strings + result = reprlib.repr(future._result) info.append(f'result={result}') if future._callbacks: info.append(_format_callbacks(future._callbacks)) @@ -78,3 +60,9 @@ def _future_repr_info(future): frame = future._source_traceback[-1] info.append(f'created at {frame[0]}:{frame[1]}') return info + + + at reprlib.recursive_repr() +def _future_repr(future): + info = ' '.join(_future_repr_info(future)) + return f'<{future.__class__.__name__} {info}>' diff --git a/Lib/asyncio/base_tasks.py b/Lib/asyncio/base_tasks.py index 1d623899f69a9..26298e638cbf0 100644 --- a/Lib/asyncio/base_tasks.py +++ b/Lib/asyncio/base_tasks.py @@ -1,4 +1,5 @@ import linecache +import reprlib import traceback from . import base_futures @@ -22,6 +23,12 @@ def _task_repr_info(task): return info + at reprlib.recursive_repr() +def _task_repr(task): + info = ' '.join(_task_repr_info(task)) + return f'<{task.__class__.__name__} {info}>' + + def _task_get_stack(task, limit): frames = [] if hasattr(task._coro, 'cr_frame'): diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py index 5a92f1769fa9f..bfd4ee926f028 100644 --- a/Lib/asyncio/futures.py +++ b/Lib/asyncio/futures.py @@ -85,11 +85,8 @@ def __init__(self, *, loop=None): self._source_traceback = format_helpers.extract_stack( sys._getframe(1)) - _repr_info = base_futures._future_repr_info - def __repr__(self): - return '<{} {}>'.format(self.__class__.__name__, - ' '.join(self._repr_info())) + return base_futures._future_repr(self) def __del__(self): if not self.__log_traceback: diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index b4f1eed91a932..0b5f3226802de 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -133,8 +133,8 @@ def __del__(self): __class_getitem__ = classmethod(GenericAlias) - def _repr_info(self): - return base_tasks._task_repr_info(self) + def __repr__(self): + return base_tasks._task_repr(self) def get_coro(self): return self._coro diff --git a/Misc/NEWS.d/next/Library/2022-03-17-01-54-13.bpo-47039.0Yxv0K.rst b/Misc/NEWS.d/next/Library/2022-03-17-01-54-13.bpo-47039.0Yxv0K.rst new file mode 100644 index 0000000000000..66785e1617c7c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-17-01-54-13.bpo-47039.0Yxv0K.rst @@ -0,0 +1 @@ +Normalize ``repr()`` of asyncio future and task objects. diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 4b12744e625e1..24119782d9c4d 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -29,11 +29,11 @@ _Py_IDENTIFIER(throw); static PyObject *asyncio_mod; static PyObject *traceback_extract_stack; static PyObject *asyncio_get_event_loop_policy; -static PyObject *asyncio_future_repr_info_func; +static PyObject *asyncio_future_repr_func; static PyObject *asyncio_iscoroutine_func; static PyObject *asyncio_task_get_stack_func; static PyObject *asyncio_task_print_stack_func; -static PyObject *asyncio_task_repr_info_func; +static PyObject *asyncio_task_repr_func; static PyObject *asyncio_InvalidStateError; static PyObject *asyncio_CancelledError; static PyObject *context_kwname; @@ -1360,6 +1360,13 @@ FutureObj_get_state(FutureObj *fut, void *Py_UNUSED(ignored)) return ret; } +static PyObject * +FutureObj_repr(FutureObj *fut) +{ + ENSURE_FUTURE_ALIVE(fut) + return PyObject_CallOneArg(asyncio_future_repr_func, (PyObject *)fut); +} + /*[clinic input] _asyncio.Future._make_cancelled_error @@ -1376,42 +1383,6 @@ _asyncio_Future__make_cancelled_error_impl(FutureObj *self) return create_cancelled_error(self); } -/*[clinic input] -_asyncio.Future._repr_info -[clinic start generated code]*/ - -static PyObject * -_asyncio_Future__repr_info_impl(FutureObj *self) -/*[clinic end generated code: output=fa69e901bd176cfb input=f21504d8e2ae1ca2]*/ -{ - return PyObject_CallOneArg(asyncio_future_repr_info_func, (PyObject *)self); -} - -static PyObject * -FutureObj_repr(FutureObj *fut) -{ - _Py_IDENTIFIER(_repr_info); - - ENSURE_FUTURE_ALIVE(fut) - - PyObject *rinfo = _PyObject_CallMethodIdNoArgs((PyObject*)fut, - &PyId__repr_info); - if (rinfo == NULL) { - return NULL; - } - - PyObject *rinfo_s = PyUnicode_Join(NULL, rinfo); - Py_DECREF(rinfo); - if (rinfo_s == NULL) { - return NULL; - } - - PyObject *rstr = PyUnicode_FromFormat("<%s %U>", - _PyType_Name(Py_TYPE(fut)), rinfo_s); - Py_DECREF(rinfo_s); - return rstr; -} - static void FutureObj_finalize(FutureObj *fut) { @@ -1497,7 +1468,6 @@ static PyMethodDef FutureType_methods[] = { _ASYNCIO_FUTURE_DONE_METHODDEF _ASYNCIO_FUTURE_GET_LOOP_METHODDEF _ASYNCIO_FUTURE__MAKE_CANCELLED_ERROR_METHODDEF - _ASYNCIO_FUTURE__REPR_INFO_METHODDEF {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, {NULL, NULL} /* Sentinel */ }; @@ -2145,6 +2115,13 @@ TaskObj_get_fut_waiter(TaskObj *task, void *Py_UNUSED(ignored)) Py_RETURN_NONE; } +static PyObject * +TaskObj_repr(TaskObj *task) +{ + return PyObject_CallOneArg(asyncio_task_repr_func, (PyObject *)task); +} + + /*[clinic input] _asyncio.Task._make_cancelled_error @@ -2163,17 +2140,6 @@ _asyncio_Task__make_cancelled_error_impl(TaskObj *self) } -/*[clinic input] -_asyncio.Task._repr_info -[clinic start generated code]*/ - -static PyObject * -_asyncio_Task__repr_info_impl(TaskObj *self) -/*[clinic end generated code: output=6a490eb66d5ba34b input=3c6d051ed3ddec8b]*/ -{ - return PyObject_CallOneArg(asyncio_task_repr_info_func, (PyObject *)self); -} - /*[clinic input] _asyncio.Task.cancel @@ -2514,7 +2480,6 @@ static PyMethodDef TaskType_methods[] = { _ASYNCIO_TASK_GET_STACK_METHODDEF _ASYNCIO_TASK_PRINT_STACK_METHODDEF _ASYNCIO_TASK__MAKE_CANCELLED_ERROR_METHODDEF - _ASYNCIO_TASK__REPR_INFO_METHODDEF _ASYNCIO_TASK_GET_NAME_METHODDEF _ASYNCIO_TASK_SET_NAME_METHODDEF _ASYNCIO_TASK_GET_CORO_METHODDEF @@ -2539,7 +2504,7 @@ static PyTypeObject TaskType = { .tp_base = &FutureType, .tp_dealloc = TaskObj_dealloc, .tp_as_async = &FutureType_as_async, - .tp_repr = (reprfunc)FutureObj_repr, + .tp_repr = (reprfunc)TaskObj_repr, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, .tp_doc = _asyncio_Task___init____doc__, .tp_traverse = (traverseproc)TaskObj_traverse, @@ -3337,12 +3302,12 @@ module_free(void *m) { Py_CLEAR(asyncio_mod); Py_CLEAR(traceback_extract_stack); - Py_CLEAR(asyncio_future_repr_info_func); + Py_CLEAR(asyncio_future_repr_func); Py_CLEAR(asyncio_get_event_loop_policy); Py_CLEAR(asyncio_iscoroutine_func); Py_CLEAR(asyncio_task_get_stack_func); Py_CLEAR(asyncio_task_print_stack_func); - Py_CLEAR(asyncio_task_repr_info_func); + Py_CLEAR(asyncio_task_repr_func); Py_CLEAR(asyncio_InvalidStateError); Py_CLEAR(asyncio_CancelledError); @@ -3403,14 +3368,14 @@ module_init(void) GET_MOD_ATTR(asyncio_get_event_loop_policy, "get_event_loop_policy") WITH_MOD("asyncio.base_futures") - GET_MOD_ATTR(asyncio_future_repr_info_func, "_future_repr_info") + GET_MOD_ATTR(asyncio_future_repr_func, "_future_repr") WITH_MOD("asyncio.exceptions") GET_MOD_ATTR(asyncio_InvalidStateError, "InvalidStateError") GET_MOD_ATTR(asyncio_CancelledError, "CancelledError") WITH_MOD("asyncio.base_tasks") - GET_MOD_ATTR(asyncio_task_repr_info_func, "_task_repr_info") + GET_MOD_ATTR(asyncio_task_repr_func, "_task_repr") GET_MOD_ATTR(asyncio_task_get_stack_func, "_task_get_stack") GET_MOD_ATTR(asyncio_task_print_stack_func, "_task_print_stack") diff --git a/Modules/clinic/_asynciomodule.c.h b/Modules/clinic/_asynciomodule.c.h index 4a90dfa67c22b..4b64367a3f631 100644 --- a/Modules/clinic/_asynciomodule.c.h +++ b/Modules/clinic/_asynciomodule.c.h @@ -292,23 +292,6 @@ _asyncio_Future__make_cancelled_error(FutureObj *self, PyObject *Py_UNUSED(ignor return _asyncio_Future__make_cancelled_error_impl(self); } -PyDoc_STRVAR(_asyncio_Future__repr_info__doc__, -"_repr_info($self, /)\n" -"--\n" -"\n"); - -#define _ASYNCIO_FUTURE__REPR_INFO_METHODDEF \ - {"_repr_info", (PyCFunction)_asyncio_Future__repr_info, METH_NOARGS, _asyncio_Future__repr_info__doc__}, - -static PyObject * -_asyncio_Future__repr_info_impl(FutureObj *self); - -static PyObject * -_asyncio_Future__repr_info(FutureObj *self, PyObject *Py_UNUSED(ignored)) -{ - return _asyncio_Future__repr_info_impl(self); -} - PyDoc_STRVAR(_asyncio_Task___init____doc__, "Task(coro, *, loop=None, name=None, context=None)\n" "--\n" @@ -383,23 +366,6 @@ _asyncio_Task__make_cancelled_error(TaskObj *self, PyObject *Py_UNUSED(ignored)) return _asyncio_Task__make_cancelled_error_impl(self); } -PyDoc_STRVAR(_asyncio_Task__repr_info__doc__, -"_repr_info($self, /)\n" -"--\n" -"\n"); - -#define _ASYNCIO_TASK__REPR_INFO_METHODDEF \ - {"_repr_info", (PyCFunction)_asyncio_Task__repr_info, METH_NOARGS, _asyncio_Task__repr_info__doc__}, - -static PyObject * -_asyncio_Task__repr_info_impl(TaskObj *self); - -static PyObject * -_asyncio_Task__repr_info(TaskObj *self, PyObject *Py_UNUSED(ignored)) -{ - return _asyncio_Task__repr_info_impl(self); -} - PyDoc_STRVAR(_asyncio_Task_cancel__doc__, "cancel($self, /, msg=None)\n" "--\n" @@ -924,4 +890,4 @@ _asyncio__leave_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, exit: return return_value; } -/*[clinic end generated code: output=540ed3caf5a4d57d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=64b3836574e8a18c input=a9049054013a1b77]*/ From webhook-mailer at python.org Wed Mar 16 21:19:37 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 17 Mar 2022 01:19:37 -0000 Subject: [Python-checkins] bpo-47038: Increase a test timeout for slow CI machines (GH-31951) Message-ID: https://github.com/python/cpython/commit/4e9bb27eaeb8bedcec6f25f4345824b50fc25337 commit: 4e9bb27eaeb8bedcec6f25f4345824b50fc25337 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-16T18:19:18-07:00 summary: bpo-47038: Increase a test timeout for slow CI machines (GH-31951) (cherry picked from commit a7c54148322781cb0f332d440a3454d550ef6414) Co-authored-by: Andrew Svetlov files: M Lib/test/test_asyncio/test_waitfor.py diff --git a/Lib/test/test_asyncio/test_waitfor.py b/Lib/test/test_asyncio/test_waitfor.py index 874aabf9bd715..45498fa097f6b 100644 --- a/Lib/test/test_asyncio/test_waitfor.py +++ b/Lib/test/test_asyncio/test_waitfor.py @@ -144,7 +144,7 @@ async def foo(): self.assertTrue(fut.done()) # it should have been cancelled due to the timeout self.assertTrue(fut.cancelled()) - self.assertLess(t1 - t0, 0.2) + self.assertLess(t1 - t0, 0.5) self.assertEqual(foo_running, False) async def test_wait_for_blocking(self): From webhook-mailer at python.org Wed Mar 16 21:20:14 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 17 Mar 2022 01:20:14 -0000 Subject: [Python-checkins] bpo-47038: Increase a test timeout for slow CI machines (GH-31951) Message-ID: https://github.com/python/cpython/commit/ba76f901923d80ad9b24bb1636aa751d55e0c768 commit: ba76f901923d80ad9b24bb1636aa751d55e0c768 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-16T18:20:02-07:00 summary: bpo-47038: Increase a test timeout for slow CI machines (GH-31951) (cherry picked from commit a7c54148322781cb0f332d440a3454d550ef6414) Co-authored-by: Andrew Svetlov files: M Lib/test/test_asyncio/test_waitfor.py diff --git a/Lib/test/test_asyncio/test_waitfor.py b/Lib/test/test_asyncio/test_waitfor.py index 874aabf9bd715..45498fa097f6b 100644 --- a/Lib/test/test_asyncio/test_waitfor.py +++ b/Lib/test/test_asyncio/test_waitfor.py @@ -144,7 +144,7 @@ async def foo(): self.assertTrue(fut.done()) # it should have been cancelled due to the timeout self.assertTrue(fut.cancelled()) - self.assertLess(t1 - t0, 0.2) + self.assertLess(t1 - t0, 0.5) self.assertEqual(foo_running, False) async def test_wait_for_blocking(self): From webhook-mailer at python.org Wed Mar 16 22:41:26 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Thu, 17 Mar 2022 02:41:26 -0000 Subject: [Python-checkins] bpo-22859: deprecate unittest.main.TestProgram.usageExit (GH-30293) Message-ID: https://github.com/python/cpython/commit/7c353b7594545fb9403b3123a17ad06cadc2f73d commit: 7c353b7594545fb9403b3123a17ad06cadc2f73d branch: main author: Carlos Damazio committer: JelleZijlstra date: 2022-03-16T19:41:02-07:00 summary: bpo-22859: deprecate unittest.main.TestProgram.usageExit (GH-30293) Co-authored-by: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> Co-authored-by: Jelle Zijlstra files: A Misc/NEWS.d/next/Library/2021-12-29-19-37-49.bpo-22859.AixHW7.rst M Lib/unittest/main.py diff --git a/Lib/unittest/main.py b/Lib/unittest/main.py index e62469aa2a170..cb8f1f302801d 100644 --- a/Lib/unittest/main.py +++ b/Lib/unittest/main.py @@ -3,6 +3,7 @@ import sys import argparse import os +import warnings from . import loader, runner from .signals import installHandler @@ -101,6 +102,8 @@ def __init__(self, module='__main__', defaultTest=None, argv=None, self.runTests() def usageExit(self, msg=None): + warnings.warn("TestProgram.usageExit() is deprecated and will be" + " removed in Python 3.13", DeprecationWarning) if msg: print(msg) if self._discovery_parser is None: diff --git a/Misc/NEWS.d/next/Library/2021-12-29-19-37-49.bpo-22859.AixHW7.rst b/Misc/NEWS.d/next/Library/2021-12-29-19-37-49.bpo-22859.AixHW7.rst new file mode 100644 index 0000000000000..f6380b0f904e8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-12-29-19-37-49.bpo-22859.AixHW7.rst @@ -0,0 +1 @@ +:meth:`~unittest.TestProgram.usageExit` is marked deprecated, to be removed in 3.13. From webhook-mailer at python.org Wed Mar 16 23:02:40 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Thu, 17 Mar 2022 03:02:40 -0000 Subject: [Python-checkins] bpo-46480: add typing.assert_type (GH-30843) Message-ID: https://github.com/python/cpython/commit/96568e995d840c66edb25b6b9d85e4dcccf5a936 commit: 96568e995d840c66edb25b6b9d85e4dcccf5a936 branch: main author: Jelle Zijlstra committer: JelleZijlstra date: 2022-03-16T20:02:26-07:00 summary: bpo-46480: add typing.assert_type (GH-30843) Co-authored-by: Alex Waygood Co-authored-by: David Foster files: A Misc/NEWS.d/next/Library/2022-01-23-16-33-07.bpo-46480.E4jHlh.rst M Doc/library/typing.rst M Lib/test/test_typing.py M Lib/typing.py diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index c7c2cd6866b70..57979cbb08e69 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -2148,6 +2148,31 @@ Functions and decorators runtime we intentionally don't check anything (we want this to be as fast as possible). +.. function:: assert_type(val, typ, /) + + Assert (to the type checker) that *val* has an inferred type of *typ*. + + When the type checker encounters a call to ``assert_type()``, it + emits an error if the value is not of the specified type:: + + def greet(name: str) -> None: + assert_type(name, str) # OK, inferred type of `name` is `str` + assert_type(name, int) # type checker error + + At runtime this returns the first argument unchanged with no side effects. + + This function is useful for ensuring the type checker's understanding of a + script is in line with the developer's intentions:: + + def complex_function(arg: object): + # Do some complex type-narrowing logic, + # after which we hope the inferred type will be `int` + ... + # Test whether the type checker correctly understands our function + assert_type(arg, int) + + .. versionadded:: 3.11 + .. function:: assert_never(arg, /) Assert to the type checker that a line of code is unreachable. diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index b212b52304880..e88f7322b2fa8 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -16,7 +16,7 @@ from typing import Tuple, List, Dict, MutableMapping from typing import Callable from typing import Generic, ClassVar, Final, final, Protocol -from typing import cast, runtime_checkable +from typing import assert_type, cast, runtime_checkable from typing import get_type_hints from typing import get_origin, get_args from typing import is_typeddict @@ -3302,6 +3302,22 @@ def test_errors(self): cast('hello', 42) +class AssertTypeTests(BaseTestCase): + + def test_basics(self): + arg = 42 + self.assertIs(assert_type(arg, int), arg) + self.assertIs(assert_type(arg, str | float), arg) + self.assertIs(assert_type(arg, AnyStr), arg) + self.assertIs(assert_type(arg, None), arg) + + def test_errors(self): + # Bogus calls are not expected to fail. + arg = 42 + self.assertIs(assert_type(arg, 42), arg) + self.assertIs(assert_type(arg, 'hello'), arg) + + # We need this to make sure that `@no_type_check` respects `__module__` attr: from test import ann_module8 diff --git a/Lib/typing.py b/Lib/typing.py index dd68e71db1558..6930f5ddac42a 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -118,6 +118,7 @@ def _idfunc(_, x): # One-off things. 'AnyStr', + 'assert_type', 'assert_never', 'cast', 'final', @@ -2093,6 +2094,22 @@ def cast(typ, val): return val +def assert_type(val, typ, /): + """Assert (to the type checker) that the value is of the given type. + + When the type checker encounters a call to assert_type(), it + emits an error if the value is not of the specified type:: + + def greet(name: str) -> None: + assert_type(name, str) # ok + assert_type(name, int) # type checker error + + At runtime this returns the first argument unchanged and otherwise + does nothing. + """ + return val + + _allowed_types = (types.FunctionType, types.BuiltinFunctionType, types.MethodType, types.ModuleType, WrapperDescriptorType, MethodWrapperType, MethodDescriptorType) diff --git a/Misc/NEWS.d/next/Library/2022-01-23-16-33-07.bpo-46480.E4jHlh.rst b/Misc/NEWS.d/next/Library/2022-01-23-16-33-07.bpo-46480.E4jHlh.rst new file mode 100644 index 0000000000000..fd18a8198edea --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-01-23-16-33-07.bpo-46480.E4jHlh.rst @@ -0,0 +1 @@ +Add :func:`typing.assert_type`. Patch by Jelle Zijlstra. From webhook-mailer at python.org Thu Mar 17 01:58:29 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Thu, 17 Mar 2022 05:58:29 -0000 Subject: [Python-checkins] bpo-44859: Raise more accurate exceptions in `sqlite3` (GH-27695) Message-ID: https://github.com/python/cpython/commit/4674fd4e938eb4a29ccd5b12c15455bd2a41c335 commit: 4674fd4e938eb4a29ccd5b12c15455bd2a41c335 branch: main author: Erlend Egeberg Aasland committer: JelleZijlstra date: 2022-03-16T22:58:25-07:00 summary: bpo-44859: Raise more accurate exceptions in `sqlite3` (GH-27695) * Improve exception compliance with PEP 249 * Raise InterfaceError instead of ProgrammingError for SQLITE_MISUSE. If SQLITE_MISUSE is raised, it is a sqlite3 module bug. Users of the sqlite3 module are not responsible for using the SQLite C API correctly. * Don't overwrite BufferError with ValueError when conversion to BLOB fails. * Raise ProgrammingError instead of Warning if user tries to execute() more than one SQL statement. * Raise ProgrammingError instead of ValueError if an SQL query contains null characters. * Make sure `_pysqlite_set_result` raises an exception if it returns -1. files: A Misc/NEWS.d/next/Library/2021-08-10-00-05-53.bpo-44859.9e9_3V.rst M Lib/test/test_sqlite3/test_dbapi.py M Lib/test/test_sqlite3/test_regression.py M Lib/test/test_sqlite3/test_userfunctions.py M Modules/_sqlite/connection.c M Modules/_sqlite/statement.c diff --git a/Lib/test/test_sqlite3/test_dbapi.py b/Lib/test/test_sqlite3/test_dbapi.py index 4eb4e180bf117..177c2cd327ff3 100644 --- a/Lib/test/test_sqlite3/test_dbapi.py +++ b/Lib/test/test_sqlite3/test_dbapi.py @@ -652,8 +652,9 @@ def test_execute_illegal_sql(self): self.cu.execute("select asdf") def test_execute_too_much_sql(self): - with self.assertRaises(sqlite.Warning): - self.cu.execute("select 5+4; select 4+5") + self.assertRaisesRegex(sqlite.ProgrammingError, + "You can only execute one statement at a time", + self.cu.execute, "select 5+4; select 4+5") def test_execute_too_much_sql2(self): self.cu.execute("select 5+4; -- foo bar") diff --git a/Lib/test/test_sqlite3/test_regression.py b/Lib/test/test_sqlite3/test_regression.py index 211f7636b746d..aebea59b9e5bb 100644 --- a/Lib/test/test_sqlite3/test_regression.py +++ b/Lib/test/test_sqlite3/test_regression.py @@ -319,12 +319,15 @@ def test_invalid_isolation_level_type(self): def test_null_character(self): # Issue #21147 - con = sqlite.connect(":memory:") - self.assertRaises(ValueError, con, "\0select 1") - self.assertRaises(ValueError, con, "select 1\0") - cur = con.cursor() - self.assertRaises(ValueError, cur.execute, " \0select 2") - self.assertRaises(ValueError, cur.execute, "select 2\0") + cur = self.con.cursor() + queries = ["\0select 1", "select 1\0"] + for query in queries: + with self.subTest(query=query): + self.assertRaisesRegex(sqlite.ProgrammingError, "null char", + self.con.execute, query) + with self.subTest(query=query): + self.assertRaisesRegex(sqlite.ProgrammingError, "null char", + cur.execute, query) def test_surrogates(self): con = sqlite.connect(":memory:") diff --git a/Lib/test/test_sqlite3/test_userfunctions.py b/Lib/test/test_sqlite3/test_userfunctions.py index 2588cae3d1f15..9070c9e01b25a 100644 --- a/Lib/test/test_sqlite3/test_userfunctions.py +++ b/Lib/test/test_sqlite3/test_userfunctions.py @@ -196,6 +196,8 @@ def setUp(self): self.con.create_function("returnlonglong", 0, func_returnlonglong) self.con.create_function("returnnan", 0, lambda: float("nan")) self.con.create_function("returntoolargeint", 0, lambda: 1 << 65) + self.con.create_function("return_noncont_blob", 0, + lambda: memoryview(b"blob")[::2]) self.con.create_function("raiseexception", 0, func_raiseexception) self.con.create_function("memoryerror", 0, func_memoryerror) self.con.create_function("overflowerror", 0, func_overflowerror) @@ -340,10 +342,17 @@ def test_too_large_int(self): "select spam(?)", (1 << 65,)) def test_non_contiguous_blob(self): - self.assertRaisesRegex(ValueError, "could not convert BLOB to buffer", + self.assertRaisesRegex(BufferError, + "underlying buffer is not C-contiguous", self.con.execute, "select spam(?)", (memoryview(b"blob")[::2],)) + @with_tracebacks(BufferError, regex="buffer.*contiguous") + def test_return_non_contiguous_blob(self): + with self.assertRaises(sqlite.OperationalError): + cur = self.con.execute("select return_noncont_blob()") + cur.fetchone() + def test_param_surrogates(self): self.assertRaisesRegex(UnicodeEncodeError, "surrogates not allowed", self.con.execute, "select spam(?)", @@ -466,6 +475,12 @@ def test_func_return_too_large_blob(self, size): with self.assertRaises(sqlite.DataError): cur.execute("select largeblob()") + def test_func_return_illegal_value(self): + self.con.create_function("badreturn", 0, lambda: self) + msg = "user-defined function raised exception" + self.assertRaisesRegex(sqlite.OperationalError, msg, + self.con.execute, "select badreturn()") + class AggregateTests(unittest.TestCase): def setUp(self): diff --git a/Misc/NEWS.d/next/Library/2021-08-10-00-05-53.bpo-44859.9e9_3V.rst b/Misc/NEWS.d/next/Library/2021-08-10-00-05-53.bpo-44859.9e9_3V.rst new file mode 100644 index 0000000000000..07d7eb0bafb62 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-08-10-00-05-53.bpo-44859.9e9_3V.rst @@ -0,0 +1,10 @@ +Raise more accurate and :pep:`249` compatible exceptions in :mod:`sqlite3`. + +* Raise :exc:`~sqlite3.InterfaceError` instead of + :exc:`~sqlite3.ProgrammingError` for ``SQLITE_MISUSE`` errors. +* Don't overwrite :exc:`BufferError` with :exc:`ValueError` when conversion to + BLOB fails. +* Raise :exc:`~sqlite3.ProgrammingError` instead of :exc:`~sqlite3.Warning` if + user tries to :meth:`~sqlite3.Cursor.execute()` more than one SQL statement. +* Raise :exc:`~sqlite3.ProgrammingError` instead of :exc:`ValueError` if an SQL + query contains null characters. diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index e4b8ecb5e2d7f..37f6d0fa5a502 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -578,8 +578,6 @@ _pysqlite_set_result(sqlite3_context* context, PyObject* py_val) } else if (PyObject_CheckBuffer(py_val)) { Py_buffer view; if (PyObject_GetBuffer(py_val, &view, PyBUF_SIMPLE) != 0) { - PyErr_SetString(PyExc_ValueError, - "could not convert BLOB to buffer"); return -1; } if (view.len > INT_MAX) { @@ -591,6 +589,11 @@ _pysqlite_set_result(sqlite3_context* context, PyObject* py_val) sqlite3_result_blob(context, view.buf, (int)view.len, SQLITE_TRANSIENT); PyBuffer_Release(&view); } else { + callback_context *ctx = (callback_context *)sqlite3_user_data(context); + PyErr_Format(ctx->state->ProgrammingError, + "User-defined functions cannot return '%s' values to " + "SQLite", + Py_TYPE(py_val)->tp_name); return -1; } return 0; diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index 6885b50f61637..baa1b71a8daa4 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -67,7 +67,7 @@ pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql) return NULL; } if (strlen(sql_cstr) != (size_t)size) { - PyErr_SetString(PyExc_ValueError, + PyErr_SetString(connection->ProgrammingError, "the query contains a null character"); return NULL; } @@ -85,7 +85,7 @@ pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql) } if (pysqlite_check_remaining_sql(tail)) { - PyErr_SetString(connection->Warning, + PyErr_SetString(connection->ProgrammingError, "You can only execute one statement at a time."); goto error; } @@ -190,7 +190,6 @@ int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObjec case TYPE_BUFFER: { Py_buffer view; if (PyObject_GetBuffer(parameter, &view, PyBUF_SIMPLE) != 0) { - PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer"); return -1; } if (view.len > INT_MAX) { From webhook-mailer at python.org Thu Mar 17 03:29:50 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 17 Mar 2022 07:29:50 -0000 Subject: [Python-checkins] bpo-45979: Fix Tkinter tests with old Tk (>= 8.5.12) (GH-31938) Message-ID: https://github.com/python/cpython/commit/612019e60e3a5340542122dabbc7ce5a27a8c635 commit: 612019e60e3a5340542122dabbc7ce5a27a8c635 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-17T00:29:37-07:00 summary: bpo-45979: Fix Tkinter tests with old Tk (>= 8.5.12) (GH-31938) (cherry picked from commit dbbe4d2d0075fa0e95b069fb4780d79aae3514c7) Co-authored-by: Serhiy Storchaka files: M Lib/tkinter/test/test_tkinter/test_widgets.py M Lib/tkinter/test/test_ttk/test_style.py diff --git a/Lib/tkinter/test/test_tkinter/test_widgets.py b/Lib/tkinter/test/test_tkinter/test_widgets.py index cc227e579679b..c0b92bf3b1921 100644 --- a/Lib/tkinter/test/test_tkinter/test_widgets.py +++ b/Lib/tkinter/test/test_tkinter/test_widgets.py @@ -800,7 +800,7 @@ def test_configure_activestyle(self): self.checkEnumParam(widget, 'activestyle', 'dotbox', 'none', 'underline') - test_justify = requires_tcl(8, 6, 5)(StandardOptionsTests.test_configure_justify) + test_configure_justify = requires_tcl(8, 6, 5)(StandardOptionsTests.test_configure_justify) def test_configure_listvariable(self): widget = self.create() @@ -939,7 +939,7 @@ def test_configure_digits(self): def test_configure_from(self): widget = self.create() - conv = False if get_tk_patchlevel() >= (8, 6, 10) else float_round + conv = float if get_tk_patchlevel() >= (8, 6, 10) else float_round self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=conv) def test_configure_label(self): diff --git a/Lib/tkinter/test/test_ttk/test_style.py b/Lib/tkinter/test/test_ttk/test_style.py index a33c24ac55bee..54ad3437168fe 100644 --- a/Lib/tkinter/test/test_ttk/test_style.py +++ b/Lib/tkinter/test/test_ttk/test_style.py @@ -4,7 +4,7 @@ from tkinter import ttk from test import support from test.support import requires -from tkinter.test.support import AbstractTkTest +from tkinter.test.support import AbstractTkTest, get_tk_patchlevel requires('gui') @@ -170,6 +170,8 @@ def test_map_custom_copy(self): newname = f'C.{name}' self.assertEqual(style.map(newname), {}) style.map(newname, **default) + if theme == 'alt' and name == '.' and get_tk_patchlevel() < (8, 6, 1): + default['embossed'] = [('disabled', '1')] self.assertEqual(style.map(newname), default) for key, value in default.items(): self.assertEqual(style.map(newname, key), value) From webhook-mailer at python.org Thu Mar 17 03:52:40 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Thu, 17 Mar 2022 07:52:40 -0000 Subject: [Python-checkins] bpo-46981: Remove typing._TypingEmpty (GH-31836) Message-ID: https://github.com/python/cpython/commit/15df8f8d89a0e563bdd15e4cd6734298736a5a1d commit: 15df8f8d89a0e563bdd15e4cd6734298736a5a1d branch: main author: Serhiy Storchaka committer: serhiy-storchaka date: 2022-03-17T09:52:24+02:00 summary: bpo-46981: Remove typing._TypingEmpty (GH-31836) * get_args(Tuple[()]) now returns () instead of ((),). * Tuple[Unpack[Ts]][()] now returns the result equal to Tuple[()]. files: A Misc/NEWS.d/next/Library/2022-03-12-11-30-42.bpo-46981.ltWCxH.rst M Lib/test/test_typing.py M Lib/typing.py diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index e88f7322b2fa8..bcffdc882dbe6 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -469,14 +469,12 @@ class G(Generic[Unpack[Ts]]): pass for A in G, Tuple: B = A[Unpack[Ts]] - if A != Tuple: - self.assertEqual(B[()], A[()]) + self.assertEqual(B[()], A[()]) self.assertEqual(B[float], A[float]) self.assertEqual(B[float, str], A[float, str]) C = List[A[Unpack[Ts]]] - if A != Tuple: - self.assertEqual(C[()], List[A[()]]) + self.assertEqual(C[()], List[A[()]]) self.assertEqual(C[float], List[A[float]]) self.assertEqual(C[float, str], List[A[float, str]]) @@ -4248,7 +4246,7 @@ class C(Generic[T]): pass self.assertEqual(get_args(Union[int, Callable[[Tuple[T, ...]], str]]), (int, Callable[[Tuple[T, ...]], str])) self.assertEqual(get_args(Tuple[int, ...]), (int, ...)) - self.assertEqual(get_args(Tuple[()]), ((),)) + self.assertEqual(get_args(Tuple[()]), ()) self.assertEqual(get_args(Annotated[T, 'one', 2, ['three']]), (T, 'one', 2, ['three'])) self.assertEqual(get_args(List), ()) self.assertEqual(get_args(Tuple), ()) diff --git a/Lib/typing.py b/Lib/typing.py index 6930f5ddac42a..e8613625c3044 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1220,7 +1220,6 @@ def __init__(self, origin, args, *, inst=True, name=None, if not isinstance(args, tuple): args = (args,) self.__args__ = tuple(... if a is _TypingEllipsis else - () if a is _TypingEmpty else a for a in args) self.__parameters__ = _collect_parameters(args) self._paramspec_tvars = _paramspec_tvars @@ -1503,8 +1502,6 @@ def __getitem_inner__(self, params): class _TupleType(_SpecialGenericAlias, _root=True): @_tp_cache def __getitem__(self, params): - if params == (): - return self.copy_with((_TypingEmpty,)) if not isinstance(params, tuple): params = (params,) if len(params) >= 2 and params[-1] is ...: @@ -1735,13 +1732,6 @@ def __init_subclass__(cls, *args, **kwargs): cls.__parameters__ = tuple(tvars) -class _TypingEmpty: - """Internal placeholder for () or []. Used by TupleMeta and CallableMeta - to allow empty list/tuple in specific places, without allowing them - to sneak in where prohibited. - """ - - class _TypingEllipsis: """Internal placeholder for ... (ellipsis).""" diff --git a/Misc/NEWS.d/next/Library/2022-03-12-11-30-42.bpo-46981.ltWCxH.rst b/Misc/NEWS.d/next/Library/2022-03-12-11-30-42.bpo-46981.ltWCxH.rst new file mode 100644 index 0000000000000..29f7c9376fe36 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-12-11-30-42.bpo-46981.ltWCxH.rst @@ -0,0 +1,2 @@ +``typing.get_args(typing.Tuple[()])`` now returns ``()`` instead of +``((),)``. From webhook-mailer at python.org Thu Mar 17 05:01:06 2022 From: webhook-mailer at python.org (methane) Date: Thu, 17 Mar 2022 09:01:06 -0000 Subject: [Python-checkins] Do not run test_gdb when gdb embeds Python 2. (GH-31956) Message-ID: https://github.com/python/cpython/commit/7aeb06f78ee4abba64ca2c5c7a848fd2616da6fb commit: 7aeb06f78ee4abba64ca2c5c7a848fd2616da6fb branch: main author: Inada Naoki committer: methane date: 2022-03-17T18:00:56+09:00 summary: Do not run test_gdb when gdb embeds Python 2. (GH-31956) files: M Lib/test/test_gdb.py diff --git a/Lib/test/test_gdb.py b/Lib/test/test_gdb.py index 344fd3dd3f7fc..0f39b8f45714a 100644 --- a/Lib/test/test_gdb.py +++ b/Lib/test/test_gdb.py @@ -117,6 +117,9 @@ def run_gdb(*args, **env_vars): if not gdbpy_version: raise unittest.SkipTest("gdb not built with embedded python support") +if "major=2" in gdbpy_version: + raise unittest.SkipTest("gdb built with Python 2") + # Verify that "gdb" can load our custom hooks, as OS security settings may # disallow this without a customized .gdbinit. _, gdbpy_errors = run_gdb('--args', sys.executable) From webhook-mailer at python.org Thu Mar 17 07:06:11 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Thu, 17 Mar 2022 11:06:11 -0000 Subject: [Python-checkins] bpo-46996: Remove support of Tcl/Tk < 8.5.12 (GH-31839) Message-ID: https://github.com/python/cpython/commit/c2e3c06139e9468efb32629d147d99a1672d9e19 commit: c2e3c06139e9468efb32629d147d99a1672d9e19 branch: main author: Serhiy Storchaka committer: serhiy-storchaka date: 2022-03-17T13:05:52+02:00 summary: bpo-46996: Remove support of Tcl/Tk < 8.5.12 (GH-31839) files: A Misc/NEWS.d/next/Build/2022-03-12-18-09-31.bpo-46996.SygzVz.rst M Doc/library/tkinter.ttk.rst M Doc/whatsnew/3.11.rst M Lib/test/test_tcl.py M Lib/tkinter/test/test_tkinter/test_geometry_managers.py M Lib/tkinter/test/test_tkinter/test_widgets.py M Lib/tkinter/test/test_ttk/test_widgets.py M Lib/tkinter/test/widget_tests.py M Lib/tkinter/ttk.py M Modules/_tkinter.c diff --git a/Doc/library/tkinter.ttk.rst b/Doc/library/tkinter.ttk.rst index 2db4c0f9143f6..d50ea99aa46ee 100644 --- a/Doc/library/tkinter.ttk.rst +++ b/Doc/library/tkinter.ttk.rst @@ -13,9 +13,7 @@ -------------- The :mod:`tkinter.ttk` module provides access to the Tk themed widget set, -introduced in Tk 8.5. If Python has not been compiled against Tk 8.5, this -module can still be accessed if *Tile* has been installed. The former -method using Tk 8.5 provides additional benefits including anti-aliased font +introduced in Tk 8.5. It provides additional benefits including anti-aliased font rendering under X11 and window transparency (requiring a composition window manager on X11). diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 9fbf46791c27d..391423407eecd 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -712,6 +712,9 @@ Build Changes be removed at some point in the future. (Contributed by Mark Dickinson in :issue:`45569`.) +* The :mod:`tkinter` package now requires Tcl/Tk version 8.5.12 or newer. + (Contributed by Serhiy Storchaka in :issue:`46996`.) + C API Changes ============= diff --git a/Lib/test/test_tcl.py b/Lib/test/test_tcl.py index 581c31ccb72fd..e73ad596fe678 100644 --- a/Lib/test/test_tcl.py +++ b/Lib/test/test_tcl.py @@ -143,27 +143,18 @@ def testUnsetVarException(self): self.assertRaises(TclError,tcl.unsetvar,'a') def get_integers(self): - integers = (0, 1, -1, 2**31-1, -2**31, 2**31, -2**31-1, 2**63-1, -2**63) - # bignum was added in Tcl 8.5, but its support is able only since 8.5.8. - # Actually it is determined at compile time, so using get_tk_patchlevel() - # is not reliable. - # TODO: expose full static version. - if tcl_version >= (8, 5): - v = get_tk_patchlevel() - if v >= (8, 6, 0, 'final') or (8, 5, 8) <= v < (8, 6): - integers += (2**63, -2**63-1, 2**1000, -2**1000) - return integers + return (0, 1, -1, + 2**31-1, -2**31, 2**31, -2**31-1, + 2**63-1, -2**63, 2**63, -2**63-1, + 2**1000, -2**1000) def test_getint(self): tcl = self.interp.tk for i in self.get_integers(): self.assertEqual(tcl.getint(' %d ' % i), i) - if tcl_version >= (8, 5): - self.assertEqual(tcl.getint(' %#o ' % i), i) + self.assertEqual(tcl.getint(' %#o ' % i), i) self.assertEqual(tcl.getint((' %#o ' % i).replace('o', '')), i) self.assertEqual(tcl.getint(' %#x ' % i), i) - if tcl_version < (8, 5): # bignum was added in Tcl 8.5 - self.assertRaises(TclError, tcl.getint, str(2**1000)) self.assertEqual(tcl.getint(42), 42) self.assertRaises(TypeError, tcl.getint) self.assertRaises(TypeError, tcl.getint, '42', '10') @@ -317,8 +308,7 @@ def check(expr, expected): check('"a\xbd\u20ac"', 'a\xbd\u20ac') check(r'"a\xbd\u20ac"', 'a\xbd\u20ac') check(r'"a\0b"', 'a\x00b') - if tcl_version >= (8, 5): # bignum was added in Tcl 8.5 - check('2**64', str(2**64)) + check('2**64', str(2**64)) def test_exprdouble(self): tcl = self.interp @@ -349,8 +339,7 @@ def check(expr, expected): check('[string length "a\xbd\u20ac"]', 3.0) check(r'[string length "a\xbd\u20ac"]', 3.0) self.assertRaises(TclError, tcl.exprdouble, '"abc"') - if tcl_version >= (8, 5): # bignum was added in Tcl 8.5 - check('2**64', float(2**64)) + check('2**64', float(2**64)) def test_exprlong(self): tcl = self.interp @@ -381,8 +370,7 @@ def check(expr, expected): check('[string length "a\xbd\u20ac"]', 3) check(r'[string length "a\xbd\u20ac"]', 3) self.assertRaises(TclError, tcl.exprlong, '"abc"') - if tcl_version >= (8, 5): # bignum was added in Tcl 8.5 - self.assertRaises(TclError, tcl.exprlong, '2**64') + self.assertRaises(TclError, tcl.exprlong, '2**64') def test_exprboolean(self): tcl = self.interp @@ -422,10 +410,8 @@ def check(expr, expected): check('[string length "a\xbd\u20ac"]', True) check(r'[string length "a\xbd\u20ac"]', True) self.assertRaises(TclError, tcl.exprboolean, '"abc"') - if tcl_version >= (8, 5): # bignum was added in Tcl 8.5 - check('2**64', True) + check('2**64', True) - @unittest.skipUnless(tcl_version >= (8, 5), 'requires Tcl version >= 8.5') def test_booleans(self): tcl = self.interp def check(expr, expected): @@ -455,8 +441,6 @@ def test_expr_bignum(self): else: self.assertEqual(result, str(i)) self.assertIsInstance(result, str) - if get_tk_patchlevel() < (8, 5): # bignum was added in Tcl 8.5 - self.assertRaises(TclError, tcl.call, 'expr', str(2**1000)) def test_passing_values(self): def passValue(value): @@ -485,8 +469,6 @@ def passValue(value): b'str\xbding' if self.wantobjects else 'str\xbding') for i in self.get_integers(): self.assertEqual(passValue(i), i if self.wantobjects else str(i)) - if tcl_version < (8, 5): # bignum was added in Tcl 8.5 - self.assertEqual(passValue(2**1000), str(2**1000)) for f in (0.0, 1.0, -1.0, 1/3, sys.float_info.min, sys.float_info.max, -sys.float_info.min, -sys.float_info.max): @@ -552,8 +534,6 @@ def float_eq(actual, expected): check(b'str\xc0\x80ing\xe2\x82\xac', 'str\xc0\x80ing\xe2\x82\xac') for i in self.get_integers(): check(i, str(i)) - if tcl_version < (8, 5): # bignum was added in Tcl 8.5 - check(2**1000, str(2**1000)) for f in (0.0, 1.0, -1.0): check(f, repr(f)) for f in (1/3.0, sys.float_info.min, sys.float_info.max, @@ -600,16 +580,14 @@ def test_splitlist(self): ('1', '2', '3.4')), ] tk_patchlevel = get_tk_patchlevel() - if tcl_version >= (8, 5): - if not self.wantobjects or tk_patchlevel < (8, 5, 5): - # Before 8.5.5 dicts were converted to lists through string - expected = ('12', '\u20ac', '\xe2\x82\xac', '3.4') - else: - expected = (12, '\u20ac', b'\xe2\x82\xac', (3.4,)) - testcases += [ - (call('dict', 'create', 12, '\u20ac', b'\xe2\x82\xac', (3.4,)), - expected), - ] + if not self.wantobjects: + expected = ('12', '\u20ac', '\xe2\x82\xac', '3.4') + else: + expected = (12, '\u20ac', b'\xe2\x82\xac', (3.4,)) + testcases += [ + (call('dict', 'create', 12, '\u20ac', b'\xe2\x82\xac', (3.4,)), + expected), + ] dbg_info = ('want objects? %s, Tcl version: %s, Tk patchlevel: %s' % (self.wantobjects, tcl_version, tk_patchlevel)) for arg, res in testcases: @@ -642,15 +620,13 @@ def test_splitdict(self): {'a': (1, 2, 3) if self.wantobjects else '1 2 3', 'something': 'foo', 'status': ''}) - if tcl_version >= (8, 5): - arg = tcl.call('dict', 'create', - '-a', (1, 2, 3), '-something', 'foo', 'status', ()) - if not self.wantobjects or get_tk_patchlevel() < (8, 5, 5): - # Before 8.5.5 dicts were converted to lists through string - expected = {'a': '1 2 3', 'something': 'foo', 'status': ''} - else: - expected = {'a': (1, 2, 3), 'something': 'foo', 'status': ''} - self.assertEqual(splitdict(tcl, arg), expected) + arg = tcl.call('dict', 'create', + '-a', (1, 2, 3), '-something', 'foo', 'status', ()) + if not self.wantobjects: + expected = {'a': '1 2 3', 'something': 'foo', 'status': ''} + else: + expected = {'a': (1, 2, 3), 'something': 'foo', 'status': ''} + self.assertEqual(splitdict(tcl, arg), expected) def test_join(self): join = tkinter._join diff --git a/Lib/tkinter/test/test_tkinter/test_geometry_managers.py b/Lib/tkinter/test/test_tkinter/test_geometry_managers.py index c645d430079a5..c89bc8dbf8575 100644 --- a/Lib/tkinter/test/test_tkinter/test_geometry_managers.py +++ b/Lib/tkinter/test/test_tkinter/test_geometry_managers.py @@ -4,7 +4,7 @@ from tkinter import TclError from test.support import requires -from tkinter.test.support import pixels_conv, tcl_version, requires_tcl +from tkinter.test.support import pixels_conv from tkinter.test.widget_tests import AbstractWidgetTest requires('gui') @@ -295,8 +295,7 @@ def test_place_configure_in(self): with self.assertRaisesRegex(TclError, "can't place %s relative to " "itself" % re.escape(str(f2))): f2.place_configure(in_=f2) - if tcl_version >= (8, 5): - self.assertEqual(f2.winfo_manager(), '') + self.assertEqual(f2.winfo_manager(), '') with self.assertRaisesRegex(TclError, 'bad window path name'): f2.place_configure(in_='spam') f2.place_configure(in_=f) @@ -491,8 +490,7 @@ def tearDown(self): for i in range(rows + 1): self.root.grid_rowconfigure(i, weight=0, minsize=0, pad=0, uniform='') self.root.grid_propagate(1) - if tcl_version >= (8, 5): - self.root.grid_anchor('nw') + self.root.grid_anchor('nw') super().tearDown() def test_grid_configure(self): @@ -619,16 +617,14 @@ def test_grid_columnconfigure(self): self.root.grid_columnconfigure((0, 3)) b = tkinter.Button(self.root) b.grid_configure(column=0, row=0) - if tcl_version >= (8, 5): - self.root.grid_columnconfigure('all', weight=3) - with self.assertRaisesRegex(TclError, 'expected integer but got "all"'): - self.root.grid_columnconfigure('all') - self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 3) + self.root.grid_columnconfigure('all', weight=3) + with self.assertRaisesRegex(TclError, 'expected integer but got "all"'): + self.root.grid_columnconfigure('all') + self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 3) self.assertEqual(self.root.grid_columnconfigure(3, 'weight'), 2) self.assertEqual(self.root.grid_columnconfigure(265, 'weight'), 0) - if tcl_version >= (8, 5): - self.root.grid_columnconfigure(b, weight=4) - self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 4) + self.root.grid_columnconfigure(b, weight=4) + self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 4) def test_grid_columnconfigure_minsize(self): with self.assertRaisesRegex(TclError, 'bad screen distance "foo"'): @@ -675,16 +671,14 @@ def test_grid_rowconfigure(self): self.root.grid_rowconfigure((0, 3)) b = tkinter.Button(self.root) b.grid_configure(column=0, row=0) - if tcl_version >= (8, 5): - self.root.grid_rowconfigure('all', weight=3) - with self.assertRaisesRegex(TclError, 'expected integer but got "all"'): - self.root.grid_rowconfigure('all') - self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 3) + self.root.grid_rowconfigure('all', weight=3) + with self.assertRaisesRegex(TclError, 'expected integer but got "all"'): + self.root.grid_rowconfigure('all') + self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 3) self.assertEqual(self.root.grid_rowconfigure(3, 'weight'), 2) self.assertEqual(self.root.grid_rowconfigure(265, 'weight'), 0) - if tcl_version >= (8, 5): - self.root.grid_rowconfigure(b, weight=4) - self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 4) + self.root.grid_rowconfigure(b, weight=4) + self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 4) def test_grid_rowconfigure_minsize(self): with self.assertRaisesRegex(TclError, 'bad screen distance "foo"'): @@ -774,7 +768,6 @@ def test_grid_info(self): self.assertEqual(info['pady'], self._str(4)) self.assertEqual(info['sticky'], 'ns') - @requires_tcl(8, 5) def test_grid_anchor(self): with self.assertRaisesRegex(TclError, 'bad anchor "x"'): self.root.grid_anchor('x') diff --git a/Lib/tkinter/test/test_tkinter/test_widgets.py b/Lib/tkinter/test/test_tkinter/test_widgets.py index c0b92bf3b1921..fe8ecfeb32655 100644 --- a/Lib/tkinter/test/test_tkinter/test_widgets.py +++ b/Lib/tkinter/test/test_tkinter/test_widgets.py @@ -4,11 +4,11 @@ import os from test.support import requires -from tkinter.test.support import (tcl_version, requires_tcl, +from tkinter.test.support import (requires_tcl, get_tk_patchlevel, widget_eq, AbstractDefaultRootTest) from tkinter.test.widget_tests import ( - add_standard_options, noconv, pixels_round, + add_standard_options, AbstractWidgetTest, StandardOptionsTests, IntegerSizeTests, PixelSizeTests, setUpModule) @@ -20,7 +20,7 @@ def float_round(x): class AbstractToplevelTest(AbstractWidgetTest, PixelSizeTests): - _conv_pad_pixels = noconv + _conv_pad_pixels = False def test_configure_class(self): widget = self.create() @@ -139,7 +139,7 @@ def test_configure_labelwidget(self): class AbstractLabelTest(AbstractWidgetTest, IntegerSizeTests): - _conv_pixels = noconv + _conv_pixels = False def test_configure_highlightthickness(self): widget = self.create() @@ -249,7 +249,7 @@ class MenubuttonTest(AbstractLabelTest, unittest.TestCase): 'takefocus', 'text', 'textvariable', 'underline', 'width', 'wraplength', ) - _conv_pixels = staticmethod(pixels_round) + _conv_pixels = round def create(self, **kwargs): return tkinter.Menubutton(self.root, **kwargs) @@ -345,10 +345,7 @@ def test_configure_insertwidth(self): self.checkPixelsParam(widget, 'insertwidth', 1.3, 3.6, '10p') self.checkParam(widget, 'insertwidth', 0.1, expected=2) self.checkParam(widget, 'insertwidth', -2, expected=2) - if pixels_round(0.9) <= 0: - self.checkParam(widget, 'insertwidth', 0.9, expected=2) - else: - self.checkParam(widget, 'insertwidth', 0.9, expected=1) + self.checkParam(widget, 'insertwidth', 0.9, expected=1) def test_configure_invalidcommand(self): widget = self.create() @@ -550,8 +547,6 @@ class TextTest(AbstractWidgetTest, unittest.TestCase): 'tabs', 'tabstyle', 'takefocus', 'undo', 'width', 'wrap', 'xscrollcommand', 'yscrollcommand', ) - if tcl_version < (8, 5): - _stringify = True def create(self, **kwargs): return tkinter.Text(self.root, **kwargs) @@ -560,12 +555,10 @@ def test_configure_autoseparators(self): widget = self.create() self.checkBooleanParam(widget, 'autoseparators') - @requires_tcl(8, 5) def test_configure_blockcursor(self): widget = self.create() self.checkBooleanParam(widget, 'blockcursor') - @requires_tcl(8, 5) def test_configure_endline(self): widget = self.create() text = '\n'.join('Line %d' for i in range(100)) @@ -589,7 +582,6 @@ def test_configure_maxundo(self): widget = self.create() self.checkIntegerParam(widget, 'maxundo', 0, 5, -1) - @requires_tcl(8, 5) def test_configure_inactiveselectbackground(self): widget = self.create() self.checkColorParam(widget, 'inactiveselectbackground') @@ -603,8 +595,7 @@ def test_configure_insertunfocussed(self): def test_configure_selectborderwidth(self): widget = self.create() self.checkPixelsParam(widget, 'selectborderwidth', - 1.3, 2.6, -2, '10p', conv=noconv, - keep_orig=tcl_version >= (8, 5)) + 1.3, 2.6, -2, '10p', conv=False) def test_configure_spacing1(self): widget = self.create() @@ -621,7 +612,6 @@ def test_configure_spacing3(self): self.checkPixelsParam(widget, 'spacing3', 20, 21.4, 22.6, '0.5c') self.checkParam(widget, 'spacing3', -10, expected=0) - @requires_tcl(8, 5) def test_configure_startline(self): widget = self.create() text = '\n'.join('Line %d' for i in range(100)) @@ -637,27 +627,18 @@ def test_configure_startline(self): def test_configure_state(self): widget = self.create() - if tcl_version < (8, 5): - self.checkParams(widget, 'state', 'disabled', 'normal') - else: - self.checkEnumParam(widget, 'state', 'disabled', 'normal') + self.checkEnumParam(widget, 'state', 'disabled', 'normal') def test_configure_tabs(self): widget = self.create() - if get_tk_patchlevel() < (8, 5, 11): - self.checkParam(widget, 'tabs', (10.2, 20.7, '1i', '2i'), - expected=('10.2', '20.7', '1i', '2i')) - else: - self.checkParam(widget, 'tabs', (10.2, 20.7, '1i', '2i')) + self.checkParam(widget, 'tabs', (10.2, 20.7, '1i', '2i')) self.checkParam(widget, 'tabs', '10.2 20.7 1i 2i', expected=('10.2', '20.7', '1i', '2i')) self.checkParam(widget, 'tabs', '2c left 4c 6c center', expected=('2c', 'left', '4c', '6c', 'center')) self.checkInvalidParam(widget, 'tabs', 'spam', - errmsg='bad screen distance "spam"', - keep_orig=tcl_version >= (8, 5)) + errmsg='bad screen distance "spam"') - @requires_tcl(8, 5) def test_configure_tabstyle(self): widget = self.create() self.checkEnumParam(widget, 'tabstyle', 'tabular', 'wordprocessor') @@ -674,10 +655,7 @@ def test_configure_width(self): def test_configure_wrap(self): widget = self.create() - if tcl_version < (8, 5): - self.checkParams(widget, 'wrap', 'char', 'none', 'word') - else: - self.checkEnumParam(widget, 'wrap', 'char', 'none', 'word') + self.checkEnumParam(widget, 'wrap', 'char', 'none', 'word') def test_bbox(self): widget = self.create() @@ -1055,12 +1033,12 @@ def test_configure_handlepad(self): def test_configure_handlesize(self): widget = self.create() self.checkPixelsParam(widget, 'handlesize', 8, 9.4, 10.6, -3, '2m', - conv=noconv) + conv=False) def test_configure_height(self): widget = self.create() self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, -100, 0, '1i', - conv=noconv) + conv=False) def test_configure_opaqueresize(self): widget = self.create() @@ -1076,7 +1054,7 @@ def test_configure_proxyborderwidth(self): widget = self.create() self.checkPixelsParam(widget, 'proxyborderwidth', 0, 1.3, 2.9, 6, -2, '10p', - conv=noconv) + conv=False) @requires_tcl(8, 6, 5) def test_configure_proxyrelief(self): @@ -1098,7 +1076,7 @@ def test_configure_sashrelief(self): def test_configure_sashwidth(self): widget = self.create() self.checkPixelsParam(widget, 'sashwidth', 10, 11.1, 15.6, -3, '1m', - conv=noconv) + conv=False) def test_configure_showhandle(self): widget = self.create() @@ -1107,7 +1085,7 @@ def test_configure_showhandle(self): def test_configure_width(self): widget = self.create() self.checkPixelsParam(widget, 'width', 402, 403.4, 404.6, -402, 0, '5i', - conv=noconv) + conv=False) def create2(self): p = self.create() @@ -1127,15 +1105,12 @@ def test_paneconfigure(self): self.assertEqual(v, p.paneconfigure(b, k)) self.assertEqual(v[4], p.panecget(b, k)) - def check_paneconfigure(self, p, b, name, value, expected, stringify=False): - conv = lambda x: x - if not self.wantobjects or stringify: + def check_paneconfigure(self, p, b, name, value, expected): + if not self.wantobjects: expected = str(expected) - if self.wantobjects and stringify: - conv = str p.paneconfigure(b, **{name: value}) - self.assertEqual(conv(p.paneconfigure(b, name)[4]), expected) - self.assertEqual(conv(p.panecget(b, name)), expected) + self.assertEqual(p.paneconfigure(b, name)[4], expected) + self.assertEqual(p.panecget(b, name), expected) def check_paneconfigure_bad(self, p, b, name, msg): with self.assertRaisesRegex(TclError, msg): @@ -1155,12 +1130,10 @@ def test_paneconfigure_before(self): def test_paneconfigure_height(self): p, b, c = self.create2() - self.check_paneconfigure(p, b, 'height', 10, 10, - stringify=get_tk_patchlevel() < (8, 5, 11)) + self.check_paneconfigure(p, b, 'height', 10, 10) self.check_paneconfigure_bad(p, b, 'height', 'bad screen distance "badValue"') - @requires_tcl(8, 5) def test_paneconfigure_hide(self): p, b, c = self.create2() self.check_paneconfigure(p, b, 'hide', False, 0) @@ -1193,7 +1166,6 @@ def test_paneconfigure_sticky(self): 'be a string containing zero or more of ' 'n, e, s, and w') - @requires_tcl(8, 5) def test_paneconfigure_stretch(self): p, b, c = self.create2() self.check_paneconfigure(p, b, 'stretch', 'alw', 'always') @@ -1203,8 +1175,7 @@ def test_paneconfigure_stretch(self): def test_paneconfigure_width(self): p, b, c = self.create2() - self.check_paneconfigure(p, b, 'width', 10, 10, - stringify=get_tk_patchlevel() < (8, 5, 11)) + self.check_paneconfigure(p, b, 'width', 10, 10) self.check_paneconfigure_bad(p, b, 'width', 'bad screen distance "badValue"') @@ -1218,7 +1189,7 @@ class MenuTest(AbstractWidgetTest, unittest.TestCase): 'postcommand', 'relief', 'selectcolor', 'takefocus', 'tearoff', 'tearoffcommand', 'title', 'type', ) - _conv_pixels = noconv + _conv_pixels = False def create(self, **kwargs): return tkinter.Menu(self.root, **kwargs) @@ -1290,7 +1261,7 @@ class MessageTest(AbstractWidgetTest, unittest.TestCase): 'justify', 'padx', 'pady', 'relief', 'takefocus', 'text', 'textvariable', 'width', ) - _conv_pad_pixels = noconv + _conv_pad_pixels = False def create(self, **kwargs): return tkinter.Message(self.root, **kwargs) diff --git a/Lib/tkinter/test/test_ttk/test_widgets.py b/Lib/tkinter/test/test_ttk/test_widgets.py index 1cb7e74c66ec7..c14c321ca2687 100644 --- a/Lib/tkinter/test/test_ttk/test_widgets.py +++ b/Lib/tkinter/test/test_ttk/test_widgets.py @@ -7,7 +7,7 @@ from test.test_ttk_textonly import MockTclObj from tkinter.test.support import (AbstractTkTest, tcl_version, get_tk_patchlevel, simulate_mouse_click, AbstractDefaultRootTest) -from tkinter.test.widget_tests import (add_standard_options, noconv, +from tkinter.test.widget_tests import (add_standard_options, AbstractWidgetTest, StandardOptionsTests, IntegerSizeTests, PixelSizeTests, setUpModule) @@ -110,7 +110,7 @@ def test_cb(arg1, **kw): class AbstractToplevelTest(AbstractWidgetTest, PixelSizeTests): - _conv_pixels = noconv + _conv_pixels = False @add_standard_options(StandardTtkOptionsTests) @@ -193,7 +193,7 @@ class LabelTest(AbstractLabelTest, unittest.TestCase): 'takefocus', 'text', 'textvariable', 'underline', 'width', 'wraplength', ) - _conv_pixels = noconv + _conv_pixels = False def create(self, **kwargs): return ttk.Label(self.root, **kwargs) @@ -473,8 +473,7 @@ def check_get_current(getval, currval): self.assertEqual(self.combo.get(), getval) self.assertEqual(self.combo.current(), currval) - self.assertEqual(self.combo['values'], - () if tcl_version < (8, 5) else '') + self.assertEqual(self.combo['values'], '') check_get_current('', -1) self.checkParam(self.combo, 'values', 'mon tue wed thur', @@ -741,7 +740,7 @@ class ScaleTest(AbstractWidgetTest, unittest.TestCase): 'class', 'command', 'cursor', 'from', 'length', 'orient', 'style', 'takefocus', 'to', 'value', 'variable', ) - _conv_pixels = noconv + _conv_pixels = False default_orient = 'horizontal' def setUp(self): @@ -848,7 +847,7 @@ class ProgressbarTest(AbstractWidgetTest, unittest.TestCase): 'mode', 'maximum', 'phase', 'style', 'takefocus', 'value', 'variable', ) - _conv_pixels = noconv + _conv_pixels = False default_orient = 'horizontal' def create(self, **kwargs): @@ -1231,8 +1230,7 @@ def test_configure_wrap(self): self.assertEqual(self.spin.get(), '1') def test_configure_values(self): - self.assertEqual(self.spin['values'], - () if tcl_version < (8, 5) else '') + self.assertEqual(self.spin['values'], '') self.checkParam(self.spin, 'values', 'mon tue wed thur', expected=('mon', 'tue', 'wed', 'thur')) self.checkParam(self.spin, 'values', ('mon', 'tue', 'wed', 'thur')) @@ -1316,7 +1314,7 @@ def test_configure_displaycolumns(self): def test_configure_height(self): widget = self.create() self.checkPixelsParam(widget, 'height', 100, -100, 0, '3c', conv=False) - self.checkPixelsParam(widget, 'height', 101.2, 102.6, conv=noconv) + self.checkPixelsParam(widget, 'height', 101.2, 102.6, conv=False) def test_configure_selectmode(self): widget = self.create() diff --git a/Lib/tkinter/test/widget_tests.py b/Lib/tkinter/test/widget_tests.py index 9702ff453002e..37d1979c23f1d 100644 --- a/Lib/tkinter/test/widget_tests.py +++ b/Lib/tkinter/test/widget_tests.py @@ -2,26 +2,15 @@ import unittest import tkinter -from tkinter.test.support import (AbstractTkTest, tcl_version, requires_tcl, - get_tk_patchlevel, pixels_conv, tcl_obj_eq) +from tkinter.test.support import (AbstractTkTest, tcl_version, + pixels_conv, tcl_obj_eq) import test.support -noconv = False -if get_tk_patchlevel() < (8, 5, 11): - noconv = str - -pixels_round = round -if get_tk_patchlevel()[:3] == (8, 5, 11): - # Issue #19085: Workaround a bug in Tk - # http://core.tcl.tk/tk/info/3497848 - pixels_round = int - - _sentinel = object() class AbstractWidgetTest(AbstractTkTest): - _conv_pixels = staticmethod(pixels_round) + _conv_pixels = round _conv_pad_pixels = None _stringify = False @@ -65,8 +54,7 @@ def checkParam(self, widget, name, value, *, expected=_sentinel, self.assertEqual(len(t), 5) self.assertEqual2(t[4], expected, eq=eq) - def checkInvalidParam(self, widget, name, value, errmsg=None, *, - keep_orig=True): + def checkInvalidParam(self, widget, name, value, errmsg=None): orig = widget[name] if errmsg is not None: errmsg = errmsg.format(value) @@ -74,18 +62,12 @@ def checkInvalidParam(self, widget, name, value, errmsg=None, *, widget[name] = value if errmsg is not None: self.assertEqual(str(cm.exception), errmsg) - if keep_orig: - self.assertEqual(widget[name], orig) - else: - widget[name] = orig + self.assertEqual(widget[name], orig) with self.assertRaises(tkinter.TclError) as cm: widget.configure({name: value}) if errmsg is not None: self.assertEqual(str(cm.exception), errmsg) - if keep_orig: - self.assertEqual(widget[name], orig) - else: - widget[name] = orig + self.assertEqual(widget[name], orig) def checkParams(self, widget, name, *values, **kwargs): for value in values: @@ -128,8 +110,7 @@ def checkColorParam(self, widget, name, *, allow_empty=None, **kwargs): def checkCursorParam(self, widget, name, **kwargs): self.checkParams(widget, name, 'arrow', 'watch', 'cross', '',**kwargs) - if tcl_version >= (8, 5): - self.checkParam(widget, name, 'none') + self.checkParam(widget, name, 'none') self.checkInvalidParam(widget, name, 'spam', errmsg='bad cursor spec "spam"') @@ -154,7 +135,7 @@ def checkEnumParam(self, widget, name, *values, errmsg=None, **kwargs): self.checkInvalidParam(widget, name, 'spam', errmsg=errmsg) def checkPixelsParam(self, widget, name, *values, - conv=None, keep_orig=True, **kwargs): + conv=None, **kwargs): if conv is None: conv = self._conv_pixels for value in values: @@ -167,9 +148,9 @@ def checkPixelsParam(self, widget, name, *values, self.checkParam(widget, name, value, expected=expected, conv=conv1, **kwargs) self.checkInvalidParam(widget, name, '6x', - errmsg='bad screen distance "6x"', keep_orig=keep_orig) + errmsg='bad screen distance "6x"') self.checkInvalidParam(widget, name, 'spam', - errmsg='bad screen distance "spam"', keep_orig=keep_orig) + errmsg='bad screen distance "spam"') def checkReliefParam(self, widget, name): self.checkParams(widget, name, @@ -475,12 +456,10 @@ def test_configure_selectimage(self): widget = self.create() self.checkImageParam(widget, 'selectimage') - @requires_tcl(8, 5) def test_configure_tristateimage(self): widget = self.create() self.checkImageParam(widget, 'tristateimage') - @requires_tcl(8, 5) def test_configure_tristatevalue(self): widget = self.create() self.checkParam(widget, 'tristatevalue', 'unknowable') diff --git a/Lib/tkinter/ttk.py b/Lib/tkinter/ttk.py index acdd565ec48a9..efeabb7a92c62 100644 --- a/Lib/tkinter/ttk.py +++ b/Lib/tkinter/ttk.py @@ -28,23 +28,6 @@ import tkinter from tkinter import _flatten, _join, _stringify, _splitdict -# Verify if Tk is new enough to not need the Tile package -_REQUIRE_TILE = True if tkinter.TkVersion < 8.5 else False - -def _load_tile(master): - if _REQUIRE_TILE: - import os - tilelib = os.environ.get('TILE_LIBRARY') - if tilelib: - # append custom tile path to the list of directories that - # Tcl uses when attempting to resolve packages with the package - # command - master.tk.eval( - 'global auto_path; ' - 'lappend auto_path {%s}' % tilelib) - - master.tk.eval('package require tile') # TclError may be raised here - master._tile_loaded = True def _format_optvalue(value, script=False): """Internal function.""" @@ -360,11 +343,6 @@ class Style(object): def __init__(self, master=None): master = setup_master(master) - - if not getattr(master, '_tile_loaded', False): - # Load tile now, if needed - _load_tile(master) - self.master = master self.tk = self.master.tk @@ -546,9 +524,6 @@ def __init__(self, master, widgetname, kw=None): readonly, alternate, invalid """ master = setup_master(master) - if not getattr(master, '_tile_loaded', False): - # Load tile now, if needed - _load_tile(master) tkinter.Widget.__init__(self, master, widgetname, kw=kw) diff --git a/Misc/NEWS.d/next/Build/2022-03-12-18-09-31.bpo-46996.SygzVz.rst b/Misc/NEWS.d/next/Build/2022-03-12-18-09-31.bpo-46996.SygzVz.rst new file mode 100644 index 0000000000000..08138f2e3e935 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2022-03-12-18-09-31.bpo-46996.SygzVz.rst @@ -0,0 +1 @@ +The :mod:`tkinter` package now requires Tcl/Tk version 8.5.12 or newer. diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index cd167fd81250e..4807ad59f6da2 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -9,8 +9,8 @@ Copyright (C) 1994 Steen Lumholt. /* TCL/TK VERSION INFO: - Only Tcl/Tk 8.4 and later are supported. Older versions are not - supported. Use Python 3.4 or older if you cannot upgrade your + Only Tcl/Tk 8.5.12 and later are supported. Older versions are not + supported. Use Python 3.10 or older if you cannot upgrade your Tcl/Tk libraries. */ @@ -54,15 +54,11 @@ Copyright (C) 1994 Steen Lumholt. #include "tkinter.h" -#if TK_HEX_VERSION < 0x08040200 -#error "Tk older than 8.4 not supported" +#if TK_HEX_VERSION < 0x0805020c +#error "Tk older than 8.5.12 not supported" #endif -#if TK_HEX_VERSION >= 0x08050208 && TK_HEX_VERSION < 0x08060000 || \ - TK_HEX_VERSION >= 0x08060200 -#define HAVE_LIBTOMMATH #include -#endif #if !(defined(MS_WINDOWS) || defined(__CYGWIN__)) #define HAVE_CREATEFILEHANDLER @@ -885,7 +881,6 @@ static PyType_Spec PyTclObject_Type_spec = { #define CHECK_STRING_LENGTH(s) #endif -#ifdef HAVE_LIBTOMMATH static Tcl_Obj* asBignumObj(PyObject *value) { @@ -922,7 +917,6 @@ asBignumObj(PyObject *value) } return result; } -#endif static Tcl_Obj* AsObj(PyObject *value) @@ -965,9 +959,7 @@ AsObj(PyObject *value) #endif /* If there is an overflow in the wideInt conversion, fall through to bignum handling. */ -#ifdef HAVE_LIBTOMMATH return asBignumObj(value); -#endif /* If there is no wideInt or bignum support, fall through to default object handling. */ } @@ -1087,7 +1079,6 @@ fromWideIntObj(TkappObject *tkapp, Tcl_Obj *value) return NULL; } -#ifdef HAVE_LIBTOMMATH static PyObject* fromBignumObj(TkappObject *tkapp, Tcl_Obj *value) { @@ -1122,7 +1113,6 @@ fromBignumObj(TkappObject *tkapp, Tcl_Obj *value) mp_clear(&bigValue); return res; } -#endif static PyObject* FromObj(TkappObject *tkapp, Tcl_Obj *value) @@ -1167,13 +1157,11 @@ FromObj(TkappObject *tkapp, Tcl_Obj *value) fall through to bignum handling. */ } -#ifdef HAVE_LIBTOMMATH if (value->typePtr == tkapp->IntType || value->typePtr == tkapp->WideIntType || value->typePtr == tkapp->BignumType) { return fromBignumObj(tkapp, value); } -#endif if (value->typePtr == tkapp->ListType) { int size; @@ -1211,23 +1199,19 @@ FromObj(TkappObject *tkapp, Tcl_Obj *value) return unicodeFromTclObj(value); } -#if TK_HEX_VERSION >= 0x08050000 if (tkapp->BooleanType == NULL && strcmp(value->typePtr->name, "booleanString") == 0) { /* booleanString type is not registered in Tcl */ tkapp->BooleanType = value->typePtr; return fromBoolean(tkapp, value); } -#endif -#ifdef HAVE_LIBTOMMATH if (tkapp->BignumType == NULL && strcmp(value->typePtr->name, "bignum") == 0) { /* bignum type is not registered in Tcl */ tkapp->BignumType = value->typePtr; return fromBignumObj(tkapp, value); } -#endif return newPyTclObject(value); } @@ -1921,11 +1905,7 @@ _tkinter_tkapp_getint(TkappObject *self, PyObject *arg) Prefer bignum because Tcl_GetWideIntFromObj returns ambiguous result for value in ranges -2**64..-2**63-1 and 2**63..2**64-1 (on 32-bit platform). */ -#ifdef HAVE_LIBTOMMATH result = fromBignumObj(self, value); -#else - result = fromWideIntObj(self, value); -#endif Tcl_DecrRefCount(value); if (result != NULL || PyErr_Occurred()) return result; From webhook-mailer at python.org Thu Mar 17 07:10:06 2022 From: webhook-mailer at python.org (tiran) Date: Thu, 17 Mar 2022 11:10:06 -0000 Subject: [Python-checkins] bpo-40280: Skip more tests on Emscripten (GH-31947) Message-ID: https://github.com/python/cpython/commit/ef1327e3b622e0cafdf8bfc1f480fed0dd386be6 commit: ef1327e3b622e0cafdf8bfc1f480fed0dd386be6 branch: main author: Christian Heimes committer: tiran date: 2022-03-17T12:09:57+01:00 summary: bpo-40280: Skip more tests on Emscripten (GH-31947) - lchmod, lchown are not fully implemented - skip umask tests - cannot fstat unlinked or renamed files yet - ignore musl libc issues that affect Emscripten files: M Lib/distutils/tests/test_dir_util.py M Lib/test/test__locale.py M Lib/test/test__xxsubinterpreters.py M Lib/test/test_coroutines.py M Lib/test/test_interpreters.py M Lib/test/test_locale.py M Lib/test/test_logging.py M Lib/test/test_ntpath.py M Lib/test/test_os.py M Lib/test/test_re.py M Lib/test/test_select.py M Lib/test/test_strptime.py M Lib/test/test_support.py M Lib/test/test_tempfile.py M Lib/test/test_time.py M Tools/wasm/config.site-wasm32-emscripten diff --git a/Lib/distutils/tests/test_dir_util.py b/Lib/distutils/tests/test_dir_util.py index 1b1f3bbb02e34..f3ba0ee33b4bc 100644 --- a/Lib/distutils/tests/test_dir_util.py +++ b/Lib/distutils/tests/test_dir_util.py @@ -11,7 +11,7 @@ from distutils import log from distutils.tests import support -from test.support import run_unittest +from test.support import run_unittest, is_emscripten class DirUtilTestCase(support.TempdirManager, unittest.TestCase): @@ -55,6 +55,7 @@ def test_mkpath_remove_tree_verbosity(self): @unittest.skipIf(sys.platform.startswith('win'), "This test is only appropriate for POSIX-like systems.") + @unittest.skipIf(is_emscripten, "Emscripten's umask is a stub.") def test_mkpath_with_custom_mode(self): # Get and set the current umask value for testing mode bits. umask = os.umask(0o002) diff --git a/Lib/test/test__locale.py b/Lib/test/test__locale.py index 59a00bad7d98a..e25c92c2c82c5 100644 --- a/Lib/test/test__locale.py +++ b/Lib/test/test__locale.py @@ -9,6 +9,8 @@ import unittest from platform import uname +from test import support + if uname().system == "Darwin": maj, min, mic = [int(part) for part in uname().release.split(".")] if (maj, min, mic) < (8, 0, 0): @@ -106,6 +108,9 @@ def numeric_tester(self, calc_type, calc_value, data_type, used_locale): return True @unittest.skipUnless(nl_langinfo, "nl_langinfo is not available") + @unittest.skipIf( + support.is_emscripten, "musl libc issue on Emscripten, bpo-46390" + ) def test_lc_numeric_nl_langinfo(self): # Test nl_langinfo against known values tested = False @@ -122,6 +127,9 @@ def test_lc_numeric_nl_langinfo(self): if not tested: self.skipTest('no suitable locales') + @unittest.skipIf( + support.is_emscripten, "musl libc issue on Emscripten, bpo-46390" + ) def test_lc_numeric_localeconv(self): # Test localeconv against known values tested = False diff --git a/Lib/test/test__xxsubinterpreters.py b/Lib/test/test__xxsubinterpreters.py index 177a8a64a4329..5d0ed9ea14ac7 100644 --- a/Lib/test/test__xxsubinterpreters.py +++ b/Lib/test/test__xxsubinterpreters.py @@ -818,7 +818,7 @@ def f(): self.assertEqual(out, 'it worked!') - @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()") + @support.requires_fork() def test_fork(self): import tempfile with tempfile.NamedTemporaryFile('w+', encoding="utf-8") as file: diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py index 3081853303b37..77944e678c750 100644 --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -2208,6 +2208,9 @@ async def f(): gen.cr_frame.clear() + at unittest.skipIf( + support.is_emscripten, "asyncio does not work under Emscripten yet." +) class CoroAsyncIOCompatTest(unittest.TestCase): def test_asyncio_1(self): diff --git a/Lib/test/test_interpreters.py b/Lib/test/test_interpreters.py index 48c7119fff1cf..b969ddf33d81b 100644 --- a/Lib/test/test_interpreters.py +++ b/Lib/test/test_interpreters.py @@ -5,6 +5,7 @@ import unittest import time +from test import support from test.support import import_helper _interpreters = import_helper.import_module('_xxsubinterpreters') from test.support import interpreters @@ -408,7 +409,7 @@ def f(): self.assertEqual(out, 'it worked!') - @unittest.skipUnless(hasattr(os, 'fork'), "test needs os.fork()") + @support.requires_fork() def test_fork(self): interp = interpreters.create() import tempfile diff --git a/Lib/test/test_locale.py b/Lib/test/test_locale.py index 2a3b0acc6bd60..774b0fcd33344 100644 --- a/Lib/test/test_locale.py +++ b/Lib/test/test_locale.py @@ -1,5 +1,5 @@ from decimal import Decimal -from test.support import verbose, is_android +from test.support import verbose, is_android, is_emscripten from test.support.warnings_helper import check_warnings import unittest import locale @@ -373,11 +373,13 @@ def setUp(self): @unittest.skipIf(sys.platform.startswith('aix'), 'bpo-29972: broken test on AIX') + @unittest.skipIf(is_emscripten, "musl libc issue on Emscripten, bpo-46390") def test_strcoll_with_diacritic(self): self.assertLess(locale.strcoll('?', 'b'), 0) @unittest.skipIf(sys.platform.startswith('aix'), 'bpo-29972: broken test on AIX') + @unittest.skipIf(is_emscripten, "musl libc issue on Emscripten, bpo-46390") def test_strxfrm_with_diacritic(self): self.assertLess(locale.strxfrm('?'), locale.strxfrm('b')) diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 4f3315161cf20..be193dcdacf4f 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -674,7 +674,7 @@ def remove_loop(fname, tries): # based on os.fork existing because that is what users and this test use. # This helps ensure that when fork exists (the important concept) that the # register_at_fork mechanism is also present and used. - @unittest.skipIf(not hasattr(os, 'fork'), 'Test requires os.fork().') + @support.requires_fork() def test_post_fork_child_no_deadlock(self): """Ensure child logging locks are not held; bpo-6721 & bpo-36533.""" class _OurHandler(logging.Handler): @@ -4493,6 +4493,7 @@ def _extract_logrecord_process_name(key, logMultiprocessing, conn=None): return results def test_multiprocessing(self): + support.skip_if_broken_multiprocessing_synchronize() multiprocessing_imported = 'multiprocessing' in sys.modules try: # logMultiprocessing is True by default diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index 99a77e3fb43dc..7211ed861762b 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -4,7 +4,7 @@ import unittest import warnings from test.support import os_helper -from test.support import TestFailed +from test.support import TestFailed, is_emscripten from test.support.os_helper import FakePath from test import test_genericpath from tempfile import TemporaryFile @@ -747,6 +747,7 @@ def check_error(exc, paths): self.assertRaises(TypeError, ntpath.commonpath, ['Program Files', b'C:\\Program Files\\Foo']) + @unittest.skipIf(is_emscripten, "Emscripten cannot fstat unnamed files.") def test_sameopenfile(self): with TemporaryFile() as tf1, TemporaryFile() as tf2: # Make sure the same file is really the same diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index ae8d930a95253..426d2ae9373bc 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -181,6 +181,9 @@ def test_access(self): os.close(f) self.assertTrue(os.access(os_helper.TESTFN, os.W_OK)) + @unittest.skipIf( + support.is_emscripten, "Test is unstable under Emscripten." + ) def test_closerange(self): first = os.open(os_helper.TESTFN, os.O_CREAT|os.O_RDWR) # We must allocate two consecutive file descriptors, otherwise @@ -1578,6 +1581,7 @@ def test_makedir(self): 'dir5', 'dir6') os.makedirs(path) + @unittest.skipIf(support.is_emscripten, "Emscripten's umask is a stub.") def test_mode(self): with os_helper.temp_umask(0o002): base = os_helper.TESTFN @@ -2158,6 +2162,9 @@ def test_fchown(self): self.check(os.fchown, -1, -1) @unittest.skipUnless(hasattr(os, 'fpathconf'), 'test needs os.fpathconf()') + @unittest.skipIf( + support.is_emscripten, "musl libc issue on Emscripten, bpo-46390" + ) def test_fpathconf(self): self.check(os.pathconf, "PC_NAME_MAX") self.check(os.fpathconf, "PC_NAME_MAX") @@ -4058,6 +4065,7 @@ def test_path_t_converter_and_custom_class(self): @unittest.skipUnless(hasattr(os, 'get_blocking'), 'needs os.get_blocking() and os.set_blocking()') + at unittest.skipIf(support.is_emscripten, "Cannot unset blocking flag") class BlockingTests(unittest.TestCase): def test_blocking(self): fd = os.open(__file__, os.O_RDONLY) @@ -4513,7 +4521,7 @@ def test_times(self): self.assertEqual(times.elapsed, 0) - at requires_os_func('fork') + at support.requires_fork() class ForkTests(unittest.TestCase): def test_fork(self): # bpo-42540: ensure os.fork() with non-default memory allocator does diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 18fa24a99ce03..59575962eb4f3 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -1,6 +1,6 @@ from test.support import (gc_collect, bigmemtest, _2G, cpython_only, captured_stdout, - check_disallow_instantiation) + check_disallow_instantiation, is_emscripten) import locale import re import sre_compile @@ -1892,6 +1892,7 @@ def test_bug_20998(self): # with ignore case. self.assertEqual(re.fullmatch('[a-c]+', 'ABC', re.I).span(), (0, 3)) + @unittest.skipIf(is_emscripten, "musl libc issue on Emscripten, bpo-46390") def test_locale_caching(self): # Issue #22410 oldlocale = locale.setlocale(locale.LC_CTYPE) @@ -1928,6 +1929,7 @@ def check_en_US_utf8(self): self.assertIsNone(re.match(b'(?Li)\xc5', b'\xe5')) self.assertIsNone(re.match(b'(?Li)\xe5', b'\xc5')) + @unittest.skipIf(is_emscripten, "musl libc issue on Emscripten, bpo-46390") def test_locale_compiled(self): oldlocale = locale.setlocale(locale.LC_CTYPE) self.addCleanup(locale.setlocale, locale.LC_CTYPE, oldlocale) diff --git a/Lib/test/test_select.py b/Lib/test/test_select.py index 69421fd77558d..8b59321121e49 100644 --- a/Lib/test/test_select.py +++ b/Lib/test/test_select.py @@ -78,6 +78,9 @@ def test_select(self): rfd, wfd, xfd) # Issue 16230: Crash on select resized list + @unittest.skipIf( + support.is_emscripten, "Emscripten cannot select a fd multiple times." + ) def test_select_mutated(self): a = [] class F: diff --git a/Lib/test/test_strptime.py b/Lib/test/test_strptime.py index e5f75b7aab9aa..e3fcabef94611 100644 --- a/Lib/test/test_strptime.py +++ b/Lib/test/test_strptime.py @@ -70,6 +70,9 @@ def test_am_pm(self): self.assertEqual(self.LT_ins.am_pm[position], strftime_output, "AM/PM representation in the wrong position within the tuple") + @unittest.skipIf( + support.is_emscripten, "musl libc issue on Emscripten, bpo-46390" + ) def test_timezone(self): # Make sure timezone is correct timezone = time.strftime("%Z", self.time_tuple).lower() @@ -368,6 +371,9 @@ def test_bad_offset(self): self.assertEqual("Inconsistent use of : in -01:3030", str(err.exception)) @skip_if_buggy_ucrt_strfptime + @unittest.skipIf( + support.is_emscripten, "musl libc issue on Emscripten, bpo-46390" + ) def test_timezone(self): # Test timezone directives. # When gmtime() is used with %Z, entire result of strftime() is empty. diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py index 59e9f3a6c1c8d..2cff377cf629e 100644 --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -658,10 +658,13 @@ def id(self): self.assertFalse(support.match_test(test_access)) self.assertTrue(support.match_test(test_chdir)) + @unittest.skipIf(support.is_emscripten, "Unstable in Emscripten") def test_fd_count(self): # We cannot test the absolute value of fd_count(): on old Linux # kernel or glibc versions, os.urandom() keeps a FD open on # /dev/urandom device and Python has 4 FD opens instead of 3. + # Test is unstable on Emscripten. The platform starts and stops + # background threads that use pipes and epoll fds. start = os_helper.fd_count() fd = os.open(__file__, os.O_RDONLY) try: diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py index 25fddaec6d317..a6847189dca46 100644 --- a/Lib/test/test_tempfile.py +++ b/Lib/test/test_tempfile.py @@ -341,6 +341,9 @@ def _mock_candidate_names(*names): class TestBadTempdir: + @unittest.skipIf( + support.is_emscripten, "Emscripten cannot remove write bits." + ) def test_read_only_directory(self): with _inside_empty_temp_dir(): oldmode = mode = os.stat(tempfile.tempdir).st_mode @@ -465,6 +468,7 @@ def test_file_mode(self): self.assertEqual(mode, expected) @unittest.skipUnless(has_spawnl, 'os.spawnl not available') + @support.requires_subprocess() def test_noinherit(self): # _mkstemp_inner file handles are not inherited by child processes @@ -1282,6 +1286,9 @@ def use_closed(): pass self.assertRaises(ValueError, use_closed) + @unittest.skipIf( + support.is_emscripten, "Emscripten cannot fstat renamed files." + ) def test_truncate_with_size_parameter(self): # A SpooledTemporaryFile can be truncated to zero size f = tempfile.SpooledTemporaryFile(max_size=10) diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py index faac639613a5c..dc0bbb0ee2931 100644 --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -313,6 +313,9 @@ def test_asctime(self): def test_asctime_bounding_check(self): self._bounds_checking(time.asctime) + @unittest.skipIf( + support.is_emscripten, "musl libc issue on Emscripten, bpo-46390" + ) def test_ctime(self): t = time.mktime((1973, 9, 16, 1, 3, 52, 0, 0, -1)) self.assertEqual(time.ctime(t), 'Sun Sep 16 01:03:52 1973') @@ -699,6 +702,9 @@ class TestStrftime4dyear(_TestStrftimeYear, _Test4dYear, unittest.TestCase): class TestPytime(unittest.TestCase): @skip_if_buggy_ucrt_strfptime @unittest.skipUnless(time._STRUCT_TM_ITEMS == 11, "needs tm_zone support") + @unittest.skipIf( + support.is_emscripten, "musl libc issue on Emscripten, bpo-46390" + ) def test_localtime_timezone(self): # Get the localtime and examine it for the offset and zone. diff --git a/Tools/wasm/config.site-wasm32-emscripten b/Tools/wasm/config.site-wasm32-emscripten index 2a601987ccedf..7f2df3a47723f 100644 --- a/Tools/wasm/config.site-wasm32-emscripten +++ b/Tools/wasm/config.site-wasm32-emscripten @@ -53,6 +53,9 @@ ac_cv_func_symlinkat=no ac_cv_func_readlinkat=no ac_cv_func_fchmodat=no ac_cv_func_dup3=no +# lchmod/lchown are implemented, but fail with ENOTSUP. +ac_cv_func_lchmod=no +ac_cv_func_lchown=no # Syscalls not implemented in emscripten # [Errno 52] Function not implemented From webhook-mailer at python.org Thu Mar 17 12:15:02 2022 From: webhook-mailer at python.org (markshannon) Date: Thu, 17 Mar 2022 16:15:02 -0000 Subject: [Python-checkins] Use low bit of LOAD_GLOBAL's oparg to indicate whether it should push an additional NULL. (GH-31933) Message-ID: https://github.com/python/cpython/commit/3011a097bd9500c007bd8b8d005edeea895f6b44 commit: 3011a097bd9500c007bd8b8d005edeea895f6b44 branch: main author: Mark Shannon committer: markshannon date: 2022-03-17T16:14:57Z summary: Use low bit of LOAD_GLOBAL's oparg to indicate whether it should push an additional NULL. (GH-31933) files: A Misc/NEWS.d/next/Core and Builtins/2022-03-16-12-19-25.bpo-46329.9oS0HT.rst M Doc/library/dis.rst M Lib/dis.py M Lib/importlib/_bootstrap_external.py M Lib/test/test_dis.py M Python/ceval.c M Python/compile.c diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 65e888dc86a19..877e11b7376b7 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -43,7 +43,7 @@ the following command can be used to display the disassembly of 1 0 RESUME 0 2 2 PUSH_NULL - 4 LOAD_GLOBAL 0 (len) + 4 LOAD_GLOBAL 1 (NULL + len) 6 LOAD_FAST 0 (alist) 8 PRECALL 1 10 CALL 1 @@ -996,8 +996,11 @@ iterations of the loop. .. opcode:: LOAD_GLOBAL (namei) - Loads the global named ``co_names[namei]`` onto the stack. + Loads the global named ``co_names[namei>>1]`` onto the stack. + .. versionchanged:: 3.11 + If the low bit of ``namei`` is set, then a ``NULL`` is pushed to the + stack before the global variable. .. opcode:: LOAD_FAST (var_num) diff --git a/Lib/dis.py b/Lib/dis.py index 2598d4a51c6a2..3b7747b03ffb1 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -28,6 +28,7 @@ MAKE_FUNCTION_FLAGS = ('defaults', 'kwdefaults', 'annotations', 'closure') LOAD_CONST = opmap['LOAD_CONST'] +LOAD_GLOBAL = opmap['LOAD_GLOBAL'] BINARY_OP = opmap['BINARY_OP'] CACHE = opmap["CACHE"] @@ -430,7 +431,12 @@ def _get_instructions_bytes(code, varname_from_oparg=None, if op in hasconst: argval, argrepr = _get_const_info(op, arg, co_consts) elif op in hasname: - argval, argrepr = _get_name_info(arg, get_name) + if op == LOAD_GLOBAL: + argval, argrepr = _get_name_info(arg//2, get_name) + if (arg & 1) and argrepr: + argrepr = "NULL + " + argrepr + else: + argval, argrepr = _get_name_info(arg, get_name) elif op in hasjabs: argval = arg*2 argrepr = "to " + repr(argval) diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index a6f0a1b3c4c7d..48b55bb821f8b 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -395,6 +395,7 @@ def _write_atomic(path, data, mode=0o666): # Python 3.11a5 3485 (Add an oparg to GET_AWAITABLE) # Python 3.11a6 3486 (Use inline caching for PRECALL and CALL) # Python 3.11a6 3487 (Remove the adaptive "oparg counter" mechanism) +# Python 3.11a6 3488 (LOAD_GLOBAL can push additional NULL) # Python 3.12 will start with magic number 3500 @@ -409,7 +410,7 @@ def _write_atomic(path, data, mode=0o666): # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array # in PC/launcher.c must also be updated. -MAGIC_NUMBER = (3487).to_bytes(2, 'little') + b'\r\n' +MAGIC_NUMBER = (3488).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c _PYCACHE = '__pycache__' diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 12d46af208e0a..16bfee188e046 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -105,8 +105,7 @@ def _f(a): dis_f = """\ %3d RESUME 0 -%3d PUSH_NULL - LOAD_GLOBAL 0 (print) +%3d LOAD_GLOBAL 1 (NULL + print) LOAD_FAST 0 (a) PRECALL 1 CALL 1 @@ -121,8 +120,7 @@ def _f(a): dis_f_co_code = """\ RESUME 0 - PUSH_NULL - LOAD_GLOBAL 0 + LOAD_GLOBAL 1 LOAD_FAST 0 PRECALL 1 CALL 1 @@ -140,8 +138,7 @@ def bug708901(): dis_bug708901 = """\ %3d RESUME 0 -%3d PUSH_NULL - LOAD_GLOBAL 0 (range) +%3d LOAD_GLOBAL 1 (NULL + range) LOAD_CONST 1 (1) %3d LOAD_CONST 2 (10) @@ -149,10 +146,10 @@ def bug708901(): %3d PRECALL 2 CALL 2 GET_ITER - >> FOR_ITER 2 (to 42) + >> FOR_ITER 2 (to 40) STORE_FAST 0 (res) -%3d JUMP_ABSOLUTE 18 (to 36) +%3d JUMP_ABSOLUTE 17 (to 34) %3d >> LOAD_CONST 0 (None) RETURN_VALUE @@ -1154,20 +1151,19 @@ def _prepare_test_cases(): Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=code_object_f, argrepr=repr(code_object_f), offset=14, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='defaults, closure', offset=16, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='f', argrepr='f', offset=18, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=20, starts_line=7, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=22, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=0, argval='a', argrepr='a', offset=34, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=1, argval='b', argrepr='b', offset=36, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='', argrepr="''", offset=38, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=40, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BUILD_LIST', opcode=103, arg=0, argval=0, argrepr='', offset=42, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BUILD_MAP', opcode=105, arg=0, argval=0, argrepr='', offset=44, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Hello world!', argrepr="'Hello world!'", offset=46, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=7, argval=7, argrepr='', offset=48, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=7, argval=7, argrepr='', offset=52, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=62, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='f', argrepr='f', offset=64, starts_line=8, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=66, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='NULL + print', offset=20, starts_line=7, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=0, argval='a', argrepr='a', offset=32, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=1, argval='b', argrepr='b', offset=34, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='', argrepr="''", offset=36, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=38, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='BUILD_LIST', opcode=103, arg=0, argval=0, argrepr='', offset=40, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='BUILD_MAP', opcode=105, arg=0, argval=0, argrepr='', offset=42, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Hello world!', argrepr="'Hello world!'", offset=44, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=7, argval=7, argrepr='', offset=46, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=7, argval=7, argrepr='', offset=50, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=60, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='f', argrepr='f', offset=62, starts_line=8, is_jump_target=False, positions=None), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=64, starts_line=None, is_jump_target=False, positions=None), ] expected_opinfo_f = [ @@ -1184,177 +1180,166 @@ def _prepare_test_cases(): Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=code_object_inner, argrepr=repr(code_object_inner), offset=20, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='defaults, closure', offset=22, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='inner', argrepr='inner', offset=24, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=26, starts_line=5, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=28, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=3, argval='a', argrepr='a', offset=40, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=4, argval='b', argrepr='b', offset=42, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=0, argval='c', argrepr='c', offset=44, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=1, argval='d', argrepr='d', offset=46, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=4, argval=4, argrepr='', offset=48, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=4, argval=4, argrepr='', offset=52, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=62, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='inner', argrepr='inner', offset=64, starts_line=6, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=66, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='NULL + print', offset=26, starts_line=5, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=3, argval='a', argrepr='a', offset=38, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=4, argval='b', argrepr='b', offset=40, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=0, argval='c', argrepr='c', offset=42, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=1, argval='d', argrepr='d', offset=44, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=4, argval=4, argrepr='', offset=46, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=4, argval=4, argrepr='', offset=50, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=60, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='inner', argrepr='inner', offset=62, starts_line=6, is_jump_target=False, positions=None), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=64, starts_line=None, is_jump_target=False, positions=None), ] expected_opinfo_inner = [ Instruction(opname='COPY_FREE_VARS', opcode=149, arg=4, argval=4, argrepr='', offset=0, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='RESUME', opcode=151, arg=0, argval=0, argrepr='', offset=2, starts_line=3, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=4, starts_line=4, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='print', argrepr='print', offset=6, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=2, argval='a', argrepr='a', offset=18, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=3, argval='b', argrepr='b', offset=20, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=4, argval='c', argrepr='c', offset=22, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=5, argval='d', argrepr='d', offset=24, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='e', argrepr='e', offset=26, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=1, argval='f', argrepr='f', offset=28, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=6, argval=6, argrepr='', offset=30, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=6, argval=6, argrepr='', offset=34, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=44, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=46, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=48, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='NULL + print', offset=4, starts_line=4, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=2, argval='a', argrepr='a', offset=16, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=3, argval='b', argrepr='b', offset=18, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=4, argval='c', argrepr='c', offset=20, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=5, argval='d', argrepr='d', offset=22, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='e', argrepr='e', offset=24, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=1, argval='f', argrepr='f', offset=26, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=6, argval=6, argrepr='', offset=28, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=6, argval=6, argrepr='', offset=32, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=42, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=44, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=46, starts_line=None, is_jump_target=False, positions=None), ] + expected_opinfo_jumpy = [ Instruction(opname='RESUME', opcode=151, arg=0, argval=0, argrepr='', offset=0, starts_line=1, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=2, starts_line=3, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='range', argrepr='range', offset=4, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=10, argrepr='10', offset=16, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=18, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=22, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='GET_ITER', opcode=68, arg=None, argval=None, argrepr='', offset=32, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='FOR_ITER', opcode=93, arg=33, argval=102, argrepr='to 102', offset=34, starts_line=None, is_jump_target=True, positions=None), - Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=36, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=38, starts_line=4, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=40, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=52, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=54, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=58, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=68, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=70, starts_line=5, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=72, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=74, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=42, argval=84, argrepr='to 84', offset=80, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=17, argval=34, argrepr='to 34', offset=82, starts_line=6, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=84, starts_line=7, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=86, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=88, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=50, argval=100, argrepr='to 100', offset=94, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=96, starts_line=8, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=17, argval=134, argrepr='to 134', offset=98, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=17, argval=34, argrepr='to 34', offset=100, starts_line=7, is_jump_target=True, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=102, starts_line=10, is_jump_target=True, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=104, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=116, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=118, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=122, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=132, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=134, starts_line=11, is_jump_target=True, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=106, argval=212, argrepr='to 212', offset=136, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=138, starts_line=12, is_jump_target=True, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=140, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=152, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=154, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=158, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=168, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=170, starts_line=13, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=172, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BINARY_OP', opcode=122, arg=23, argval=23, argrepr='-=', offset=174, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=178, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=180, starts_line=14, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=182, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=184, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=97, argval=194, argrepr='to 194', offset=190, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=67, argval=134, argrepr='to 134', offset=192, starts_line=15, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=194, starts_line=16, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=196, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=198, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=104, argval=208, argrepr='to 208', offset=204, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=18, argval=244, argrepr='to 244', offset=206, starts_line=17, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=208, starts_line=11, is_jump_target=True, positions=None), - Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=69, argval=138, argrepr='to 138', offset=210, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=212, starts_line=19, is_jump_target=True, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=214, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=226, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=228, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=232, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=242, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=244, starts_line=20, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=246, starts_line=21, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=248, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BINARY_OP', opcode=122, arg=11, argval=11, argrepr='/', offset=250, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=254, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=256, starts_line=25, is_jump_target=False, positions=None), - Instruction(opname='BEFORE_WITH', opcode=53, arg=None, argval=None, argrepr='', offset=258, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=260, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=262, starts_line=26, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=264, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval='Never reach this', argrepr="'Never reach this'", offset=276, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=278, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=282, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=292, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=294, starts_line=25, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=296, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=298, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=2, argval=2, argrepr='', offset=300, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=2, argval=2, argrepr='', offset=304, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=314, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=11, argval=340, argrepr='to 340', offset=316, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=318, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='WITH_EXCEPT_START', opcode=49, arg=None, argval=None, argrepr='', offset=320, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=166, argval=332, argrepr='to 332', offset=322, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=2, argval=2, argrepr='', offset=324, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=326, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=328, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=330, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=332, starts_line=None, is_jump_target=True, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=334, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=336, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=338, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=31, argval=404, argrepr='to 404', offset=340, starts_line=None, is_jump_target=True, positions=None), - Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=342, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=2, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=344, starts_line=22, is_jump_target=False, positions=None), - Instruction(opname='JUMP_IF_NOT_EXC_MATCH', opcode=121, arg=198, argval=396, argrepr='to 396', offset=356, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=358, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=360, starts_line=23, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=362, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=374, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=376, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=380, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=390, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=392, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=22, argval=440, argrepr='to 440', offset=394, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=396, starts_line=22, is_jump_target=True, positions=None), - Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=398, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=400, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=402, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=404, starts_line=28, is_jump_target=True, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=406, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=418, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=420, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=424, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=434, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=436, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=438, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=440, starts_line=23, is_jump_target=True, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=442, starts_line=28, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=444, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=456, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=458, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=462, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=472, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=474, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=476, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=478, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_NULL', opcode=2, arg=None, argval=None, argrepr='', offset=480, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=482, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=494, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=496, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=500, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=510, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=512, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=514, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=516, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=518, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='range', argrepr='NULL + range', offset=2, starts_line=3, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=10, argrepr='10', offset=14, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=16, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=20, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='GET_ITER', opcode=68, arg=None, argval=None, argrepr='', offset=30, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='FOR_ITER', opcode=93, arg=32, argval=98, argrepr='to 98', offset=32, starts_line=None, is_jump_target=True, positions=None), + Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=34, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=36, starts_line=4, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=48, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=50, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=54, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=64, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=66, starts_line=5, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=68, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=70, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=40, argval=80, argrepr='to 80', offset=76, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=16, argval=32, argrepr='to 32', offset=78, starts_line=6, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=80, starts_line=7, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=82, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=84, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=48, argval=96, argrepr='to 96', offset=90, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=92, starts_line=8, is_jump_target=False, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=16, argval=128, argrepr='to 128', offset=94, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=16, argval=32, argrepr='to 32', offset=96, starts_line=7, is_jump_target=True, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=98, starts_line=10, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=110, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=112, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=116, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=126, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=128, starts_line=11, is_jump_target=True, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=102, argval=204, argrepr='to 204', offset=130, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=132, starts_line=12, is_jump_target=True, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=144, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=146, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=150, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=160, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=162, starts_line=13, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=164, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='BINARY_OP', opcode=122, arg=23, argval=23, argrepr='-=', offset=166, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=170, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=172, starts_line=14, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=174, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=176, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=93, argval=186, argrepr='to 186', offset=182, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=64, argval=128, argrepr='to 128', offset=184, starts_line=15, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=186, starts_line=16, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=188, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=190, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=100, argval=200, argrepr='to 200', offset=196, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=17, argval=234, argrepr='to 234', offset=198, starts_line=17, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=200, starts_line=11, is_jump_target=True, positions=None), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=66, argval=132, argrepr='to 132', offset=202, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=204, starts_line=19, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=216, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=218, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=222, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=232, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=234, starts_line=20, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=236, starts_line=21, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=238, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='BINARY_OP', opcode=122, arg=11, argval=11, argrepr='/', offset=240, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=244, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=246, starts_line=25, is_jump_target=False, positions=None), + Instruction(opname='BEFORE_WITH', opcode=53, arg=None, argval=None, argrepr='', offset=248, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=250, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=252, starts_line=26, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval='Never reach this', argrepr="'Never reach this'", offset=264, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=266, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=270, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=280, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=282, starts_line=25, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=284, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=286, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=2, argval=2, argrepr='', offset=288, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=2, argval=2, argrepr='', offset=292, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=302, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=11, argval=328, argrepr='to 328', offset=304, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=306, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='WITH_EXCEPT_START', opcode=49, arg=None, argval=None, argrepr='', offset=308, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=160, argval=320, argrepr='to 320', offset=310, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=2, argval=2, argrepr='', offset=312, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=314, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=316, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=318, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=320, starts_line=None, is_jump_target=True, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=322, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=324, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=326, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=30, argval=390, argrepr='to 390', offset=328, starts_line=None, is_jump_target=True, positions=None), + Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=330, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=332, starts_line=22, is_jump_target=False, positions=None), + Instruction(opname='JUMP_IF_NOT_EXC_MATCH', opcode=121, arg=191, argval=382, argrepr='to 382', offset=344, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=346, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=348, starts_line=23, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=360, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=362, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=366, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=376, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=378, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=21, argval=424, argrepr='to 424', offset=380, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=382, starts_line=22, is_jump_target=True, positions=None), + Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=384, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=386, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=388, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=390, starts_line=28, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=402, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=404, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=408, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=418, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=420, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=422, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=424, starts_line=23, is_jump_target=True, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=426, starts_line=28, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=438, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=440, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=444, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=454, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=456, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=458, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=460, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=462, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=474, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=476, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=480, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=490, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=492, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=494, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=496, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=498, starts_line=None, is_jump_target=False, positions=None), ] # One last piece of inspect fodder to check the default line number handling diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-16-12-19-25.bpo-46329.9oS0HT.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-16-12-19-25.bpo-46329.9oS0HT.rst new file mode 100644 index 0000000000000..49a1886e88ba1 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-16-12-19-25.bpo-46329.9oS0HT.rst @@ -0,0 +1,2 @@ +Use low bit of ``LOAD_GLOBAL`` to indicate whether to push a ``NULL`` before +the global. Helps streamline the call sequence a bit. diff --git a/Python/ceval.c b/Python/ceval.c index 81759ad770b1e..1a120bba83f8c 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2947,7 +2947,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int TARGET(LOAD_GLOBAL) { PREDICTED(LOAD_GLOBAL); - PyObject *name = GETITEM(names, oparg); + int push_null = oparg & 1; + PEEK(0) = NULL; + PyObject *name = GETITEM(names, oparg>>1); PyObject *v; if (PyDict_CheckExact(GLOBALS()) && PyDict_CheckExact(BUILTINS())) @@ -2970,7 +2972,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int /* Slow-path if globals or builtins is not a dict */ /* namespace 1: globals */ - name = GETITEM(names, oparg); v = PyObject_GetItem(GLOBALS(), name); if (v == NULL) { if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { @@ -2992,6 +2993,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } /* Skip over inline cache */ JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); + STACK_GROW(push_null); PUSH(v); DISPATCH(); } @@ -3000,7 +3002,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert(cframe.use_tracing == 0); _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; if (cache->counter == 0) { - PyObject *name = GETITEM(names, oparg); + PyObject *name = GETITEM(names, oparg>>1); next_instr--; if (_Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name) < 0) { goto error; @@ -3025,10 +3027,13 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); PyObject *res = entries[cache->index].me_value; DEOPT_IF(res == NULL, LOAD_GLOBAL); + int push_null = oparg & 1; + PEEK(0) = NULL; JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); STAT_INC(LOAD_GLOBAL, hit); + STACK_GROW(push_null+1); Py_INCREF(res); - PUSH(res); + SET_TOP(res); NOTRACE_DISPATCH(); } @@ -3047,10 +3052,13 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(bdict->ma_keys); PyObject *res = entries[cache->index].me_value; DEOPT_IF(res == NULL, LOAD_GLOBAL); + int push_null = oparg & 1; + PEEK(0) = NULL; JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); STAT_INC(LOAD_GLOBAL, hit); + STACK_GROW(push_null+1); Py_INCREF(res); - PUSH(res); + SET_TOP(res); NOTRACE_DISPATCH(); } diff --git a/Python/compile.c b/Python/compile.c index ac9ddbcd79d03..950c44a749fc6 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1000,7 +1000,7 @@ stack_effect(int opcode, int oparg, int jump) return -1; case LOAD_GLOBAL: - return 1; + return (oparg & 1) + 1; /* Exception handling pseudo-instructions */ case SETUP_FINALLY: @@ -4185,8 +4185,12 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) assert(op); arg = compiler_add_o(dict, mangled); Py_DECREF(mangled); - if (arg < 0) + if (arg < 0) { return 0; + } + if (op == LOAD_GLOBAL) { + arg <<= 1; + } return compiler_addop_i(c, op, arg); } @@ -8812,6 +8816,13 @@ optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts) break; case KW_NAMES: break; + case PUSH_NULL: + if (nextop == LOAD_GLOBAL && (inst[1].i_opcode & 1) == 0) { + inst->i_opcode = NOP; + inst->i_oparg = 0; + inst[1].i_oparg |= 1; + } + break; default: /* All HAS_CONST opcodes should be handled with LOAD_CONST */ assert (!HAS_CONST(inst->i_opcode)); From webhook-mailer at python.org Thu Mar 17 12:33:02 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Thu, 17 Mar 2022 16:33:02 -0000 Subject: [Python-checkins] bpo-47042: Fix testing the HTML output in test_pydoc (GH-31959) Message-ID: https://github.com/python/cpython/commit/a5d246066b5352a7d72e70ec0acb643e7c0861fa commit: a5d246066b5352a7d72e70ec0acb643e7c0861fa branch: main author: Serhiy Storchaka committer: serhiy-storchaka date: 2022-03-17T18:32:53+02:00 summary: bpo-47042: Fix testing the HTML output in test_pydoc (GH-31959) Previously it tested that that the actual output contains every non-whitespace character from the expected output (ignoring order and repetitions). Now it will test that the actual output contains the same lines as the expected output, in the same order, ignoring indentation and empty lines. files: M Lib/test/test_pydoc.py diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py index 057780d51f9ac..4f18af3f0ec69 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -340,9 +340,10 @@ def html2text(html): Tailored for pydoc tests only. """ - return pydoc.replace( - re.sub("<.*?>", "", html), - " ", " ", ">", ">", "<", "<") + html = html.replace("
", "\n") + html = re.sub("<.*?>", "", html) + html = pydoc.replace(html, " ", " ", ">", ">", "<", "<") + return html class PydocBaseTest(unittest.TestCase): @@ -384,9 +385,12 @@ class PydocDocTest(unittest.TestCase): def test_html_doc(self): result, doc_loc = get_pydoc_html(pydoc_mod) text_result = html2text(result) - expected_lines = [line.strip() for line in html2text_of_expected if line] - for line in expected_lines: - self.assertIn(line, text_result) + text_lines = [line.strip() for line in text_result.splitlines()] + text_lines = [line for line in text_lines if line] + del text_lines[1] + expected_lines = html2text_of_expected.splitlines() + expected_lines = [line.strip() for line in expected_lines if line] + self.assertEqual(text_lines, expected_lines) mod_file = inspect.getabsfile(pydoc_mod) mod_url = urllib.parse.quote(mod_file) self.assertIn(mod_url, result) From webhook-mailer at python.org Thu Mar 17 12:53:45 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Thu, 17 Mar 2022 16:53:45 -0000 Subject: [Python-checkins] Fix whitespace error in setup.py (GH-31960) Message-ID: https://github.com/python/cpython/commit/424dfc723137fb1ca8f3b5e4eb12ba3e669a9f52 commit: 424dfc723137fb1ca8f3b5e4eb12ba3e669a9f52 branch: main author: Erlend Egeberg Aasland committer: JelleZijlstra date: 2022-03-17T09:53:29-07:00 summary: Fix whitespace error in setup.py (GH-31960) files: M setup.py diff --git a/setup.py b/setup.py index e47b2ab90958b..c3cf2417bc429 100644 --- a/setup.py +++ b/setup.py @@ -1247,7 +1247,7 @@ def detect_readline_curses(self): self.missing.append('_curses_panel') def detect_crypt(self): - self.addext(Extension('_crypt', ['_cryptmodule.c'])) + self.addext(Extension('_crypt', ['_cryptmodule.c'])) def detect_dbm_gdbm(self): # Modules that provide persistent dictionary-like semantics. You will From webhook-mailer at python.org Thu Mar 17 16:40:15 2022 From: webhook-mailer at python.org (asvetlov) Date: Thu, 17 Mar 2022 20:40:15 -0000 Subject: [Python-checkins] bpo-46030: socket module add couple of FreeBSD constants. (GH-30018) Message-ID: https://github.com/python/cpython/commit/33698e8ff40fcc67df3d95658e87196f8021de6f commit: 33698e8ff40fcc67df3d95658e87196f8021de6f branch: main author: David CARLIER committer: asvetlov date: 2022-03-17T22:40:00+02:00 summary: bpo-46030: socket module add couple of FreeBSD constants. (GH-30018) Co-authored-by: Andrew Svetlov files: A Misc/NEWS.d/next/Library/2021-12-10-07-07-47.bpo-46030.UN349J.rst M Doc/library/socket.rst M Modules/socketmodule.c diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index 679631a739092..f8392ba1254b7 100755 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -556,6 +556,21 @@ Constants .. availability:: Linux >= 4.7. +.. data:: SCM_CREDS2 + LOCAL_CREDS + LOCAL_CREDS_PERSISTENT + + LOCAL_CREDS and LOCAL_CREDS_PERSISTENT can be used + with SOCK_DGRAM, SOCK_STREAM sockets, equivalent to + Linux/DragonFlyBSD SO_PASSCRED, while LOCAL_CREDS + sends the credentials at first read, LOCAL_CREDS_PERSISTENT + sends for each read, SCM_CREDS2 must be then used for + the latter for the message type. + + .. versionadded:: 3.11 + + .. availability:: FreeBSD. + Functions ^^^^^^^^^ diff --git a/Misc/NEWS.d/next/Library/2021-12-10-07-07-47.bpo-46030.UN349J.rst b/Misc/NEWS.d/next/Library/2021-12-10-07-07-47.bpo-46030.UN349J.rst new file mode 100644 index 0000000000000..4f91b17963157 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-12-10-07-07-47.bpo-46030.UN349J.rst @@ -0,0 +1 @@ +Add ``LOCAL_CREDS``, ``LOCAL_CREDS_PERSISTENT`` and ``SCM_CREDS2`` FreeBSD constants to the socket module. diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index fbdd1a164db25..7f7af1895bd9f 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -7581,6 +7581,12 @@ PyInit__socket(void) #ifdef SO_PROTOCOL PyModule_AddIntMacro(m, SO_PROTOCOL); #endif +#ifdef LOCAL_CREDS + PyModule_AddIntMacro(m, LOCAL_CREDS); +#endif +#ifdef LOCAL_CREDS_PERSISTENT + PyModule_AddIntMacro(m, LOCAL_CREDS_PERSISTENT); +#endif /* Maximum number of connections for "listen" */ #ifdef SOMAXCONN @@ -7599,6 +7605,9 @@ PyInit__socket(void) #ifdef SCM_CREDS PyModule_AddIntMacro(m, SCM_CREDS); #endif +#ifdef SCM_CREDS2 + PyModule_AddIntMacro(m, SCM_CREDS2); +#endif /* Flags for send, recv */ #ifdef MSG_OOB From webhook-mailer at python.org Thu Mar 17 16:51:53 2022 From: webhook-mailer at python.org (asvetlov) Date: Thu, 17 Mar 2022 20:51:53 -0000 Subject: [Python-checkins] bpo-34790: Remove passing coroutine objects to asyncio.wait() (GH-31964) Message-ID: https://github.com/python/cpython/commit/903f0a02c16240dc769a08c30e8d072a4fb09154 commit: 903f0a02c16240dc769a08c30e8d072a4fb09154 branch: main author: Andrew Svetlov committer: asvetlov date: 2022-03-17T22:51:40+02:00 summary: bpo-34790: Remove passing coroutine objects to asyncio.wait() (GH-31964) Co-authored-by: Yury Selivanov files: A Misc/NEWS.d/next/Library/2022-03-17-19-38-40.bpo-34790.zQIiVJ.rst M Doc/library/asyncio-task.rst M Lib/asyncio/tasks.py M Lib/test/test_asyncio/test_tasks.py diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index faf5910124f9b..294f5ab2b22f9 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -534,7 +534,7 @@ Waiting Primitives .. coroutinefunction:: wait(aws, *, timeout=None, return_when=ALL_COMPLETED) - Run :ref:`awaitable objects ` in the *aws* + Run :class:`~asyncio.Future` and :class:`~asyncio.Task` instances in the *aws* iterable concurrently and block until the condition specified by *return_when*. @@ -577,51 +577,11 @@ Waiting Primitives Unlike :func:`~asyncio.wait_for`, ``wait()`` does not cancel the futures when a timeout occurs. - .. deprecated:: 3.8 - - If any awaitable in *aws* is a coroutine, it is automatically - scheduled as a Task. Passing coroutines objects to - ``wait()`` directly is deprecated as it leads to - :ref:`confusing behavior `. - - .. versionchanged:: 3.10 - Removed the *loop* parameter. - - .. _asyncio_example_wait_coroutine: - .. note:: - - ``wait()`` schedules coroutines as Tasks automatically and later - returns those implicitly created Task objects in ``(done, pending)`` - sets. Therefore the following code won't work as expected:: - - async def foo(): - return 42 - - coro = foo() - done, pending = await asyncio.wait({coro}) - - if coro in done: - # This branch will never be run! - - Here is how the above snippet can be fixed:: - - async def foo(): - return 42 - - task = asyncio.create_task(foo()) - done, pending = await asyncio.wait({task}) - - if task in done: - # Everything will work as expected now. - - .. deprecated-removed:: 3.8 3.11 - - Passing coroutine objects to ``wait()`` directly is - deprecated. - .. versionchanged:: 3.10 Removed the *loop* parameter. + .. versionchanged:: 3.11 + Passing coroutine objects to ``wait()`` directly is forbidden. .. function:: as_completed(aws, *, timeout=None) diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index 0b5f3226802de..e876f8d002ce4 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -387,7 +387,7 @@ def create_task(coro, *, name=None, context=None): async def wait(fs, *, timeout=None, return_when=ALL_COMPLETED): - """Wait for the Futures and coroutines given by fs to complete. + """Wait for the Futures or Tasks given by fs to complete. The fs iterable must not be empty. @@ -405,22 +405,16 @@ async def wait(fs, *, timeout=None, return_when=ALL_COMPLETED): if futures.isfuture(fs) or coroutines.iscoroutine(fs): raise TypeError(f"expect a list of futures, not {type(fs).__name__}") if not fs: - raise ValueError('Set of coroutines/Futures is empty.') + raise ValueError('Set of Tasks/Futures is empty.') if return_when not in (FIRST_COMPLETED, FIRST_EXCEPTION, ALL_COMPLETED): raise ValueError(f'Invalid return_when value: {return_when}') - loop = events.get_running_loop() - fs = set(fs) if any(coroutines.iscoroutine(f) for f in fs): - warnings.warn("The explicit passing of coroutine objects to " - "asyncio.wait() is deprecated since Python 3.8, and " - "scheduled for removal in Python 3.11.", - DeprecationWarning, stacklevel=2) - - fs = {ensure_future(f, loop=loop) for f in fs} + raise TypeError("Passing coroutines is forbidden, use tasks explicitly.") + loop = events.get_running_loop() return await _wait(fs, timeout, return_when, loop) diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 141c019dcb9cc..b86646ee398ae 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -997,13 +997,12 @@ def test_wait_duplicate_coroutines(self): async def coro(s): return s - c = coro('test') + c = self.loop.create_task(coro('test')) task = self.new_task( self.loop, - asyncio.wait([c, c, coro('spam')])) + asyncio.wait([c, c, self.loop.create_task(coro('spam'))])) - with self.assertWarns(DeprecationWarning): - done, pending = self.loop.run_until_complete(task) + done, pending = self.loop.run_until_complete(task) self.assertFalse(pending) self.assertEqual(set(f.result() for f in done), {'test', 'spam'}) @@ -1380,11 +1379,9 @@ def gen(): async def test(): futs = list(asyncio.as_completed(fs)) self.assertEqual(len(futs), 2) - waiter = asyncio.wait(futs) - # Deprecation from passing coros in futs to asyncio.wait() - with self.assertWarns(DeprecationWarning) as cm: - done, pending = await waiter - self.assertEqual(cm.warnings[0].filename, __file__) + done, pending = await asyncio.wait( + [asyncio.ensure_future(fut) for fut in futs] + ) self.assertEqual(set(f.result() for f in done), {'a', 'b'}) loop = self.new_test_loop(gen) @@ -1434,21 +1431,6 @@ async def test(): loop.run_until_complete(test()) - def test_as_completed_coroutine_use_global_loop(self): - # Deprecated in 3.10 - async def coro(): - return 42 - - loop = self.new_test_loop() - asyncio.set_event_loop(loop) - self.addCleanup(asyncio.set_event_loop, None) - futs = asyncio.as_completed([coro()]) - with self.assertWarns(DeprecationWarning) as cm: - futs = list(futs) - self.assertEqual(cm.warnings[0].filename, __file__) - self.assertEqual(len(futs), 1) - self.assertEqual(loop.run_until_complete(futs[0]), 42) - def test_sleep(self): def gen(): @@ -1751,7 +1733,7 @@ async def inner(): async def outer(): nonlocal proof with self.assertWarns(DeprecationWarning): - d, p = await asyncio.wait([inner()]) + d, p = await asyncio.wait([asyncio.create_task(inner())]) proof += 100 f = asyncio.ensure_future(outer(), loop=self.loop) @@ -3220,29 +3202,6 @@ async def coro(): self.assertEqual(result, 11) -class WaitTests(test_utils.TestCase): - def setUp(self): - super().setUp() - self.loop = asyncio.new_event_loop() - self.set_event_loop(self.loop) - - def tearDown(self): - self.loop.close() - self.loop = None - super().tearDown() - - def test_coro_is_deprecated_in_wait(self): - # Remove test when passing coros to asyncio.wait() is removed in 3.11 - with self.assertWarns(DeprecationWarning): - self.loop.run_until_complete( - asyncio.wait([coroutine_function()])) - - task = self.loop.create_task(coroutine_function()) - with self.assertWarns(DeprecationWarning): - self.loop.run_until_complete( - asyncio.wait([task, coroutine_function()])) - - class CompatibilityTests(test_utils.TestCase): # Tests for checking a bridge between old-styled coroutines # and async/await syntax diff --git a/Misc/NEWS.d/next/Library/2022-03-17-19-38-40.bpo-34790.zQIiVJ.rst b/Misc/NEWS.d/next/Library/2022-03-17-19-38-40.bpo-34790.zQIiVJ.rst new file mode 100644 index 0000000000000..50a71b5877fc4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-17-19-38-40.bpo-34790.zQIiVJ.rst @@ -0,0 +1 @@ +Remove passing coroutine objects to :func:`asyncio.wait`. From webhook-mailer at python.org Thu Mar 17 19:10:56 2022 From: webhook-mailer at python.org (sweeneyde) Date: Thu, 17 Mar 2022 23:10:56 -0000 Subject: [Python-checkins] bpo-47005: Improve performance of bytearray_repeat and bytearray_irepeat (GH-31856) Message-ID: https://github.com/python/cpython/commit/ac8308d3eaf2526318c1bbf13d4a214fd24605d2 commit: ac8308d3eaf2526318c1bbf13d4a214fd24605d2 branch: main author: Pieter Eendebak committer: sweeneyde <36520290+sweeneyde at users.noreply.github.com> date: 2022-03-17T19:10:36-04:00 summary: bpo-47005: Improve performance of bytearray_repeat and bytearray_irepeat (GH-31856) files: A Misc/NEWS.d/next/Core and Builtins/2022-03-13-21-04-20.bpo-47005.OHBfCc.rst M Objects/bytearrayobject.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-13-21-04-20.bpo-47005.OHBfCc.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-13-21-04-20.bpo-47005.OHBfCc.rst new file mode 100644 index 0000000000000..bf8a4f92a1e7f --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-13-21-04-20.bpo-47005.OHBfCc.rst @@ -0,0 +1 @@ +Improve performance of ``bytearray_repeat`` and ``bytearray_irepeat`` by reducing the number of invocations of ``memcpy``. diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 3493ff046ae13..ba2d347dbd7a8 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -335,9 +335,19 @@ bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count) if (mysize == 1) memset(result->ob_bytes, buf[0], size); else { - Py_ssize_t i; - for (i = 0; i < count; i++) - memcpy(result->ob_bytes + i*mysize, buf, mysize); + Py_ssize_t i, j; + + i = 0; + if (i < size) { + memcpy(result->ob_bytes, buf, mysize); + i = mysize; + } + // repeatedly double the number of bytes copied + while (i < size) { + j = Py_MIN(i, size - i); + memcpy(result->ob_bytes + i, result->ob_bytes, j); + i += j; + } } } return (PyObject *)result; @@ -363,9 +373,15 @@ bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count) if (mysize == 1) memset(buf, buf[0], size); else { - Py_ssize_t i; - for (i = 1; i < count; i++) - memcpy(buf + i*mysize, buf, mysize); + Py_ssize_t i, j; + + i = mysize; + // repeatedly double the number of bytes copied + while (i < size) { + j = Py_MIN(i, size - i); + memcpy(buf + i, buf, j); + i += j; + } } Py_INCREF(self); From webhook-mailer at python.org Thu Mar 17 19:38:00 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Thu, 17 Mar 2022 23:38:00 -0000 Subject: [Python-checkins] bpo-46421: Fix unittest filename evaluation when called as a module (GH-30654) Message-ID: https://github.com/python/cpython/commit/a0db11b10fca0fee6bb2b8d6277e266bad8c0fdb commit: a0db11b10fca0fee6bb2b8d6277e266bad8c0fdb branch: main author: Bader Zaidan committer: JelleZijlstra date: 2022-03-17T16:37:52-07:00 summary: bpo-46421: Fix unittest filename evaluation when called as a module (GH-30654) files: A Misc/NEWS.d/next/Library/2022-01-18-01-29-38.bpo-46421.9LdmNr.rst M Lib/test/test_cmd_line.py M Lib/unittest/main.py M Misc/ACKS diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index 1521b5b50ca24..84eab71f97701 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -166,6 +166,17 @@ def test_run_module_bug1764407(self): self.assertTrue(data.find(b'1 loop') != -1) self.assertTrue(data.find(b'__main__.Timer') != -1) + def test_relativedir_bug46421(self): + # Test `python -m unittest` with a relative directory beginning with ./ + # Note: We have to switch to the project's top module's directory, as per + # the python unittest wiki. We will switch back when we are done. + defaultwd = os.getcwd() + projectlibpath = os.path.dirname(__file__).removesuffix("test") + with os_helper.change_cwd(projectlibpath): + # Testing with and without ./ + assert_python_ok('-m', 'unittest', "test/test_longexp.py") + assert_python_ok('-m', 'unittest', "./test/test_longexp.py") + def test_run_code(self): # Test expected operation of the '-c' switch # Switch needs an argument diff --git a/Lib/unittest/main.py b/Lib/unittest/main.py index cb8f1f302801d..046fbd3a45dcf 100644 --- a/Lib/unittest/main.py +++ b/Lib/unittest/main.py @@ -40,7 +40,7 @@ def _convert_name(name): name = rel_path # on Windows both '\' and '/' are used as path # separators. Better to replace both than rely on os.path.sep - return name[:-3].replace('\\', '.').replace('/', '.') + return os.path.normpath(name)[:-3].replace('\\', '.').replace('/', '.') return name def _convert_names(names): diff --git a/Misc/ACKS b/Misc/ACKS index 00194f40f074a..895813e8fc208 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1994,6 +1994,7 @@ Masazumi Yoshikawa Arnaud Ysmal Bernard Yue Moshe Zadka +Bader Zaidan Elias Zamaria Milan Zamazal Artur Zaprzala diff --git a/Misc/NEWS.d/next/Library/2022-01-18-01-29-38.bpo-46421.9LdmNr.rst b/Misc/NEWS.d/next/Library/2022-01-18-01-29-38.bpo-46421.9LdmNr.rst new file mode 100644 index 0000000000000..03ff27fd7d1a7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-01-18-01-29-38.bpo-46421.9LdmNr.rst @@ -0,0 +1,3 @@ +Fix a unittest issue where if the command was invoked as ``python -m +unittest`` and the filename(s) began with a dot (.), a ``ValueError`` is +returned. From webhook-mailer at python.org Thu Mar 17 20:01:02 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 18 Mar 2022 00:01:02 -0000 Subject: [Python-checkins] bpo-46421: Fix unittest filename evaluation when called as a module (GH-30654) Message-ID: https://github.com/python/cpython/commit/0b5f99ad1af0892a2d6043abd8aeb10d685d3844 commit: 0b5f99ad1af0892a2d6043abd8aeb10d685d3844 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-17T17:00:52-07:00 summary: bpo-46421: Fix unittest filename evaluation when called as a module (GH-30654) (cherry picked from commit a0db11b10fca0fee6bb2b8d6277e266bad8c0fdb) Co-authored-by: Bader Zaidan files: A Misc/NEWS.d/next/Library/2022-01-18-01-29-38.bpo-46421.9LdmNr.rst M Lib/test/test_cmd_line.py M Lib/unittest/main.py M Misc/ACKS diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index d93e98f372532..d299f766dc500 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -137,6 +137,17 @@ def test_run_module_bug1764407(self): self.assertTrue(data.find(b'1 loop') != -1) self.assertTrue(data.find(b'__main__.Timer') != -1) + def test_relativedir_bug46421(self): + # Test `python -m unittest` with a relative directory beginning with ./ + # Note: We have to switch to the project's top module's directory, as per + # the python unittest wiki. We will switch back when we are done. + defaultwd = os.getcwd() + projectlibpath = os.path.dirname(__file__).removesuffix("test") + with os_helper.change_cwd(projectlibpath): + # Testing with and without ./ + assert_python_ok('-m', 'unittest', "test/test_longexp.py") + assert_python_ok('-m', 'unittest', "./test/test_longexp.py") + def test_run_code(self): # Test expected operation of the '-c' switch # Switch needs an argument diff --git a/Lib/unittest/main.py b/Lib/unittest/main.py index e62469aa2a170..88a188c545cd0 100644 --- a/Lib/unittest/main.py +++ b/Lib/unittest/main.py @@ -39,7 +39,7 @@ def _convert_name(name): name = rel_path # on Windows both '\' and '/' are used as path # separators. Better to replace both than rely on os.path.sep - return name[:-3].replace('\\', '.').replace('/', '.') + return os.path.normpath(name)[:-3].replace('\\', '.').replace('/', '.') return name def _convert_names(names): diff --git a/Misc/ACKS b/Misc/ACKS index 7668caf43bc36..1f1364e4f0bb8 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1983,6 +1983,7 @@ Masazumi Yoshikawa Arnaud Ysmal Bernard Yue Moshe Zadka +Bader Zaidan Elias Zamaria Milan Zamazal Artur Zaprzala diff --git a/Misc/NEWS.d/next/Library/2022-01-18-01-29-38.bpo-46421.9LdmNr.rst b/Misc/NEWS.d/next/Library/2022-01-18-01-29-38.bpo-46421.9LdmNr.rst new file mode 100644 index 0000000000000..03ff27fd7d1a7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-01-18-01-29-38.bpo-46421.9LdmNr.rst @@ -0,0 +1,3 @@ +Fix a unittest issue where if the command was invoked as ``python -m +unittest`` and the filename(s) began with a dot (.), a ``ValueError`` is +returned. From webhook-mailer at python.org Thu Mar 17 22:46:05 2022 From: webhook-mailer at python.org (orsenthil) Date: Fri, 18 Mar 2022 02:46:05 -0000 Subject: [Python-checkins] [3.9] bpo-42782: fix broken shutil test (GH-31971) Message-ID: https://github.com/python/cpython/commit/e808c9d5c78e5a7a9d804eced013a02c0c7df1a5 commit: e808c9d5c78e5a7a9d804eced013a02c0c7df1a5 branch: 3.9 author: Jelle Zijlstra committer: orsenthil date: 2022-03-17T19:45:40-07:00 summary: [3.9] bpo-42782: fix broken shutil test (GH-31971) We were using os_helper, which doesn't exist on 3.9. This wasn't caught because the test is only run as root. I confirmed that when run as root, the test previously failed and now passes. files: M Lib/test/test_shutil.py diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index 85cac94dfec78..3890df93bbccd 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -2154,7 +2154,7 @@ def test_move_dir_permission_denied(self): # Create a file and keep the directory immutable os.lchflags(TESTFN_SRC, stat.UF_OPAQUE) - os_helper.create_empty_file(os.path.join(TESTFN_SRC, 'child')) + support.create_empty_file(os.path.join(TESTFN_SRC, 'child')) os.lchflags(TESTFN_SRC, stat.SF_IMMUTABLE) # Testing on a non-empty immutable directory @@ -2164,10 +2164,10 @@ def test_move_dir_permission_denied(self): finally: if os.path.exists(TESTFN_SRC): os.lchflags(TESTFN_SRC, stat.UF_OPAQUE) - os_helper.rmtree(TESTFN_SRC) + support.rmtree(TESTFN_SRC) if os.path.exists(TESTFN_DST): os.lchflags(TESTFN_DST, stat.UF_OPAQUE) - os_helper.rmtree(TESTFN_DST) + support.rmtree(TESTFN_DST) class TestCopyFile(unittest.TestCase): From webhook-mailer at python.org Thu Mar 17 23:25:04 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Fri, 18 Mar 2022 03:25:04 -0000 Subject: [Python-checkins] [3.9] bpo-46421: Fix unittest filename evaluation when called as a module (GH-30654) (GH-31970) Message-ID: https://github.com/python/cpython/commit/1cab44d8650ae3eece90b04fca373908205e7ee0 commit: 1cab44d8650ae3eece90b04fca373908205e7ee0 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: JelleZijlstra date: 2022-03-17T20:24:59-07:00 summary: [3.9] bpo-46421: Fix unittest filename evaluation when called as a module (GH-30654) (GH-31970) (cherry picked from commit a0db11b10fca0fee6bb2b8d6277e266bad8c0fdb) Co-authored-by: Bader Zaidan files: A Misc/NEWS.d/next/Library/2022-01-18-01-29-38.bpo-46421.9LdmNr.rst M Lib/test/test_cmd_line.py M Lib/unittest/main.py M Misc/ACKS diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index 712d861c4d5a3..4b3e33c4fd354 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -136,6 +136,17 @@ def test_run_module_bug1764407(self): self.assertTrue(data.find(b'1 loop') != -1) self.assertTrue(data.find(b'__main__.Timer') != -1) + def test_relativedir_bug46421(self): + # Test `python -m unittest` with a relative directory beginning with ./ + # Note: We have to switch to the project's top module's directory, as per + # the python unittest wiki. We will switch back when we are done. + defaultwd = os.getcwd() + projectlibpath = os.path.dirname(__file__).removesuffix("test") + with support.change_cwd(projectlibpath): + # Testing with and without ./ + assert_python_ok('-m', 'unittest', "test/test_longexp.py") + assert_python_ok('-m', 'unittest', "./test/test_longexp.py") + def test_run_code(self): # Test expected operation of the '-c' switch # Switch needs an argument diff --git a/Lib/unittest/main.py b/Lib/unittest/main.py index e62469aa2a170..88a188c545cd0 100644 --- a/Lib/unittest/main.py +++ b/Lib/unittest/main.py @@ -39,7 +39,7 @@ def _convert_name(name): name = rel_path # on Windows both '\' and '/' are used as path # separators. Better to replace both than rely on os.path.sep - return name[:-3].replace('\\', '.').replace('/', '.') + return os.path.normpath(name)[:-3].replace('\\', '.').replace('/', '.') return name def _convert_names(names): diff --git a/Misc/ACKS b/Misc/ACKS index 2a26fdcd16b43..d043195a7b550 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1947,6 +1947,7 @@ Masazumi Yoshikawa Arnaud Ysmal Bernard Yue Moshe Zadka +Bader Zaidan Elias Zamaria Milan Zamazal Artur Zaprzala diff --git a/Misc/NEWS.d/next/Library/2022-01-18-01-29-38.bpo-46421.9LdmNr.rst b/Misc/NEWS.d/next/Library/2022-01-18-01-29-38.bpo-46421.9LdmNr.rst new file mode 100644 index 0000000000000..03ff27fd7d1a7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-01-18-01-29-38.bpo-46421.9LdmNr.rst @@ -0,0 +1,3 @@ +Fix a unittest issue where if the command was invoked as ``python -m +unittest`` and the filename(s) began with a dot (.), a ``ValueError`` is +returned. From webhook-mailer at python.org Fri Mar 18 05:05:28 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Fri, 18 Mar 2022 09:05:28 -0000 Subject: [Python-checkins] bpo-40296: Fix supporting generic aliases in pydoc (GH-30253) Message-ID: https://github.com/python/cpython/commit/cd44afc573e2e2de8d7e5a9119c347373066cd10 commit: cd44afc573e2e2de8d7e5a9119c347373066cd10 branch: main author: Serhiy Storchaka committer: serhiy-storchaka date: 2022-03-18T11:05:18+02:00 summary: bpo-40296: Fix supporting generic aliases in pydoc (GH-30253) files: A Misc/NEWS.d/next/Library/2021-12-25-14-13-14.bpo-40296.p0YVGB.rst M Lib/pydoc.py M Lib/test/pydoc_mod.py M Lib/test/test_pydoc.py diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 7d52359c9a0ce..85eefa46b7299 100755 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -69,6 +69,7 @@ class or function within a module or module in a package. If the import sysconfig import time import tokenize +import types import urllib.parse import warnings from collections import deque @@ -90,13 +91,16 @@ def pathdirs(): normdirs.append(normdir) return dirs +def _isclass(object): + return inspect.isclass(object) and not isinstance(object, types.GenericAlias) + def _findclass(func): cls = sys.modules.get(func.__module__) if cls is None: return None for name in func.__qualname__.split('.')[:-1]: cls = getattr(cls, name) - if not inspect.isclass(cls): + if not _isclass(cls): return None return cls @@ -104,7 +108,7 @@ def _finddoc(obj): if inspect.ismethod(obj): name = obj.__func__.__name__ self = obj.__self__ - if (inspect.isclass(self) and + if (_isclass(self) and getattr(getattr(self, name, None), '__func__') is obj.__func__): # classmethod cls = self @@ -118,7 +122,7 @@ def _finddoc(obj): elif inspect.isbuiltin(obj): name = obj.__name__ self = obj.__self__ - if (inspect.isclass(self) and + if (_isclass(self) and self.__qualname__ + '.' + name == obj.__qualname__): # classmethod cls = self @@ -205,7 +209,7 @@ def classname(object, modname): def isdata(object): """Check if an object is of a type that probably means it's data.""" - return not (inspect.ismodule(object) or inspect.isclass(object) or + return not (inspect.ismodule(object) or _isclass(object) or inspect.isroutine(object) or inspect.isframe(object) or inspect.istraceback(object) or inspect.iscode(object)) @@ -470,7 +474,7 @@ def document(self, object, name=None, *args): # by lacking a __name__ attribute) and an instance. try: if inspect.ismodule(object): return self.docmodule(*args) - if inspect.isclass(object): return self.docclass(*args) + if _isclass(object): return self.docclass(*args) if inspect.isroutine(object): return self.docroutine(*args) except AttributeError: pass @@ -772,7 +776,7 @@ def docmodule(self, object, name=None, mod=None, *ignored): modules = inspect.getmembers(object, inspect.ismodule) classes, cdict = [], {} - for key, value in inspect.getmembers(object, inspect.isclass): + for key, value in inspect.getmembers(object, _isclass): # if __all__ exists, believe it. Otherwise use old heuristic. if (all is not None or (inspect.getmodule(value) or object) is object): @@ -1212,7 +1216,7 @@ def docmodule(self, object, name=None, mod=None): result = result + self.section('DESCRIPTION', desc) classes = [] - for key, value in inspect.getmembers(object, inspect.isclass): + for key, value in inspect.getmembers(object, _isclass): # if __all__ exists, believe it. Otherwise use old heuristic. if (all is not None or (inspect.getmodule(value) or object) is object): @@ -1696,7 +1700,7 @@ def describe(thing): return 'member descriptor %s.%s.%s' % ( thing.__objclass__.__module__, thing.__objclass__.__name__, thing.__name__) - if inspect.isclass(thing): + if _isclass(thing): return 'class ' + thing.__name__ if inspect.isfunction(thing): return 'function ' + thing.__name__ @@ -1757,7 +1761,7 @@ def render_doc(thing, title='Python Library Documentation: %s', forceload=0, desc += ' in module ' + module.__name__ if not (inspect.ismodule(object) or - inspect.isclass(object) or + _isclass(object) or inspect.isroutine(object) or inspect.isdatadescriptor(object) or _getdoc(object)): diff --git a/Lib/test/pydoc_mod.py b/Lib/test/pydoc_mod.py index 9c1fff5c2f2c1..f9bc4b89d3d0a 100644 --- a/Lib/test/pydoc_mod.py +++ b/Lib/test/pydoc_mod.py @@ -1,5 +1,8 @@ """This is a test module for test_pydoc""" +import types +import typing + __author__ = "Benjamin Peterson" __credits__ = "Nobody" __version__ = "1.2.3.4" @@ -24,6 +27,8 @@ def get_answer(self): def is_it_true(self): """ Return self.get_answer() """ return self.get_answer() + def __class_getitem__(self, item): + return types.GenericAlias(self, item) def doc_func(): """ @@ -35,3 +40,10 @@ def doc_func(): def nodoc_func(): pass + + +list_alias1 = typing.List[int] +list_alias2 = list[int] +c_alias = C[int] +type_union1 = typing.Union[int, str] +type_union2 = int | str diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py index 4f18af3f0ec69..7cedf76fb3af4 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -95,6 +95,11 @@ class C(builtins.object) | say_no(self) |\x20\x20 | ---------------------------------------------------------------------- + | Class methods defined here: + |\x20\x20 + | __class_getitem__(item) from builtins.type + |\x20\x20 + | ---------------------------------------------------------------------- | Data descriptors defined here: |\x20\x20 | __dict__ @@ -114,6 +119,11 @@ class C(builtins.object) DATA __xyz__ = 'X, Y and Z' + c_alias = test.pydoc_mod.C[int] + list_alias1 = typing.List[int] + list_alias2 = list[int] + type_union1 = typing.Union[int, str] + type_union2 = int | str VERSION 1.2.3.4 @@ -135,6 +145,10 @@ class C(builtins.object) test.pydoc_mod (version 1.2.3.4) This is a test module for test_pydoc +Modules + types + typing + Classes builtins.object A @@ -172,6 +186,8 @@ class C(builtins.object) is_it_true(self) Return self.get_answer() say_no(self) + Class methods defined here: + __class_getitem__(item) from builtins.type Data descriptors defined here: __dict__ dictionary for instance variables (if defined) @@ -188,6 +204,11 @@ class C(builtins.object) Data __xyz__ = 'X, Y and Z' + c_alias = test.pydoc_mod.C[int] + list_alias1 = typing.List[int] + list_alias2 = list[int] + type_union1 = typing.Union[int, str] + type_union2 = int | str Author Benjamin Peterson @@ -1000,6 +1021,43 @@ class C: "New-style class" expected = 'C in module %s object' % __name__ self.assertIn(expected, pydoc.render_doc(c)) + def test_generic_alias(self): + self.assertEqual(pydoc.describe(typing.List[int]), '_GenericAlias') + doc = pydoc.render_doc(typing.List[int], renderer=pydoc.plaintext) + self.assertIn('_GenericAlias in module typing', doc) + self.assertIn('List = class list(object)', doc) + self.assertIn(list.__doc__.strip().splitlines()[0], doc) + + self.assertEqual(pydoc.describe(list[int]), 'GenericAlias') + doc = pydoc.render_doc(list[int], renderer=pydoc.plaintext) + self.assertIn('GenericAlias in module builtins', doc) + self.assertIn('\nclass list(object)', doc) + self.assertIn(list.__doc__.strip().splitlines()[0], doc) + + def test_union_type(self): + self.assertEqual(pydoc.describe(typing.Union[int, str]), '_UnionGenericAlias') + doc = pydoc.render_doc(typing.Union[int, str], renderer=pydoc.plaintext) + self.assertIn('_UnionGenericAlias in module typing', doc) + self.assertIn('Union = typing.Union', doc) + if typing.Union.__doc__: + self.assertIn(typing.Union.__doc__.strip().splitlines()[0], doc) + + self.assertEqual(pydoc.describe(int | str), 'UnionType') + doc = pydoc.render_doc(int | str, renderer=pydoc.plaintext) + self.assertIn('UnionType in module types object', doc) + self.assertIn('\nclass UnionType(builtins.object)', doc) + self.assertIn(types.UnionType.__doc__.strip().splitlines()[0], doc) + + def test_special_form(self): + self.assertEqual(pydoc.describe(typing.Any), '_SpecialForm') + doc = pydoc.render_doc(typing.Any, renderer=pydoc.plaintext) + self.assertIn('_SpecialForm in module typing', doc) + if typing.Any.__doc__: + self.assertIn('Any = typing.Any', doc) + self.assertIn(typing.Any.__doc__.strip().splitlines()[0], doc) + else: + self.assertIn('Any = class _SpecialForm(_Final)', doc) + def test_typing_pydoc(self): def foo(data: typing.List[typing.Any], x: int) -> typing.Iterator[typing.Tuple[int, typing.Any]]: diff --git a/Misc/NEWS.d/next/Library/2021-12-25-14-13-14.bpo-40296.p0YVGB.rst b/Misc/NEWS.d/next/Library/2021-12-25-14-13-14.bpo-40296.p0YVGB.rst new file mode 100644 index 0000000000000..ea469c916b9db --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-12-25-14-13-14.bpo-40296.p0YVGB.rst @@ -0,0 +1 @@ +Fix supporting generic aliases in :mod:`pydoc`. From webhook-mailer at python.org Fri Mar 18 05:53:36 2022 From: webhook-mailer at python.org (encukou) Date: Fri, 18 Mar 2022 09:53:36 -0000 Subject: [Python-checkins] bpo-45413: Define "posix_venv", "nt_venv" and "venv" sysconfig installation schemes (GH-31034) Message-ID: https://github.com/python/cpython/commit/48d926269963cfe7a49c0a4f34af4fe9b832399b commit: 48d926269963cfe7a49c0a4f34af4fe9b832399b branch: main author: Miro Hron?ok committer: encukou date: 2022-03-18T10:53:29+01:00 summary: bpo-45413: Define "posix_venv", "nt_venv" and "venv" sysconfig installation schemes (GH-31034) Define *posix_venv* and *nt_venv* sysconfig installation schemes to be used for bootstrapping new virtual environments. Add *venv* sysconfig installation scheme to get the appropriate one of the above. The schemes are identical to the pre-existing *posix_prefix* and *nt* install schemes. The venv module now uses the *venv* scheme to create new virtual environments instead of hardcoding the paths depending only on the platform. Downstream Python distributors customizing the *posix_prefix* or *nt* install scheme in a way that is not compatible with the install scheme used in virtual environments are encouraged not to customize the *venv* schemes. When Python itself runs in a virtual environment, sysconfig.get_default_scheme and sysconfig.get_preferred_scheme with `key="prefix"` returns *venv*. files: A Misc/NEWS.d/next/Library/2022-01-31-15-19-38.bpo-45413.1vaS0V.rst M Doc/library/sysconfig.rst M Doc/library/venv.rst M Doc/whatsnew/3.11.rst M Lib/sysconfig.py M Lib/test/test_sysconfig.py M Lib/test/test_venv.py M Lib/venv/__init__.py diff --git a/Doc/library/sysconfig.rst b/Doc/library/sysconfig.rst index 713be1e02cea6..fa18d62d22af5 100644 --- a/Doc/library/sysconfig.rst +++ b/Doc/library/sysconfig.rst @@ -73,7 +73,7 @@ Every new component that is installed using :mod:`distutils` or a Distutils-based system will follow the same scheme to copy its file in the right places. -Python currently supports six schemes: +Python currently supports nine schemes: - *posix_prefix*: scheme for POSIX platforms like Linux or macOS. This is the default scheme used when Python or a component is installed. @@ -83,8 +83,14 @@ Python currently supports six schemes: - *posix_user*: scheme for POSIX platforms used when a component is installed through Distutils and the *user* option is used. This scheme defines paths located under the user home directory. +- *posix_venv*: scheme for :mod:`Python virtual environments ` on POSIX + platforms; by default it is the same as *posix_prefix* . - *nt*: scheme for NT platforms like Windows. - *nt_user*: scheme for NT platforms, when the *user* option is used. +- *nt_venv*: scheme for :mod:`Python virtual environments ` on NT + platforms; by default it is the same as *nt* . +- *venv*: a scheme with values from ether *posix_venv* or *nt_venv* depending + on the platform Python runs on - *osx_framework_user*: scheme for macOS, when the *user* option is used. Each scheme is itself composed of a series of paths and each path has a unique @@ -119,6 +125,9 @@ identifier. Python currently uses eight paths: This function was previously named ``_get_default_scheme()`` and considered an implementation detail. + .. versionchanged:: 3.11 + When Python runs from a virtual environment, + the *venv* scheme is returned. .. function:: get_preferred_scheme(key) @@ -132,6 +141,10 @@ identifier. Python currently uses eight paths: .. versionadded:: 3.10 + .. versionchanged:: 3.11 + When Python runs from a virtual environment and ``key="prefix"``, + the *venv* scheme is returned. + .. function:: _get_preferred_schemes() diff --git a/Doc/library/venv.rst b/Doc/library/venv.rst index 092781b5ff1c4..b40bd4102c259 100644 --- a/Doc/library/venv.rst +++ b/Doc/library/venv.rst @@ -177,6 +177,11 @@ creation according to their needs, the :class:`EnvBuilder` class. ``clear=True``, contents of the environment directory will be cleared and then all necessary subdirectories will be recreated. + .. versionchanged:: 3.11 + The *venv* + :ref:`sysconfig installation scheme ` + is used to construct the paths of the created directories. + .. method:: create_configuration(context) Creates the ``pyvenv.cfg`` configuration file in the environment. diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 391423407eecd..2af663809a448 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -361,6 +361,24 @@ sys (equivalent to ``sys.exc_info()[1]``). (Contributed by Irit Katriel in :issue:`46328`.) + +sysconfig +--------- + +* Two new :ref:`installation schemes ` + (*posix_venv*, *nt_venv* and *venv*) were added and are used when Python + creates new virtual environments or when it is running from a virtual + environment. + The first two schemes (*posix_venv* and *nt_venv*) are OS-specific + for non-Windows and Windows, the *venv* is essentially an alias to one of + them according to the OS Python runs on. + This is useful for downstream distributors who modify + :func:`sysconfig.get_preferred_scheme`. + Third party code that creates new virtual environments should use the new + *venv* installation scheme to determine the paths, as does :mod:`venv`. + (Contributed by Miro Hron?ok in :issue:`45413`.) + + threading --------- @@ -395,6 +413,20 @@ unicodedata * The Unicode database has been updated to version 14.0.0. (:issue:`45190`). +venv +---- + +* When new Python virtual environments are created, the *venv* + :ref:`sysconfig installation scheme ` is used + to determine the paths inside the environment. + When Python runs in a virtual environment, the same installation scheme + is the default. + That means that downstream distributors can change the default sysconfig install + scheme without changing behavior of virtual environments. + Third party code that also creates new virtual environments should do the same. + (Contributed by Miro Hron?ok in :issue:`45413`.) + + fcntl ----- diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py index d4a8a680286c1..2a01342eda8d6 100644 --- a/Lib/sysconfig.py +++ b/Lib/sysconfig.py @@ -56,8 +56,53 @@ 'scripts': '{base}/Scripts', 'data': '{base}', }, + # Downstream distributors can overwrite the default install scheme. + # This is done to support downstream modifications where distributors change + # the installation layout (eg. different site-packages directory). + # So, distributors will change the default scheme to one that correctly + # represents their layout. + # This presents an issue for projects/people that need to bootstrap virtual + # environments, like virtualenv. As distributors might now be customizing + # the default install scheme, there is no guarantee that the information + # returned by sysconfig.get_default_scheme/get_paths is correct for + # a virtual environment, the only guarantee we have is that it is correct + # for the *current* environment. When bootstrapping a virtual environment, + # we need to know its layout, so that we can place the files in the + # correct locations. + # The "*_venv" install scheme is a scheme to bootstrap virtual environments, + # essentially identical to the default posix_prefix/nt schemes. + # Downstream distributors who patch posix_prefix/nt scheme are encouraged to + # leave the following schemes unchanged + 'posix_venv': { + 'stdlib': '{installed_base}/{platlibdir}/python{py_version_short}', + 'platstdlib': '{platbase}/{platlibdir}/python{py_version_short}', + 'purelib': '{base}/lib/python{py_version_short}/site-packages', + 'platlib': '{platbase}/{platlibdir}/python{py_version_short}/site-packages', + 'include': + '{installed_base}/include/python{py_version_short}{abiflags}', + 'platinclude': + '{installed_platbase}/include/python{py_version_short}{abiflags}', + 'scripts': '{base}/bin', + 'data': '{base}', + }, + 'nt_venv': { + 'stdlib': '{installed_base}/Lib', + 'platstdlib': '{base}/Lib', + 'purelib': '{base}/Lib/site-packages', + 'platlib': '{base}/Lib/site-packages', + 'include': '{installed_base}/Include', + 'platinclude': '{installed_base}/Include', + 'scripts': '{base}/Scripts', + 'data': '{base}', + }, } +# For the OS-native venv scheme, we essentially provide an alias: +if os.name == 'nt': + _INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['nt_venv'] +else: + _INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['posix_venv'] + # NOTE: site.py has copy of this function. # Sync it when modify this function. @@ -251,6 +296,8 @@ def _get_preferred_schemes(): def get_preferred_scheme(key): + if key == 'prefix' and sys.prefix != sys.base_prefix: + return 'venv' scheme = _get_preferred_schemes()[key] if scheme not in _INSTALL_SCHEMES: raise ValueError( diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index 2c4120979d9a2..c7ec78fa4dc81 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -139,6 +139,72 @@ def test_get_preferred_schemes(self): self.assertIsInstance(schemes, dict) self.assertEqual(set(schemes), expected_schemes) + def test_posix_venv_scheme(self): + # The following directories were hardcoded in the venv module + # before bpo-45413, here we assert the posix_venv scheme does not regress + binpath = 'bin' + incpath = 'include' + libpath = os.path.join('lib', + 'python%d.%d' % sys.version_info[:2], + 'site-packages') + + # Resolve the paths in prefix + binpath = os.path.join(sys.prefix, binpath) + incpath = os.path.join(sys.prefix, incpath) + libpath = os.path.join(sys.prefix, libpath) + + self.assertEqual(binpath, sysconfig.get_path('scripts', scheme='posix_venv')) + self.assertEqual(libpath, sysconfig.get_path('purelib', scheme='posix_venv')) + + # The include directory on POSIX isn't exactly the same as before, + # but it is "within" + sysconfig_includedir = sysconfig.get_path('include', scheme='posix_venv') + self.assertTrue(sysconfig_includedir.startswith(incpath + os.sep)) + + def test_nt_venv_scheme(self): + # The following directories were hardcoded in the venv module + # before bpo-45413, here we assert the posix_venv scheme does not regress + binpath = 'Scripts' + incpath = 'Include' + libpath = os.path.join('Lib', 'site-packages') + + # Resolve the paths in prefix + binpath = os.path.join(sys.prefix, binpath) + incpath = os.path.join(sys.prefix, incpath) + libpath = os.path.join(sys.prefix, libpath) + + self.assertEqual(binpath, sysconfig.get_path('scripts', scheme='nt_venv')) + self.assertEqual(incpath, sysconfig.get_path('include', scheme='nt_venv')) + self.assertEqual(libpath, sysconfig.get_path('purelib', scheme='nt_venv')) + + def test_venv_scheme(self): + if sys.platform == 'win32': + self.assertEqual( + sysconfig.get_path('scripts', scheme='venv'), + sysconfig.get_path('scripts', scheme='nt_venv') + ) + self.assertEqual( + sysconfig.get_path('include', scheme='venv'), + sysconfig.get_path('include', scheme='nt_venv') + ) + self.assertEqual( + sysconfig.get_path('purelib', scheme='venv'), + sysconfig.get_path('purelib', scheme='nt_venv') + ) + else: + self.assertEqual( + sysconfig.get_path('scripts', scheme='venv'), + sysconfig.get_path('scripts', scheme='posix_venv') + ) + self.assertEqual( + sysconfig.get_path('include', scheme='venv'), + sysconfig.get_path('include', scheme='posix_venv') + ) + self.assertEqual( + sysconfig.get_path('purelib', scheme='venv'), + sysconfig.get_path('purelib', scheme='posix_venv') + ) + def test_get_config_vars(self): cvars = get_config_vars() self.assertIsInstance(cvars, dict) @@ -267,7 +333,7 @@ def test_get_config_h_filename(self): self.assertTrue(os.path.isfile(config_h), config_h) def test_get_scheme_names(self): - wanted = ['nt', 'posix_home', 'posix_prefix'] + wanted = ['nt', 'posix_home', 'posix_prefix', 'posix_venv', 'nt_venv', 'venv'] if HAS_USER_BASE: wanted.extend(['nt_user', 'osx_framework_user', 'posix_user']) self.assertEqual(get_scheme_names(), tuple(sorted(wanted))) diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py index 043158c79214b..db812f21dbc56 100644 --- a/Lib/test/test_venv.py +++ b/Lib/test/test_venv.py @@ -236,6 +236,20 @@ def test_prefixes(self): out, err = check_output(cmd) self.assertEqual(out.strip(), expected.encode(), prefix) + @requireVenvCreate + def test_sysconfig_preferred_and_default_scheme(self): + """ + Test that the sysconfig preferred(prefix) and default scheme is venv. + """ + rmtree(self.env_dir) + self.run_with_capture(venv.create, self.env_dir) + envpy = os.path.join(self.env_dir, self.bindir, self.exe) + cmd = [envpy, '-c', None] + for call in ('get_preferred_scheme("prefix")', 'get_default_scheme()'): + cmd[2] = 'import sysconfig; print(sysconfig.%s)' % call + out, err = check_output(cmd) + self.assertEqual(out.strip(), b'venv', err) + if sys.platform == 'win32': ENV_SUBDIRS = ( ('Scripts',), diff --git a/Lib/venv/__init__.py b/Lib/venv/__init__.py index b90765074c36d..a8640d9163fbe 100644 --- a/Lib/venv/__init__.py +++ b/Lib/venv/__init__.py @@ -93,6 +93,15 @@ def clear_directory(self, path): elif os.path.isdir(fn): shutil.rmtree(fn) + def _venv_path(self, env_dir, name): + vars = { + 'base': env_dir, + 'platbase': env_dir, + 'installed_base': env_dir, + 'installed_platbase': env_dir, + } + return sysconfig.get_path(name, scheme='venv', vars=vars) + def ensure_directories(self, env_dir): """ Create the directories for the environment. @@ -120,18 +129,12 @@ def create_if_needed(d): context.executable = executable context.python_dir = dirname context.python_exe = exename - if sys.platform == 'win32': - binname = 'Scripts' - incpath = 'Include' - libpath = os.path.join(env_dir, 'Lib', 'site-packages') - else: - binname = 'bin' - incpath = 'include' - libpath = os.path.join(env_dir, 'lib', - 'python%d.%d' % sys.version_info[:2], - 'site-packages') - context.inc_path = path = os.path.join(env_dir, incpath) - create_if_needed(path) + binpath = self._venv_path(env_dir, 'scripts') + incpath = self._venv_path(env_dir, 'include') + libpath = self._venv_path(env_dir, 'purelib') + + context.inc_path = incpath + create_if_needed(incpath) create_if_needed(libpath) # Issue 21197: create lib64 as a symlink to lib on 64-bit non-OS X POSIX if ((sys.maxsize > 2**32) and (os.name == 'posix') and @@ -139,8 +142,8 @@ def create_if_needed(d): link_path = os.path.join(env_dir, 'lib64') if not os.path.exists(link_path): # Issue #21643 os.symlink('lib', link_path) - context.bin_path = binpath = os.path.join(env_dir, binname) - context.bin_name = binname + context.bin_path = binpath + context.bin_name = os.path.relpath(binpath, env_dir) context.env_exe = os.path.join(binpath, exename) create_if_needed(binpath) # Assign and update the command to use when launching the newly created diff --git a/Misc/NEWS.d/next/Library/2022-01-31-15-19-38.bpo-45413.1vaS0V.rst b/Misc/NEWS.d/next/Library/2022-01-31-15-19-38.bpo-45413.1vaS0V.rst new file mode 100644 index 0000000000000..6daff85781a5d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-01-31-15-19-38.bpo-45413.1vaS0V.rst @@ -0,0 +1,15 @@ +Define *posix_venv* and *nt_venv* +:ref:`sysconfig installation schemes ` +to be used for bootstrapping new virtual environments. +Add *venv* sysconfig installation scheme to get the appropriate one of the above. +The schemes are identical to the pre-existing +*posix_prefix* and *nt* install schemes. +The :mod:`venv` module now uses the *venv* scheme to create new virtual environments +instead of hardcoding the paths depending only on the platform. Downstream +Python distributors customizing the *posix_prefix* or *nt* install +scheme in a way that is not compatible with the install scheme used in +virtual environments are encouraged not to customize the *venv* schemes. +When Python itself runs in a virtual environment, +:func:`sysconfig.get_default_scheme` and +:func:`sysconfig.get_preferred_scheme` with ``key="prefix"`` returns +*venv*. From webhook-mailer at python.org Fri Mar 18 06:10:36 2022 From: webhook-mailer at python.org (markshannon) Date: Fri, 18 Mar 2022 10:10:36 -0000 Subject: [Python-checkins] summarize_stats.py: add pairs by opcode (GH-31957) Message-ID: https://github.com/python/cpython/commit/d7a93cbf4b0d2d4eb8dbda3eb67d31a7cf4decf8 commit: d7a93cbf4b0d2d4eb8dbda3eb67d31a7cf4decf8 branch: main author: Dennis Sweeney <36520290+sweeneyde at users.noreply.github.com> committer: markshannon date: 2022-03-18T10:10:31Z summary: summarize_stats.py: add pairs by opcode (GH-31957) files: M Tools/scripts/summarize_stats.py diff --git a/Tools/scripts/summarize_stats.py b/Tools/scripts/summarize_stats.py index 69babfd2ddafc..bc528ca316f93 100644 --- a/Tools/scripts/summarize_stats.py +++ b/Tools/scripts/summarize_stats.py @@ -25,6 +25,11 @@ pass opname.append(name) +# opcode_name --> opcode +# Sort alphabetically. +opmap = {name: i for i, name in enumerate(opname)} +opmap = dict(sorted(opmap.items())) + TOTAL = "specialization.deferred", "specialization.hit", "specialization.miss", "execution_count" def print_specialization_stats(name, family_stats, defines): @@ -281,16 +286,16 @@ def get_total(opcode_stats): return total def emit_pair_counts(opcode_stats, total): + pair_counts = [] + for i, opcode_stat in enumerate(opcode_stats): + if i == 0: + continue + for key, value in opcode_stat.items(): + if key.startswith("pair_count"): + x, _, _ = key[11:].partition("]") + if value: + pair_counts.append((value, (i, int(x)))) with Section("Pair counts", summary="Pair counts for top 100 pairs"): - pair_counts = [] - for i, opcode_stat in enumerate(opcode_stats): - if i == 0: - continue - for key, value in opcode_stat.items(): - if key.startswith("pair_count"): - x, _, _ = key[11:].partition("]") - if value: - pair_counts.append((value, (i, int(x)))) pair_counts.sort(reverse=True) cumulative = 0 rows = [] @@ -302,6 +307,36 @@ def emit_pair_counts(opcode_stats, total): emit_table(("Pair", "Count:", "Self:", "Cumulative:"), rows ) + with Section("Predecessor/Successor Pairs", summary="Top 3 predecessors and successors of each opcode"): + predecessors = collections.defaultdict(collections.Counter) + successors = collections.defaultdict(collections.Counter) + total_predecessors = collections.Counter() + total_successors = collections.Counter() + for count, (first, second) in pair_counts: + if count: + predecessors[second][first] = count + successors[first][second] = count + total_predecessors[second] += count + total_successors[first] += count + for name, i in opmap.items(): + total1 = total_predecessors[i] + total2 = total_successors[i] + if total1 == 0 and total2 == 0: + continue + pred_rows = succ_rows = () + if total1: + pred_rows = [(opname[pred], count, f"{count/total1:.1%}") + for (pred, count) in predecessors[i].most_common(3)] + if total2: + succ_rows = [(opname[succ], count, f"{count/total2:.1%}") + for (succ, count) in successors[i].most_common(3)] + with Section(name, 3, f"Successors and predecessors for {name}"): + emit_table(("Predecessors", "Count:", "Percentage:"), + pred_rows + ) + emit_table(("Successors", "Count:", "Percentage:"), + succ_rows + ) def main(): stats = gather_stats() From webhook-mailer at python.org Fri Mar 18 06:17:21 2022 From: webhook-mailer at python.org (vstinner) Date: Fri, 18 Mar 2022 10:17:21 -0000 Subject: [Python-checkins] bpo-45786: Remove _PyFrame_Fini() and _PyFrame_DebugMallocStats() (GH-31874) Message-ID: https://github.com/python/cpython/commit/2217462bda1865a047d358306088682ee6a091ed commit: 2217462bda1865a047d358306088682ee6a091ed branch: main author: Victor Stinner committer: vstinner date: 2022-03-18T11:16:55+01:00 summary: bpo-45786: Remove _PyFrame_Fini() and _PyFrame_DebugMallocStats() (GH-31874) Remove private empty _PyFrame_Fini() and _PyFrame_DebugMallocStats() functions. files: M Include/cpython/frameobject.h M Include/internal/pycore_frame.h M Objects/frameobject.c M Objects/object.c M Python/pylifecycle.c diff --git a/Include/cpython/frameobject.h b/Include/cpython/frameobject.h index ebaecbed1b487..9b697fb3cbaf5 100644 --- a/Include/cpython/frameobject.h +++ b/Include/cpython/frameobject.h @@ -22,6 +22,4 @@ PyAPI_FUNC(void) PyFrame_LocalsToFast(PyFrameObject *, int); PyAPI_FUNC(int) PyFrame_FastToLocalsWithError(PyFrameObject *f); PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *); -PyAPI_FUNC(void) _PyFrame_DebugMallocStats(FILE *out); - PyAPI_FUNC(PyFrameObject *) PyFrame_GetBack(PyFrameObject *frame); diff --git a/Include/internal/pycore_frame.h b/Include/internal/pycore_frame.h index 207983dcc22d7..e2f551ef2c062 100644 --- a/Include/internal/pycore_frame.h +++ b/Include/internal/pycore_frame.h @@ -21,10 +21,6 @@ struct _frame { extern PyFrameObject* _PyFrame_New_NoTrack(PyCodeObject *code); -/* runtime lifecycle */ - -extern void _PyFrame_Fini(PyInterpreterState *interp); - /* other API */ diff --git a/Objects/frameobject.c b/Objects/frameobject.c index eb7fdb30cd75e..73b6c3d9f8ab7 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -1034,17 +1034,6 @@ PyFrame_LocalsToFast(PyFrameObject *f, int clear) _PyFrame_LocalsToFast(f->f_frame, clear); } -void -_PyFrame_Fini(PyInterpreterState *interp) -{ -} - -/* Print summary info about the state of the optimized allocator */ -void -_PyFrame_DebugMallocStats(FILE *out) -{ -} - PyCodeObject * PyFrame_GetCode(PyFrameObject *frame) diff --git a/Objects/object.c b/Objects/object.c index f029a72dd3145..33dab5ecbf205 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2118,7 +2118,6 @@ _PyObject_DebugTypeStats(FILE *out) { _PyDict_DebugMallocStats(out); _PyFloat_DebugMallocStats(out); - _PyFrame_DebugMallocStats(out); _PyList_DebugMallocStats(out); _PyTuple_DebugMallocStats(out); } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 8abd536f5534d..0754c1ac3bf40 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -9,7 +9,6 @@ #include "pycore_dict.h" // _PyDict_Fini() #include "pycore_fileutils.h" // _Py_ResetForceASCII() #include "pycore_floatobject.h" // _PyFloat_InitTypes() -#include "pycore_frame.h" // _PyFrame_Fini() #include "pycore_genobject.h" // _PyAsyncGen_Fini() #include "pycore_import.h" // _PyImport_BootstrapImp() #include "pycore_initconfig.h" // _PyStatus_OK() @@ -1667,7 +1666,6 @@ finalize_interp_types(PyInterpreterState *interp) _PyUnicode_FiniTypes(interp); _PySys_Fini(interp); _PyExc_Fini(interp); - _PyFrame_Fini(interp); _PyAsyncGen_Fini(interp); _PyContext_Fini(interp); _PyFloat_FiniType(interp); From webhook-mailer at python.org Fri Mar 18 07:27:30 2022 From: webhook-mailer at python.org (zooba) Date: Fri, 18 Mar 2022 11:27:30 -0000 Subject: [Python-checkins] bpo-47037: Don't test for strftime('%4Y') on Windows (GH-31945) Message-ID: https://github.com/python/cpython/commit/d190a9351be577a534a84fd1899f02a9f50f7276 commit: d190a9351be577a534a84fd1899f02a9f50f7276 branch: main author: Christian Heimes committer: zooba date: 2022-03-18T11:27:20Z summary: bpo-47037: Don't test for strftime('%4Y') on Windows (GH-31945) files: A Misc/NEWS.d/next/Tests/2022-03-16-21-29-30.bpo-47037.xcrLpJ.rst M Lib/test/support/__init__.py diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 01bb57ec44f0c..fc1b86bebcd1a 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -521,10 +521,13 @@ def requires_subprocess(): return unittest.skipUnless(has_subprocess_support, "requires subprocess support") # Does strftime() support glibc extension like '%4Y'? -try: - has_strftime_extensions = time.strftime("%4Y") != "%4Y" -except ValueError: - has_strftime_extensions = False +has_strftime_extensions = False +if sys.platform != "win32": + # bpo-47037: Windows debug builds crash with "Debug Assertion Failed" + try: + has_strftime_extensions = time.strftime("%4Y") != "%4Y" + except ValueError: + pass # Define the URL of a dedicated HTTP server for the network tests. # The URL must use clear-text HTTP: no redirection to encrypted HTTPS. diff --git a/Misc/NEWS.d/next/Tests/2022-03-16-21-29-30.bpo-47037.xcrLpJ.rst b/Misc/NEWS.d/next/Tests/2022-03-16-21-29-30.bpo-47037.xcrLpJ.rst new file mode 100644 index 0000000000000..f4f28d1e9a012 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2022-03-16-21-29-30.bpo-47037.xcrLpJ.rst @@ -0,0 +1,2 @@ +Skip ``strftime("%4Y")`` feature test on Windows. It can cause an assertion +error in debug builds. From webhook-mailer at python.org Fri Mar 18 08:03:29 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 18 Mar 2022 12:03:29 -0000 Subject: [Python-checkins] bpo-46968: Check for 'sys/auxv.h' in the configure script (GH-31961) Message-ID: https://github.com/python/cpython/commit/8e3fde728f547f1d32bde8adf62b4c50bb877b9d commit: 8e3fde728f547f1d32bde8adf62b4c50bb877b9d branch: main author: Pablo Galindo Salgado committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-18T05:03:22-07:00 summary: bpo-46968: Check for 'sys/auxv.h' in the configure script (GH-31961) files: A Misc/NEWS.d/next/Core and Builtins/2022-03-17-14-22-23.bpo-46968.4gz4NA.rst M Modules/faulthandler.c M configure M configure.ac M pyconfig.h.in diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-17-14-22-23.bpo-46968.4gz4NA.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-17-14-22-23.bpo-46968.4gz4NA.rst new file mode 100644 index 0000000000000..bef1d0532b098 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-17-14-22-23.bpo-46968.4gz4NA.rst @@ -0,0 +1,3 @@ +Check for the existence of the "sys/auxv.h" header in :mod:`faulthandler` to +avoid compilation problems in systems where this header doesn't exist. Patch +by Pablo Galindo diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index 744698cd7aba2..91f96665a4a30 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -26,9 +26,9 @@ # define FAULTHANDLER_USE_ALT_STACK #endif -#if defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_LINUX_AUXVEC_H) -# include -# include +#if defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_LINUX_AUXVEC_H) && defined(HAVE_SYS_AUXV_H) +# include // AT_MINSIGSTKSZ +# include // getauxval() #endif /* Allocate at maximum 100 MiB of the stack to raise the stack overflow */ diff --git a/configure b/configure index 4d585eba626a6..5fa6efaab4fb7 100755 --- a/configure +++ b/configure @@ -8652,7 +8652,7 @@ $as_echo "#define STDC_HEADERS 1" >>confdefs.h # checks for header files for ac_header in \ alloca.h asm/types.h bluetooth.h conio.h crypt.h direct.h dlfcn.h endian.h errno.h fcntl.h grp.h \ - ieeefp.h io.h langinfo.h libintl.h libutil.h linux/auxvec.h linux/memfd.h linux/random.h linux/soundcard.h \ + ieeefp.h io.h langinfo.h libintl.h libutil.h linux/auxvec.h sys/auxv.h linux/memfd.h linux/random.h linux/soundcard.h \ linux/tipc.h linux/wait.h netinet/in.h netpacket/packet.h poll.h process.h pthread.h pty.h \ sched.h setjmp.h shadow.h signal.h spawn.h stropts.h sys/audioio.h sys/bsdtty.h sys/devpoll.h \ sys/endian.h sys/epoll.h sys/event.h sys/eventfd.h sys/file.h sys/ioctl.h sys/kern_control.h \ diff --git a/configure.ac b/configure.ac index 81262ae38e534..7a37ad279d0fc 100644 --- a/configure.ac +++ b/configure.ac @@ -2375,7 +2375,7 @@ AC_DEFINE(STDC_HEADERS, 1, [Define to 1 if you have the ANSI C header files.]) # checks for header files AC_CHECK_HEADERS([ \ alloca.h asm/types.h bluetooth.h conio.h crypt.h direct.h dlfcn.h endian.h errno.h fcntl.h grp.h \ - ieeefp.h io.h langinfo.h libintl.h libutil.h linux/auxvec.h linux/memfd.h linux/random.h linux/soundcard.h \ + ieeefp.h io.h langinfo.h libintl.h libutil.h linux/auxvec.h sys/auxv.h linux/memfd.h linux/random.h linux/soundcard.h \ linux/tipc.h linux/wait.h netinet/in.h netpacket/packet.h poll.h process.h pthread.h pty.h \ sched.h setjmp.h shadow.h signal.h spawn.h stropts.h sys/audioio.h sys/bsdtty.h sys/devpoll.h \ sys/endian.h sys/epoll.h sys/event.h sys/eventfd.h sys/file.h sys/ioctl.h sys/kern_control.h \ diff --git a/pyconfig.h.in b/pyconfig.h.in index 1b84ee108fbfc..40952883853e3 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -1188,6 +1188,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_AUDIOIO_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_AUXV_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_BSDTTY_H From webhook-mailer at python.org Fri Mar 18 08:45:02 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 18 Mar 2022 12:45:02 -0000 Subject: [Python-checkins] bpo-45979: Fix Tkinter tests with old Tk (>= 8.5.12) (GH-31938) Message-ID: https://github.com/python/cpython/commit/d27af88c1bcf3c6c185f81218b7bf86b38128ea9 commit: d27af88c1bcf3c6c185f81218b7bf86b38128ea9 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-18T05:44:54-07:00 summary: bpo-45979: Fix Tkinter tests with old Tk (>= 8.5.12) (GH-31938) (cherry picked from commit dbbe4d2d0075fa0e95b069fb4780d79aae3514c7) Co-authored-by: Serhiy Storchaka files: M Lib/tkinter/test/test_tkinter/test_widgets.py M Lib/tkinter/test/test_ttk/test_style.py diff --git a/Lib/tkinter/test/test_tkinter/test_widgets.py b/Lib/tkinter/test/test_tkinter/test_widgets.py index cc227e579679b..c0b92bf3b1921 100644 --- a/Lib/tkinter/test/test_tkinter/test_widgets.py +++ b/Lib/tkinter/test/test_tkinter/test_widgets.py @@ -800,7 +800,7 @@ def test_configure_activestyle(self): self.checkEnumParam(widget, 'activestyle', 'dotbox', 'none', 'underline') - test_justify = requires_tcl(8, 6, 5)(StandardOptionsTests.test_configure_justify) + test_configure_justify = requires_tcl(8, 6, 5)(StandardOptionsTests.test_configure_justify) def test_configure_listvariable(self): widget = self.create() @@ -939,7 +939,7 @@ def test_configure_digits(self): def test_configure_from(self): widget = self.create() - conv = False if get_tk_patchlevel() >= (8, 6, 10) else float_round + conv = float if get_tk_patchlevel() >= (8, 6, 10) else float_round self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=conv) def test_configure_label(self): diff --git a/Lib/tkinter/test/test_ttk/test_style.py b/Lib/tkinter/test/test_ttk/test_style.py index a33c24ac55bee..54ad3437168fe 100644 --- a/Lib/tkinter/test/test_ttk/test_style.py +++ b/Lib/tkinter/test/test_ttk/test_style.py @@ -4,7 +4,7 @@ from tkinter import ttk from test import support from test.support import requires -from tkinter.test.support import AbstractTkTest +from tkinter.test.support import AbstractTkTest, get_tk_patchlevel requires('gui') @@ -170,6 +170,8 @@ def test_map_custom_copy(self): newname = f'C.{name}' self.assertEqual(style.map(newname), {}) style.map(newname, **default) + if theme == 'alt' and name == '.' and get_tk_patchlevel() < (8, 6, 1): + default['embossed'] = [('disabled', '1')] self.assertEqual(style.map(newname), default) for key, value in default.items(): self.assertEqual(style.map(newname, key), value) From webhook-mailer at python.org Fri Mar 18 09:33:12 2022 From: webhook-mailer at python.org (pablogsal) Date: Fri, 18 Mar 2022 13:33:12 -0000 Subject: [Python-checkins] [3.9] bpo-46968: Check for 'sys/auxv.h' in the configure script (GH-31961). (GH-31975) Message-ID: https://github.com/python/cpython/commit/a12ef81231d65da5efbef4fa1434716270a19af6 commit: a12ef81231d65da5efbef4fa1434716270a19af6 branch: 3.9 author: Pablo Galindo Salgado committer: pablogsal date: 2022-03-18T13:33:03Z summary: [3.9] bpo-46968: Check for 'sys/auxv.h' in the configure script (GH-31961). (GH-31975) (cherry picked from commit 8e3fde728f547f1d32bde8adf62b4c50bb877b9d) Co-authored-by: Pablo Galindo Salgado files: A Misc/NEWS.d/next/Core and Builtins/2022-03-17-14-22-23.bpo-46968.4gz4NA.rst M Modules/faulthandler.c M configure M configure.ac M pyconfig.h.in diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-17-14-22-23.bpo-46968.4gz4NA.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-17-14-22-23.bpo-46968.4gz4NA.rst new file mode 100644 index 0000000000000..bef1d0532b098 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-17-14-22-23.bpo-46968.4gz4NA.rst @@ -0,0 +1,3 @@ +Check for the existence of the "sys/auxv.h" header in :mod:`faulthandler` to +avoid compilation problems in systems where this header doesn't exist. Patch +by Pablo Galindo diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index 764ff439d77d9..16f98ace3bb05 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -21,9 +21,9 @@ # define FAULTHANDLER_USE_ALT_STACK #endif -#if defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_LINUX_AUXVEC_H) -# include -# include +#if defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_LINUX_AUXVEC_H) && defined(HAVE_SYS_AUXV_H) +# include // AT_MINSIGSTKSZ +# include // getauxval() #endif /* Allocate at maximum 100 MiB of the stack to raise the stack overflow */ diff --git a/configure b/configure index 7f9749091dc01..b7be60eaa37dd 100755 --- a/configure +++ b/configure @@ -8042,7 +8042,7 @@ sys/stat.h sys/syscall.h sys/sys_domain.h sys/termio.h sys/time.h \ sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \ libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \ linux/tipc.h linux/random.h spawn.h util.h alloca.h endian.h \ -sys/endian.h sys/sysmacros.h linux/auxvec.h linux/memfd.h linux/wait.h sys/memfd.h sys/mman.h +sys/endian.h sys/sysmacros.h linux/auxvec.h sys/auxv.h linux/memfd.h linux/wait.h sys/memfd.h sys/mman.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" diff --git a/configure.ac b/configure.ac index 1354cc0a8dd68..aa515da46553a 100644 --- a/configure.ac +++ b/configure.ac @@ -2228,7 +2228,7 @@ sys/stat.h sys/syscall.h sys/sys_domain.h sys/termio.h sys/time.h \ sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \ libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \ linux/tipc.h linux/random.h spawn.h util.h alloca.h endian.h \ -sys/endian.h sys/sysmacros.h linux/auxvec.h linux/memfd.h linux/wait.h sys/memfd.h sys/mman.h) +sys/endian.h sys/sysmacros.h linux/auxvec.h sys/auxv.h linux/memfd.h linux/wait.h sys/memfd.h sys/mman.h) AC_HEADER_DIRENT AC_HEADER_MAJOR diff --git a/pyconfig.h.in b/pyconfig.h.in index ce850fcad8280..bf695e9e58200 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -1113,6 +1113,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_AUDIOIO_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_AUXV_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_BSDTTY_H From webhook-mailer at python.org Fri Mar 18 09:33:15 2022 From: webhook-mailer at python.org (pablogsal) Date: Fri, 18 Mar 2022 13:33:15 -0000 Subject: [Python-checkins] [3.10] bpo-46968: Check for 'sys/auxv.h' in the configure script (GH-31961). (GH-31974) Message-ID: https://github.com/python/cpython/commit/6fd9737373f2bed03f409440b4fd50b9f8f121cb commit: 6fd9737373f2bed03f409440b4fd50b9f8f121cb branch: 3.10 author: Pablo Galindo Salgado committer: pablogsal date: 2022-03-18T13:33:11Z summary: [3.10] bpo-46968: Check for 'sys/auxv.h' in the configure script (GH-31961). (GH-31974) (cherry picked from commit 8e3fde728f547f1d32bde8adf62b4c50bb877b9d) Co-authored-by: Pablo Galindo Salgado files: A Misc/NEWS.d/next/Core and Builtins/2022-03-17-14-22-23.bpo-46968.4gz4NA.rst M Modules/faulthandler.c M configure M configure.ac M pyconfig.h.in diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-17-14-22-23.bpo-46968.4gz4NA.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-17-14-22-23.bpo-46968.4gz4NA.rst new file mode 100644 index 0000000000000..bef1d0532b098 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-17-14-22-23.bpo-46968.4gz4NA.rst @@ -0,0 +1,3 @@ +Check for the existence of the "sys/auxv.h" header in :mod:`faulthandler` to +avoid compilation problems in systems where this header doesn't exist. Patch +by Pablo Galindo diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index 88a5b9376aa7d..4af8702068b14 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -23,9 +23,9 @@ # define FAULTHANDLER_USE_ALT_STACK #endif -#if defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_LINUX_AUXVEC_H) -# include -# include +#if defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_LINUX_AUXVEC_H) && defined(HAVE_SYS_AUXV_H) +# include // AT_MINSIGSTKSZ +# include // getauxval() #endif /* Allocate at maximum 100 MiB of the stack to raise the stack overflow */ diff --git a/configure b/configure index 0cc86f9ed7687..19f1bd59ba8b1 100755 --- a/configure +++ b/configure @@ -8101,7 +8101,7 @@ sys/stat.h sys/syscall.h sys/sys_domain.h sys/termio.h sys/time.h \ sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \ libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \ linux/tipc.h linux/random.h spawn.h util.h alloca.h endian.h \ -sys/endian.h sys/sysmacros.h linux/auxvec.h linux/memfd.h linux/wait.h sys/memfd.h \ +sys/endian.h sys/sysmacros.h linux/auxvec.h sys/auxv.h linux/memfd.h linux/wait.h sys/memfd.h \ sys/mman.h sys/eventfd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` diff --git a/configure.ac b/configure.ac index 547255ff31ebc..763fc697be7bc 100644 --- a/configure.ac +++ b/configure.ac @@ -2225,7 +2225,7 @@ sys/stat.h sys/syscall.h sys/sys_domain.h sys/termio.h sys/time.h \ sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \ libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \ linux/tipc.h linux/random.h spawn.h util.h alloca.h endian.h \ -sys/endian.h sys/sysmacros.h linux/auxvec.h linux/memfd.h linux/wait.h sys/memfd.h \ +sys/endian.h sys/sysmacros.h linux/auxvec.h sys/auxv.h linux/memfd.h linux/wait.h sys/memfd.h \ sys/mman.h sys/eventfd.h) AC_HEADER_DIRENT AC_HEADER_MAJOR diff --git a/pyconfig.h.in b/pyconfig.h.in index b0948e9b9b79d..57c84e5f8fac0 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -1128,6 +1128,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_AUDIOIO_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_AUXV_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_BSDTTY_H From webhook-mailer at python.org Fri Mar 18 09:49:07 2022 From: webhook-mailer at python.org (JulienPalard) Date: Fri, 18 Mar 2022 13:49:07 -0000 Subject: [Python-checkins] [doc] Some more make suspicious false positives. (GH-31977) Message-ID: https://github.com/python/cpython/commit/f1683173aabb0ff22e378d36981af6a72a24d6a1 commit: f1683173aabb0ff22e378d36981af6a72a24d6a1 branch: main author: Julien Palard committer: JulienPalard date: 2022-03-18T14:48:58+01:00 summary: [doc] Some more make suspicious false positives. (GH-31977) files: M Doc/tools/susp-ignored.csv diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv index 12d670d3607e6..43a36042059f7 100644 --- a/Doc/tools/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -390,3 +390,5 @@ reference/compound_stmts,324,:keyword,:keyword:`continue` and :keyword:`return` reference/compound_stmts,324,`,:keyword:`continue` and :keyword:`return` cannot appear in an except* whatsnew/changelog,,:CON,": os.path.abspath(?C:CON?) is now fixed to return ?\.CON?, not" whatsnew/changelog,,::,Lib/email/mime/nonmultipart.py::MIMENonMultipart +library/typing,,`,"assert_type(name, str) # OK, inferred type of `name` is `str`" +library/typing,,`,# after which we hope the inferred type will be `int` From webhook-mailer at python.org Fri Mar 18 11:02:54 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Fri, 18 Mar 2022 15:02:54 -0000 Subject: [Python-checkins] [3.9] bpo-14156: Make argparse.FileType work correctly for binary file modes when argument is '-' (GH-13165) (GH-31979) Message-ID: https://github.com/python/cpython/commit/4d2099f455229b10f88846dbe9fe6debbee55356 commit: 4d2099f455229b10f88846dbe9fe6debbee55356 branch: 3.9 author: Serhiy Storchaka committer: serhiy-storchaka date: 2022-03-18T17:02:44+02:00 summary: [3.9] bpo-14156: Make argparse.FileType work correctly for binary file modes when argument is '-' (GH-13165) (GH-31979) Also made modes containing 'a' or 'x' act the same as a mode containing 'w' when argument is '-' (so 'a'/'x' return sys.stdout like 'w', and 'ab'/'xb' return sys.stdout.buffer like 'wb'). (cherry picked from commit eafec26ae5327bb23b6dace2650b074c3327dfa0) Co-authored-by: MojoVampire files: A Misc/NEWS.d/next/Library/2019-05-07-14-25-45.bpo-14156.0FaHXE.rst M Lib/argparse.py M Lib/test/test_argparse.py diff --git a/Lib/argparse.py b/Lib/argparse.py index fbdfd5172fb35..c46bb302711fc 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -726,7 +726,7 @@ def _get_action_name(argument): if argument is None: return None elif argument.option_strings: - return '/'.join(argument.option_strings) + return '/'.join(argument.option_strings) elif argument.metavar not in (None, SUPPRESS): return argument.metavar elif argument.dest not in (None, SUPPRESS): @@ -1256,9 +1256,9 @@ def __call__(self, string): # the special argument "-" means sys.std{in,out} if string == '-': if 'r' in self._mode: - return _sys.stdin - elif 'w' in self._mode: - return _sys.stdout + return _sys.stdin.buffer if 'b' in self._mode else _sys.stdin + elif any(c in self._mode for c in 'wax'): + return _sys.stdout.buffer if 'b' in self._mode else _sys.stdout else: msg = _('argument "-" with mode %r') % self._mode raise ValueError(msg) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 5c86583ce10a4..dcc392faf2310 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -1,6 +1,8 @@ # Author: Steven J. Bethard . import inspect +import io +import operator import os import shutil import stat @@ -10,12 +12,27 @@ import unittest import argparse -from io import StringIO - from test import support from unittest import mock -class StdIOBuffer(StringIO): - pass + + +class StdIOBuffer(io.TextIOWrapper): + '''Replacement for writable io.StringIO that behaves more like real file + + Unlike StringIO, provides a buffer attribute that holds the underlying + binary data, allowing it to replace sys.stdout/sys.stderr in more + contexts. + ''' + + def __init__(self, initial_value='', newline='\n'): + initial_value = initial_value.encode('utf-8') + super().__init__(io.BufferedWriter(io.BytesIO(initial_value)), + 'utf-8', newline=newline) + + def getvalue(self): + self.flush() + return self.buffer.raw.getvalue().decode('utf-8') + class TestCase(unittest.TestCase): @@ -42,11 +59,14 @@ def tearDown(self): os.chmod(os.path.join(self.temp_dir, name), stat.S_IWRITE) shutil.rmtree(self.temp_dir, True) - def create_readonly_file(self, filename): + def create_writable_file(self, filename): file_path = os.path.join(self.temp_dir, filename) with open(file_path, 'w') as file: file.write(filename) - os.chmod(file_path, stat.S_IREAD) + return file_path + + def create_readonly_file(self, filename): + os.chmod(self.create_writable_file(filename), stat.S_IREAD) class Sig(object): @@ -96,10 +116,15 @@ def stderr_to_parser_error(parse_args, *args, **kwargs): try: result = parse_args(*args, **kwargs) for key in list(vars(result)): - if getattr(result, key) is sys.stdout: + attr = getattr(result, key) + if attr is sys.stdout: setattr(result, key, old_stdout) - if getattr(result, key) is sys.stderr: + elif attr is sys.stdout.buffer: + setattr(result, key, getattr(old_stdout, 'buffer', BIN_STDOUT_SENTINEL)) + elif attr is sys.stderr: setattr(result, key, old_stderr) + elif attr is sys.stderr.buffer: + setattr(result, key, getattr(old_stderr, 'buffer', BIN_STDERR_SENTINEL)) return result except SystemExit as e: code = e.code @@ -1545,16 +1570,40 @@ def test_r_1_replace(self): type = argparse.FileType('r', 1, errors='replace') self.assertEqual("FileType('r', 1, errors='replace')", repr(type)) + +BIN_STDOUT_SENTINEL = object() +BIN_STDERR_SENTINEL = object() + + class StdStreamComparer: def __init__(self, attr): - self.attr = attr + # We try to use the actual stdXXX.buffer attribute as our + # marker, but but under some test environments, + # sys.stdout/err are replaced by io.StringIO which won't have .buffer, + # so we use a sentinel simply to show that the tests do the right thing + # for any buffer supporting object + self.getattr = operator.attrgetter(attr) + if attr == 'stdout.buffer': + self.backupattr = BIN_STDOUT_SENTINEL + elif attr == 'stderr.buffer': + self.backupattr = BIN_STDERR_SENTINEL + else: + self.backupattr = object() # Not equal to anything def __eq__(self, other): - return other == getattr(sys, self.attr) + try: + return other == self.getattr(sys) + except AttributeError: + return other == self.backupattr + eq_stdin = StdStreamComparer('stdin') eq_stdout = StdStreamComparer('stdout') eq_stderr = StdStreamComparer('stderr') +eq_bstdin = StdStreamComparer('stdin.buffer') +eq_bstdout = StdStreamComparer('stdout.buffer') +eq_bstderr = StdStreamComparer('stderr.buffer') + class RFile(object): seen = {} @@ -1631,7 +1680,7 @@ def setUp(self): ('foo', NS(x=None, spam=RFile('foo'))), ('-x foo bar', NS(x=RFile('foo'), spam=RFile('bar'))), ('bar -x foo', NS(x=RFile('foo'), spam=RFile('bar'))), - ('-x - -', NS(x=eq_stdin, spam=eq_stdin)), + ('-x - -', NS(x=eq_bstdin, spam=eq_bstdin)), ] @@ -1658,8 +1707,9 @@ class TestFileTypeW(TempDirMixin, ParserTestCase): """Test the FileType option/argument type for writing files""" def setUp(self): - super(TestFileTypeW, self).setUp() + super().setUp() self.create_readonly_file('readonly') + self.create_writable_file('writable') argument_signatures = [ Sig('-x', type=argparse.FileType('w')), @@ -1668,13 +1718,37 @@ def setUp(self): failures = ['-x', '', 'readonly'] successes = [ ('foo', NS(x=None, spam=WFile('foo'))), + ('writable', NS(x=None, spam=WFile('writable'))), ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))), ('bar -x foo', NS(x=WFile('foo'), spam=WFile('bar'))), ('-x - -', NS(x=eq_stdout, spam=eq_stdout)), ] + at unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0, + "non-root user required") +class TestFileTypeX(TempDirMixin, ParserTestCase): + """Test the FileType option/argument type for writing new files only""" + + def setUp(self): + super().setUp() + self.create_readonly_file('readonly') + self.create_writable_file('writable') + + argument_signatures = [ + Sig('-x', type=argparse.FileType('x')), + Sig('spam', type=argparse.FileType('x')), + ] + failures = ['-x', '', 'readonly', 'writable'] + successes = [ + ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))), + ('-x - -', NS(x=eq_stdout, spam=eq_stdout)), + ] + + at unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0, + "non-root user required") class TestFileTypeWB(TempDirMixin, ParserTestCase): + """Test the FileType option/argument type for writing binary files""" argument_signatures = [ Sig('-x', type=argparse.FileType('wb')), @@ -1685,7 +1759,22 @@ class TestFileTypeWB(TempDirMixin, ParserTestCase): ('foo', NS(x=None, spam=WFile('foo'))), ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))), ('bar -x foo', NS(x=WFile('foo'), spam=WFile('bar'))), - ('-x - -', NS(x=eq_stdout, spam=eq_stdout)), + ('-x - -', NS(x=eq_bstdout, spam=eq_bstdout)), + ] + + + at unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0, + "non-root user required") +class TestFileTypeXB(TestFileTypeX): + "Test the FileType option/argument type for writing new binary files only" + + argument_signatures = [ + Sig('-x', type=argparse.FileType('xb')), + Sig('spam', type=argparse.FileType('xb')), + ] + successes = [ + ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))), + ('-x - -', NS(x=eq_bstdout, spam=eq_bstdout)), ] diff --git a/Misc/NEWS.d/next/Library/2019-05-07-14-25-45.bpo-14156.0FaHXE.rst b/Misc/NEWS.d/next/Library/2019-05-07-14-25-45.bpo-14156.0FaHXE.rst new file mode 100644 index 0000000000000..7bfc917a2a750 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-07-14-25-45.bpo-14156.0FaHXE.rst @@ -0,0 +1,4 @@ +argparse.FileType now supports an argument of '-' in binary mode, returning +the .buffer attribute of sys.stdin/sys.stdout as appropriate. Modes +including 'x' and 'a' are treated equivalently to 'w' when argument is '-'. +Patch contributed by Josh Rosenberg From webhook-mailer at python.org Fri Mar 18 13:19:42 2022 From: webhook-mailer at python.org (zooba) Date: Fri, 18 Mar 2022 17:19:42 -0000 Subject: [Python-checkins] bpo-47037: Test debug builds on Windows in CI so that native assertions are noticed sooner (GH-31965) Message-ID: https://github.com/python/cpython/commit/d0a91bd277d1122b41d59e8022b596e3b3ae24fe commit: d0a91bd277d1122b41d59e8022b596e3b3ae24fe branch: main author: Steve Dower committer: zooba date: 2022-03-18T17:19:28Z summary: bpo-47037: Test debug builds on Windows in CI so that native assertions are noticed sooner (GH-31965) files: M .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b950c594709ec..bda6dde37d185 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -113,12 +113,12 @@ jobs: steps: - uses: actions/checkout at v2 - name: Build CPython - run: .\PCbuild\build.bat -e -p Win32 + run: .\PCbuild\build.bat -e -d -p Win32 timeout-minutes: 30 - name: Display build info run: .\python.bat -m test.pythoninfo - name: Tests - run: .\PCbuild\rt.bat -p Win32 -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 + run: .\PCbuild\rt.bat -p Win32 -d -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 build_win_amd64: name: 'Windows (x64)' @@ -132,12 +132,12 @@ jobs: - name: Register MSVC problem matcher run: echo "::add-matcher::.github/problem-matchers/msvc.json" - name: Build CPython - run: .\PCbuild\build.bat -e -p x64 + run: .\PCbuild\build.bat -e -d -p x64 timeout-minutes: 30 - name: Display build info run: .\python.bat -m test.pythoninfo - name: Tests - run: .\PCbuild\rt.bat -p x64 -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 + run: .\PCbuild\rt.bat -p x64 -d -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 build_macos: name: 'macOS' From webhook-mailer at python.org Fri Mar 18 13:56:49 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Fri, 18 Mar 2022 17:56:49 -0000 Subject: [Python-checkins] bpo-43224: Add TypeVarTuple.__name__ (GH-31954) Message-ID: https://github.com/python/cpython/commit/3a2b89580ded72262fbea0f7ad24096a90c42b9c commit: 3a2b89580ded72262fbea0f7ad24096a90c42b9c branch: main author: Jelle Zijlstra committer: JelleZijlstra date: 2022-03-18T10:56:36-07:00 summary: bpo-43224: Add TypeVarTuple.__name__ (GH-31954) I noticed that TypeVar and ParamSpec put their name in a __name__ attribute, but TypeVarTuple doesn't. Let's be consistent. files: M Lib/test/test_typing.py M Lib/typing.py diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index bcffdc882dbe6..0e28655296d14 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -415,6 +415,12 @@ def assertEndsWith(self, string, tail): if not string.endswith(tail): self.fail(f"String {string!r} does not end with {tail!r}") + def test_name(self): + Ts = TypeVarTuple('Ts') + self.assertEqual(Ts.__name__, 'Ts') + Ts2 = TypeVarTuple('Ts2') + self.assertEqual(Ts2.__name__, 'Ts2') + def test_instance_is_equal_to_itself(self): Ts = TypeVarTuple('Ts') self.assertEqual(Ts, Ts) @@ -509,15 +515,6 @@ def test_repr_is_correct(self): self.assertEqual(repr(Unpack[tuple[Unpack[Ts]]]), '*tuple[*Ts]') self.assertEqual(repr(Unpack[Tuple[Unpack[Ts]]]), '*typing.Tuple[*Ts]') - def test_repr_is_correct(self): - Ts = TypeVarTuple('Ts') - self.assertEqual(repr(Ts), 'Ts') - self.assertEqual(repr(Unpack[Ts]), '*Ts') - self.assertEqual(repr(tuple[Unpack[Ts]]), 'tuple[*Ts]') - self.assertEqual(repr(Tuple[Unpack[Ts]]), 'typing.Tuple[*Ts]') - self.assertEqual(repr(Unpack[tuple[Unpack[Ts]]]), '*tuple[*Ts]') - self.assertEqual(repr(Unpack[Tuple[Unpack[Ts]]]), '*typing.Tuple[*Ts]') - def test_variadic_class_repr_is_correct(self): Ts = TypeVarTuple('Ts') class A(Generic[Unpack[Ts]]): pass diff --git a/Lib/typing.py b/Lib/typing.py index e8613625c3044..f0e84900d7f80 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -939,13 +939,13 @@ class C(Generic[*Ts]): ... """ def __init__(self, name): - self._name = name + self.__name__ = name def __iter__(self): yield Unpack[self] def __repr__(self): - return self._name + return self.__name__ def __typing_subst__(self, arg): raise AssertionError From webhook-mailer at python.org Fri Mar 18 14:46:49 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Fri, 18 Mar 2022 18:46:49 -0000 Subject: [Python-checkins] [3.10] bpo-40296: Fix supporting generic aliases in pydoc (GH-30253). (GH-31976) Message-ID: https://github.com/python/cpython/commit/a5b7678a67ac99edd50822827b772e7d9afc8e64 commit: a5b7678a67ac99edd50822827b772e7d9afc8e64 branch: 3.10 author: Serhiy Storchaka committer: serhiy-storchaka date: 2022-03-18T20:46:31+02:00 summary: [3.10] bpo-40296: Fix supporting generic aliases in pydoc (GH-30253). (GH-31976) (cherry picked from commit cd44afc573e2e2de8d7e5a9119c347373066cd10) files: A Misc/NEWS.d/next/Library/2021-12-25-14-13-14.bpo-40296.p0YVGB.rst M Lib/pydoc.py M Lib/test/pydoc_mod.py M Lib/test/test_pydoc.py diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 4a8c10a379ed8..e00ba4191c410 100755 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -69,6 +69,7 @@ class or function within a module or module in a package. If the import sysconfig import time import tokenize +import types import urllib.parse import warnings from collections import deque @@ -90,13 +91,16 @@ def pathdirs(): normdirs.append(normdir) return dirs +def _isclass(object): + return inspect.isclass(object) and not isinstance(object, types.GenericAlias) + def _findclass(func): cls = sys.modules.get(func.__module__) if cls is None: return None for name in func.__qualname__.split('.')[:-1]: cls = getattr(cls, name) - if not inspect.isclass(cls): + if not _isclass(cls): return None return cls @@ -104,7 +108,7 @@ def _finddoc(obj): if inspect.ismethod(obj): name = obj.__func__.__name__ self = obj.__self__ - if (inspect.isclass(self) and + if (_isclass(self) and getattr(getattr(self, name, None), '__func__') is obj.__func__): # classmethod cls = self @@ -118,7 +122,7 @@ def _finddoc(obj): elif inspect.isbuiltin(obj): name = obj.__name__ self = obj.__self__ - if (inspect.isclass(self) and + if (_isclass(self) and self.__qualname__ + '.' + name == obj.__qualname__): # classmethod cls = self @@ -205,7 +209,7 @@ def classname(object, modname): def isdata(object): """Check if an object is of a type that probably means it's data.""" - return not (inspect.ismodule(object) or inspect.isclass(object) or + return not (inspect.ismodule(object) or _isclass(object) or inspect.isroutine(object) or inspect.isframe(object) or inspect.istraceback(object) or inspect.iscode(object)) @@ -470,7 +474,7 @@ def document(self, object, name=None, *args): # by lacking a __name__ attribute) and an instance. try: if inspect.ismodule(object): return self.docmodule(*args) - if inspect.isclass(object): return self.docclass(*args) + if _isclass(object): return self.docclass(*args) if inspect.isroutine(object): return self.docroutine(*args) except AttributeError: pass @@ -775,7 +779,7 @@ def docmodule(self, object, name=None, mod=None, *ignored): modules = inspect.getmembers(object, inspect.ismodule) classes, cdict = [], {} - for key, value in inspect.getmembers(object, inspect.isclass): + for key, value in inspect.getmembers(object, _isclass): # if __all__ exists, believe it. Otherwise use old heuristic. if (all is not None or (inspect.getmodule(value) or object) is object): @@ -1217,7 +1221,7 @@ def docmodule(self, object, name=None, mod=None): result = result + self.section('DESCRIPTION', desc) classes = [] - for key, value in inspect.getmembers(object, inspect.isclass): + for key, value in inspect.getmembers(object, _isclass): # if __all__ exists, believe it. Otherwise use old heuristic. if (all is not None or (inspect.getmodule(value) or object) is object): @@ -1699,7 +1703,7 @@ def describe(thing): return 'member descriptor %s.%s.%s' % ( thing.__objclass__.__module__, thing.__objclass__.__name__, thing.__name__) - if inspect.isclass(thing): + if _isclass(thing): return 'class ' + thing.__name__ if inspect.isfunction(thing): return 'function ' + thing.__name__ @@ -1760,7 +1764,7 @@ def render_doc(thing, title='Python Library Documentation: %s', forceload=0, desc += ' in module ' + module.__name__ if not (inspect.ismodule(object) or - inspect.isclass(object) or + _isclass(object) or inspect.isroutine(object) or inspect.isdatadescriptor(object) or _getdoc(object)): diff --git a/Lib/test/pydoc_mod.py b/Lib/test/pydoc_mod.py index 9c1fff5c2f2c1..f9bc4b89d3d0a 100644 --- a/Lib/test/pydoc_mod.py +++ b/Lib/test/pydoc_mod.py @@ -1,5 +1,8 @@ """This is a test module for test_pydoc""" +import types +import typing + __author__ = "Benjamin Peterson" __credits__ = "Nobody" __version__ = "1.2.3.4" @@ -24,6 +27,8 @@ def get_answer(self): def is_it_true(self): """ Return self.get_answer() """ return self.get_answer() + def __class_getitem__(self, item): + return types.GenericAlias(self, item) def doc_func(): """ @@ -35,3 +40,10 @@ def doc_func(): def nodoc_func(): pass + + +list_alias1 = typing.List[int] +list_alias2 = list[int] +c_alias = C[int] +type_union1 = typing.Union[int, str] +type_union2 = int | str diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py index 44c16989716a0..bd37ab9d3324e 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -95,6 +95,11 @@ class C(builtins.object) | say_no(self) |\x20\x20 | ---------------------------------------------------------------------- + | Class methods defined here: + |\x20\x20 + | __class_getitem__(item) from builtins.type + |\x20\x20 + | ---------------------------------------------------------------------- | Data descriptors defined here: |\x20\x20 | __dict__ @@ -114,6 +119,11 @@ class C(builtins.object) DATA __xyz__ = 'X, Y and Z' + c_alias = test.pydoc_mod.C[int] + list_alias1 = typing.List[int] + list_alias2 = list[int] + type_union1 = typing.Union[int, str] + type_union2 = int | str VERSION 1.2.3.4 @@ -141,6 +151,15 @@ class C(builtins.object)

This is a test module for test_pydoc

+ + +\x20\x20\x20\x20 + +
 
+Modules
       
types
+
typing
+

+ @@ -210,6 +229,10 @@ class C(builtins.object)
say_no(self)
+
+Class methods defined here:
+
__class_getitem__(item) from builtins.type
+
Data descriptors defined here:
__dict__
@@ -237,7 +260,12 @@ class C(builtins.object) Data \x20\x20\x20\x20
-
 
Classes
       __xyz__ = 'X, Y and Z'

+__xyz__ = 'X, Y and Z'
+c_alias = test.pydoc_mod.C[int]
+list_alias1 = typing.List[int]
+list_alias2 = list[int]
+type_union1 = typing.Union[int, str]
+type_union2 = int | str

 
@@ -1048,6 +1076,43 @@ class C: "New-style class" expected = 'C in module %s object' % __name__ self.assertIn(expected, pydoc.render_doc(c)) + def test_generic_alias(self): + self.assertEqual(pydoc.describe(typing.List[int]), '_GenericAlias') + doc = pydoc.render_doc(typing.List[int], renderer=pydoc.plaintext) + self.assertIn('_GenericAlias in module typing', doc) + self.assertIn('List = class list(object)', doc) + self.assertIn(list.__doc__.strip().splitlines()[0], doc) + + self.assertEqual(pydoc.describe(list[int]), 'GenericAlias') + doc = pydoc.render_doc(list[int], renderer=pydoc.plaintext) + self.assertIn('GenericAlias in module builtins', doc) + self.assertIn('\nclass list(object)', doc) + self.assertIn(list.__doc__.strip().splitlines()[0], doc) + + def test_union_type(self): + self.assertEqual(pydoc.describe(typing.Union[int, str]), '_UnionGenericAlias') + doc = pydoc.render_doc(typing.Union[int, str], renderer=pydoc.plaintext) + self.assertIn('_UnionGenericAlias in module typing', doc) + self.assertIn('Union = typing.Union', doc) + if typing.Union.__doc__: + self.assertIn(typing.Union.__doc__.strip().splitlines()[0], doc) + + self.assertEqual(pydoc.describe(int | str), 'UnionType') + doc = pydoc.render_doc(int | str, renderer=pydoc.plaintext) + self.assertIn('UnionType in module types object', doc) + self.assertIn('\nclass UnionType(builtins.object)', doc) + self.assertIn(types.UnionType.__doc__.strip().splitlines()[0], doc) + + def test_special_form(self): + self.assertEqual(pydoc.describe(typing.Any), '_SpecialForm') + doc = pydoc.render_doc(typing.Any, renderer=pydoc.plaintext) + self.assertIn('_SpecialForm in module typing', doc) + if typing.Any.__doc__: + self.assertIn('Any = typing.Any', doc) + self.assertIn(typing.Any.__doc__.strip().splitlines()[0], doc) + else: + self.assertIn('Any = class _SpecialForm(_Final)', doc) + def test_typing_pydoc(self): def foo(data: typing.List[typing.Any], x: int) -> typing.Iterator[typing.Tuple[int, typing.Any]]: diff --git a/Misc/NEWS.d/next/Library/2021-12-25-14-13-14.bpo-40296.p0YVGB.rst b/Misc/NEWS.d/next/Library/2021-12-25-14-13-14.bpo-40296.p0YVGB.rst new file mode 100644 index 0000000000000..ea469c916b9db --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-12-25-14-13-14.bpo-40296.p0YVGB.rst @@ -0,0 +1 @@ +Fix supporting generic aliases in :mod:`pydoc`. From webhook-mailer at python.org Fri Mar 18 15:45:55 2022 From: webhook-mailer at python.org (miss-islington) Date: Fri, 18 Mar 2022 19:45:55 -0000 Subject: [Python-checkins] bpo-47022: Document asynchat, asyncore and smtpd removals in 3.12 (GH-31891) Message-ID: https://github.com/python/cpython/commit/77473846439b8a3eae66de1a1cfe931619f38513 commit: 77473846439b8a3eae66de1a1cfe931619f38513 branch: main author: Hugo van Kemenade committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-18T12:45:37-07:00 summary: bpo-47022: Document asynchat, asyncore and smtpd removals in 3.12 (GH-31891) Document the deprecation of asyncore, asynchat, and smtpd with a slated removal in Python 3.12 thanks to PEP 594. files: A Misc/NEWS.d/next/Library/2022-03-15-09-29-52.bpo-47022.uaEDcI.rst M Doc/library/asynchat.rst M Doc/library/asyncore.rst M Doc/library/smtpd.rst M Doc/library/superseded.rst M Doc/whatsnew/3.11.rst M Lib/asynchat.py M Lib/asyncore.py M Lib/smtpd.py diff --git a/Doc/library/asynchat.rst b/Doc/library/asynchat.rst index 9e51416b83a57..4354444a1d331 100644 --- a/Doc/library/asynchat.rst +++ b/Doc/library/asynchat.rst @@ -3,6 +3,7 @@ .. module:: asynchat :synopsis: Support for asynchronous command/response protocols. + :deprecated: .. moduleauthor:: Sam Rushing .. sectionauthor:: Steve Holden @@ -10,6 +11,7 @@ **Source code:** :source:`Lib/asynchat.py` .. deprecated:: 3.6 + :mod:`asynchat` will be removed in Python 3.12 (:pep:`594`). Please use :mod:`asyncio` instead. -------------- diff --git a/Doc/library/asyncore.rst b/Doc/library/asyncore.rst index a86518ebff277..e481e13db76f7 100644 --- a/Doc/library/asyncore.rst +++ b/Doc/library/asyncore.rst @@ -4,6 +4,7 @@ .. module:: asyncore :synopsis: A base class for developing asynchronous socket handling services. + :deprecated: .. moduleauthor:: Sam Rushing .. sectionauthor:: Christopher Petrilli @@ -13,6 +14,7 @@ **Source code:** :source:`Lib/asyncore.py` .. deprecated:: 3.6 + :mod:`asyncore` will be removed in Python 3.12 (:pep:`594`). Please use :mod:`asyncio` instead. -------------- diff --git a/Doc/library/smtpd.rst b/Doc/library/smtpd.rst index 611411ddd295b..6b37a0517063d 100644 --- a/Doc/library/smtpd.rst +++ b/Doc/library/smtpd.rst @@ -3,6 +3,7 @@ .. module:: smtpd :synopsis: A SMTP server implementation in Python. + :deprecated: .. moduleauthor:: Barry Warsaw .. sectionauthor:: Moshe Zadka @@ -14,6 +15,7 @@ This module offers several classes to implement SMTP (email) servers. .. deprecated:: 3.6 + :mod:`smtpd` will be removed in Python 3.12 (:pep:`594`). The `aiosmtpd `_ package is a recommended replacement for this module. It is based on :mod:`asyncio` and provides a more straightforward API. diff --git a/Doc/library/superseded.rst b/Doc/library/superseded.rst index 50a5983236e76..fd23e4d1536d3 100644 --- a/Doc/library/superseded.rst +++ b/Doc/library/superseded.rst @@ -10,5 +10,8 @@ backwards compatibility. They have been superseded by other modules. .. toctree:: - optparse.rst + asynchat.rst + asyncore.rst + smtpd.rst imp.rst + optparse.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 2af663809a448..8b3450ed404f2 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -555,6 +555,11 @@ Deprecated :func:`locale.getlocale` functions instead. (Contributed by Victor Stinner in :issue:`46659`.) +* The :mod:`asynchat`, :mod:`asyncore` and :mod:`smtpd` modules have been + deprecated since at least Python 3.6. Their documentation and deprecation + warnings have now been updated to note they will removed in Python 3.12 + (:pep:`594`). + (Contributed by Hugo van Kemenade in :issue:`47022`.) Removed ======= diff --git a/Lib/asynchat.py b/Lib/asynchat.py index de26ffa648ffe..e081e67c75acb 100644 --- a/Lib/asynchat.py +++ b/Lib/asynchat.py @@ -50,7 +50,7 @@ from warnings import warn warn( - 'The asynchat module is deprecated. ' + 'The asynchat module is deprecated and will be removed in Python 3.12. ' 'The recommended replacement is asyncio', DeprecationWarning, stacklevel=2) diff --git a/Lib/asyncore.py b/Lib/asyncore.py index b1eea4bf65211..a360d404395e5 100644 --- a/Lib/asyncore.py +++ b/Lib/asyncore.py @@ -58,7 +58,7 @@ errorcode warnings.warn( - 'The asyncore module is deprecated. ' + 'The asyncore module is deprecated and will be removed in Python 3.12. ' 'The recommended replacement is asyncio', DeprecationWarning, stacklevel=2) diff --git a/Lib/smtpd.py b/Lib/smtpd.py index 1cd004fbc6fe5..eeda155b920f7 100755 --- a/Lib/smtpd.py +++ b/Lib/smtpd.py @@ -85,7 +85,8 @@ ] warn( - 'The smtpd module is deprecated and unmaintained. Please see aiosmtpd ' + 'The smtpd module is deprecated and unmaintained and will be removed ' + 'in Python 3.12. Please see aiosmtpd ' '(https://aiosmtpd.readthedocs.io/) for the recommended replacement.', DeprecationWarning, stacklevel=2) diff --git a/Misc/NEWS.d/next/Library/2022-03-15-09-29-52.bpo-47022.uaEDcI.rst b/Misc/NEWS.d/next/Library/2022-03-15-09-29-52.bpo-47022.uaEDcI.rst new file mode 100644 index 0000000000000..0e867b9506484 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-15-09-29-52.bpo-47022.uaEDcI.rst @@ -0,0 +1,4 @@ +The :mod:`asynchat`, :mod:`asyncore` and :mod:`smtpd` modules have been +deprecated since at least Python 3.6. Their documentation and deprecation +warnings and have now been updated to note they will removed in Python 3.12 +(:pep:`594`). From webhook-mailer at python.org Sat Mar 19 08:01:51 2022 From: webhook-mailer at python.org (asvetlov) Date: Sat, 19 Mar 2022 12:01:51 -0000 Subject: [Python-checkins] bpo-47057: Use FASTCALL convention for FutureIter.throw() (GH-31973) Message-ID: https://github.com/python/cpython/commit/0a8b8e0d262eae83ffbc6b414a1f5747cdbd1d88 commit: 0a8b8e0d262eae83ffbc6b414a1f5747cdbd1d88 branch: main author: Andrew Svetlov committer: asvetlov date: 2022-03-19T14:01:46+02:00 summary: bpo-47057: Use FASTCALL convention for FutureIter.throw() (GH-31973) Co-authored-by: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> files: A Misc/NEWS.d/next/Library/2022-03-18-14-22-38.bpo-47057.n-IHbt.rst M Modules/_asynciomodule.c diff --git a/Misc/NEWS.d/next/Library/2022-03-18-14-22-38.bpo-47057.n-IHbt.rst b/Misc/NEWS.d/next/Library/2022-03-18-14-22-38.bpo-47057.n-IHbt.rst new file mode 100644 index 0000000000000..b404b45e7cee4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-18-14-22-38.bpo-47057.n-IHbt.rst @@ -0,0 +1 @@ +Use FASTCALL convention for ``FutureIter.throw()`` diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 24119782d9c4d..c3e9cb2fa2a30 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -1637,18 +1637,23 @@ FutureIter_send(futureiterobject *self, PyObject *unused) } static PyObject * -FutureIter_throw(futureiterobject *self, PyObject *args) +FutureIter_throw(futureiterobject *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *type, *val = NULL, *tb = NULL; - if (!PyArg_ParseTuple(args, "O|OO", &type, &val, &tb)) + if (!_PyArg_CheckPositional("throw", nargs, 1, 3)) { return NULL; + } - if (val == Py_None) { - val = NULL; + type = args[0]; + if (nargs == 3) { + val = args[1]; + tb = args[2]; + } + else if (nargs == 2) { + val = args[1]; } - if (tb == Py_None) { - tb = NULL; - } else if (tb != NULL && !PyTraceBack_Check(tb)) { + + if (tb != NULL && !PyTraceBack_Check(tb)) { PyErr_SetString(PyExc_TypeError, "throw() third argument must be a traceback"); return NULL; } @@ -1708,7 +1713,7 @@ FutureIter_traverse(futureiterobject *it, visitproc visit, void *arg) static PyMethodDef FutureIter_methods[] = { {"send", (PyCFunction)FutureIter_send, METH_O, NULL}, - {"throw", (PyCFunction)FutureIter_throw, METH_VARARGS, NULL}, + {"throw", (PyCFunction)(void(*)(void))FutureIter_throw, METH_FASTCALL, NULL}, {"close", (PyCFunction)FutureIter_close, METH_NOARGS, NULL}, {NULL, NULL} /* Sentinel */ }; From webhook-mailer at python.org Sat Mar 19 08:13:37 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Sat, 19 Mar 2022 12:13:37 -0000 Subject: [Python-checkins] bpo-39394: Improve warning message in the re module (GH-31988) Message-ID: https://github.com/python/cpython/commit/4142961b9f5ad3bf93976a6a7162f8049e354018 commit: 4142961b9f5ad3bf93976a6a7162f8049e354018 branch: main author: Serhiy Storchaka committer: serhiy-storchaka date: 2022-03-19T14:13:31+02:00 summary: bpo-39394: Improve warning message in the re module (GH-31988) A warning about inline flags not at the start of the regular expression now contains the position of the flag. files: A Misc/NEWS.d/next/Library/2022-03-19-13-38-29.bpo-39394.7j6WL6.rst M Lib/sre_parse.py M Lib/test/test_re.py diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py index 83119168e6376..53706676e9f7b 100644 --- a/Lib/sre_parse.py +++ b/Lib/sre_parse.py @@ -807,9 +807,11 @@ def _parse(source, state, verbose, nested, first=False): if not first or subpattern: import warnings warnings.warn( - 'Flags not at the start of the expression %r%s' % ( + 'Flags not at the start of the expression %r%s' + ' but at position %d' % ( source.string[:20], # truncate long regexes ' (truncated)' if len(source.string) > 20 else '', + start, ), DeprecationWarning, stacklevel=nested + 6 ) diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 59575962eb4f3..48dcb16f8fa57 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -1444,7 +1444,8 @@ def test_inline_flags(self): self.assertTrue(re.match(p, lower_char)) self.assertEqual( str(warns.warnings[0].message), - 'Flags not at the start of the expression %r' % p + 'Flags not at the start of the expression %r' + ' but at position 1' % p ) self.assertEqual(warns.warnings[0].filename, __file__) @@ -1453,7 +1454,8 @@ def test_inline_flags(self): self.assertTrue(re.match(p, lower_char)) self.assertEqual( str(warns.warnings[0].message), - 'Flags not at the start of the expression %r (truncated)' % p[:20] + 'Flags not at the start of the expression %r (truncated)' + ' but at position 1' % p[:20] ) self.assertEqual(warns.warnings[0].filename, __file__) @@ -1465,7 +1467,8 @@ def test_inline_flags(self): self.assertTrue(re.match(p, b'a')) self.assertEqual( str(warns.warnings[0].message), - 'Flags not at the start of the expression %r' % p + 'Flags not at the start of the expression %r' + ' but at position 1' % p ) self.assertEqual(warns.warnings[0].filename, __file__) diff --git a/Misc/NEWS.d/next/Library/2022-03-19-13-38-29.bpo-39394.7j6WL6.rst b/Misc/NEWS.d/next/Library/2022-03-19-13-38-29.bpo-39394.7j6WL6.rst new file mode 100644 index 0000000000000..9285179c9fdca --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-19-13-38-29.bpo-39394.7j6WL6.rst @@ -0,0 +1,2 @@ +A warning about inline flags not at the start of the regular expression now +contains the position of the flag. From webhook-mailer at python.org Sat Mar 19 08:27:43 2022 From: webhook-mailer at python.org (asvetlov) Date: Sat, 19 Mar 2022 12:27:43 -0000 Subject: [Python-checkins] bpo-44544: add textwrap placeholder arg (GH-27671) Message-ID: https://github.com/python/cpython/commit/cb7874f49d3d55df73a3c529773af14e2e344fb7 commit: cb7874f49d3d55df73a3c529773af14e2e344fb7 branch: main author: andrei kulakov committer: asvetlov date: 2022-03-19T14:27:37+02:00 summary: bpo-44544: add textwrap placeholder arg (GH-27671) files: M Doc/library/textwrap.rst diff --git a/Doc/library/textwrap.rst b/Doc/library/textwrap.rst index 7780e24176965..1a9d5f98f78a7 100644 --- a/Doc/library/textwrap.rst +++ b/Doc/library/textwrap.rst @@ -21,7 +21,8 @@ functions should be good enough; otherwise, you should use an instance of subsequent_indent="", expand_tabs=True, \ replace_whitespace=True, fix_sentence_endings=False, \ break_long_words=True, drop_whitespace=True, \ - break_on_hyphens=True, tabsize=8, max_lines=None) + break_on_hyphens=True, tabsize=8, max_lines=None, \ + placeholder=' [...]') Wraps the single paragraph in *text* (a string) so every line is at most *width* characters long. Returns a list of output lines, without final @@ -39,7 +40,7 @@ functions should be good enough; otherwise, you should use an instance of replace_whitespace=True, fix_sentence_endings=False, \ break_long_words=True, drop_whitespace=True, \ break_on_hyphens=True, tabsize=8, \ - max_lines=None) + max_lines=None, placeholder=' [...]') Wraps the single paragraph in *text*, and returns a single string containing the wrapped paragraph. :func:`fill` is shorthand for :: From webhook-mailer at python.org Sat Mar 19 08:48:03 2022 From: webhook-mailer at python.org (miss-islington) Date: Sat, 19 Mar 2022 12:48:03 -0000 Subject: [Python-checkins] bpo-44544: add textwrap placeholder arg (GH-27671) Message-ID: https://github.com/python/cpython/commit/c1f327f30db09388fc777196e233b7a6182c6efa commit: c1f327f30db09388fc777196e233b7a6182c6efa branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-19T05:47:58-07:00 summary: bpo-44544: add textwrap placeholder arg (GH-27671) (cherry picked from commit cb7874f49d3d55df73a3c529773af14e2e344fb7) Co-authored-by: andrei kulakov files: M Doc/library/textwrap.rst diff --git a/Doc/library/textwrap.rst b/Doc/library/textwrap.rst index 7780e24176965..1a9d5f98f78a7 100644 --- a/Doc/library/textwrap.rst +++ b/Doc/library/textwrap.rst @@ -21,7 +21,8 @@ functions should be good enough; otherwise, you should use an instance of subsequent_indent="", expand_tabs=True, \ replace_whitespace=True, fix_sentence_endings=False, \ break_long_words=True, drop_whitespace=True, \ - break_on_hyphens=True, tabsize=8, max_lines=None) + break_on_hyphens=True, tabsize=8, max_lines=None, \ + placeholder=' [...]') Wraps the single paragraph in *text* (a string) so every line is at most *width* characters long. Returns a list of output lines, without final @@ -39,7 +40,7 @@ functions should be good enough; otherwise, you should use an instance of replace_whitespace=True, fix_sentence_endings=False, \ break_long_words=True, drop_whitespace=True, \ break_on_hyphens=True, tabsize=8, \ - max_lines=None) + max_lines=None, placeholder=' [...]') Wraps the single paragraph in *text*, and returns a single string containing the wrapped paragraph. :func:`fill` is shorthand for :: From webhook-mailer at python.org Sat Mar 19 08:54:16 2022 From: webhook-mailer at python.org (miss-islington) Date: Sat, 19 Mar 2022 12:54:16 -0000 Subject: [Python-checkins] bpo-44544: add textwrap placeholder arg (GH-27671) Message-ID: https://github.com/python/cpython/commit/fcd57996899569ec6b8028bc5b75f973f7074e21 commit: fcd57996899569ec6b8028bc5b75f973f7074e21 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-19T05:54:07-07:00 summary: bpo-44544: add textwrap placeholder arg (GH-27671) (cherry picked from commit cb7874f49d3d55df73a3c529773af14e2e344fb7) Co-authored-by: andrei kulakov files: M Doc/library/textwrap.rst diff --git a/Doc/library/textwrap.rst b/Doc/library/textwrap.rst index 7780e24176965..1a9d5f98f78a7 100644 --- a/Doc/library/textwrap.rst +++ b/Doc/library/textwrap.rst @@ -21,7 +21,8 @@ functions should be good enough; otherwise, you should use an instance of subsequent_indent="", expand_tabs=True, \ replace_whitespace=True, fix_sentence_endings=False, \ break_long_words=True, drop_whitespace=True, \ - break_on_hyphens=True, tabsize=8, max_lines=None) + break_on_hyphens=True, tabsize=8, max_lines=None, \ + placeholder=' [...]') Wraps the single paragraph in *text* (a string) so every line is at most *width* characters long. Returns a list of output lines, without final @@ -39,7 +40,7 @@ functions should be good enough; otherwise, you should use an instance of replace_whitespace=True, fix_sentence_endings=False, \ break_long_words=True, drop_whitespace=True, \ break_on_hyphens=True, tabsize=8, \ - max_lines=None) + max_lines=None, placeholder=' [...]') Wraps the single paragraph in *text*, and returns a single string containing the wrapped paragraph. :func:`fill` is shorthand for :: From webhook-mailer at python.org Sat Mar 19 10:09:54 2022 From: webhook-mailer at python.org (miss-islington) Date: Sat, 19 Mar 2022 14:09:54 -0000 Subject: [Python-checkins] bpo-39394: Improve warning message in the re module (GH-31988) Message-ID: https://github.com/python/cpython/commit/906f1a4a95e9ca82171a40a28b16533a14fa339c commit: 906f1a4a95e9ca82171a40a28b16533a14fa339c branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-19T07:09:45-07:00 summary: bpo-39394: Improve warning message in the re module (GH-31988) A warning about inline flags not at the start of the regular expression now contains the position of the flag. (cherry picked from commit 4142961b9f5ad3bf93976a6a7162f8049e354018) Co-authored-by: Serhiy Storchaka files: A Misc/NEWS.d/next/Library/2022-03-19-13-38-29.bpo-39394.7j6WL6.rst M Lib/sre_parse.py M Lib/test/test_re.py diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py index 83119168e6376..53706676e9f7b 100644 --- a/Lib/sre_parse.py +++ b/Lib/sre_parse.py @@ -807,9 +807,11 @@ def _parse(source, state, verbose, nested, first=False): if not first or subpattern: import warnings warnings.warn( - 'Flags not at the start of the expression %r%s' % ( + 'Flags not at the start of the expression %r%s' + ' but at position %d' % ( source.string[:20], # truncate long regexes ' (truncated)' if len(source.string) > 20 else '', + start, ), DeprecationWarning, stacklevel=nested + 6 ) diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 588cc7930c327..3d0637817da98 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -1444,7 +1444,8 @@ def test_inline_flags(self): self.assertTrue(re.match(p, lower_char)) self.assertEqual( str(warns.warnings[0].message), - 'Flags not at the start of the expression %r' % p + 'Flags not at the start of the expression %r' + ' but at position 1' % p ) self.assertEqual(warns.warnings[0].filename, __file__) @@ -1453,7 +1454,8 @@ def test_inline_flags(self): self.assertTrue(re.match(p, lower_char)) self.assertEqual( str(warns.warnings[0].message), - 'Flags not at the start of the expression %r (truncated)' % p[:20] + 'Flags not at the start of the expression %r (truncated)' + ' but at position 1' % p[:20] ) self.assertEqual(warns.warnings[0].filename, __file__) @@ -1465,7 +1467,8 @@ def test_inline_flags(self): self.assertTrue(re.match(p, b'a')) self.assertEqual( str(warns.warnings[0].message), - 'Flags not at the start of the expression %r' % p + 'Flags not at the start of the expression %r' + ' but at position 1' % p ) self.assertEqual(warns.warnings[0].filename, __file__) diff --git a/Misc/NEWS.d/next/Library/2022-03-19-13-38-29.bpo-39394.7j6WL6.rst b/Misc/NEWS.d/next/Library/2022-03-19-13-38-29.bpo-39394.7j6WL6.rst new file mode 100644 index 0000000000000..9285179c9fdca --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-19-13-38-29.bpo-39394.7j6WL6.rst @@ -0,0 +1,2 @@ +A warning about inline flags not at the start of the regular expression now +contains the position of the flag. From webhook-mailer at python.org Sat Mar 19 10:10:03 2022 From: webhook-mailer at python.org (miss-islington) Date: Sat, 19 Mar 2022 14:10:03 -0000 Subject: [Python-checkins] bpo-39394: Improve warning message in the re module (GH-31988) Message-ID: https://github.com/python/cpython/commit/cbcd2e36d6cbb1d8b6a2b30a2cf1484b7857e7d6 commit: cbcd2e36d6cbb1d8b6a2b30a2cf1484b7857e7d6 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-19T07:09:59-07:00 summary: bpo-39394: Improve warning message in the re module (GH-31988) A warning about inline flags not at the start of the regular expression now contains the position of the flag. (cherry picked from commit 4142961b9f5ad3bf93976a6a7162f8049e354018) Co-authored-by: Serhiy Storchaka files: A Misc/NEWS.d/next/Library/2022-03-19-13-38-29.bpo-39394.7j6WL6.rst M Lib/sre_parse.py M Lib/test/test_re.py diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py index 83119168e6376..53706676e9f7b 100644 --- a/Lib/sre_parse.py +++ b/Lib/sre_parse.py @@ -807,9 +807,11 @@ def _parse(source, state, verbose, nested, first=False): if not first or subpattern: import warnings warnings.warn( - 'Flags not at the start of the expression %r%s' % ( + 'Flags not at the start of the expression %r%s' + ' but at position %d' % ( source.string[:20], # truncate long regexes ' (truncated)' if len(source.string) > 20 else '', + start, ), DeprecationWarning, stacklevel=nested + 6 ) diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 1bfbcb853c4ed..48a609b5a0031 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -1443,7 +1443,8 @@ def test_inline_flags(self): self.assertTrue(re.match(p, lower_char)) self.assertEqual( str(warns.warnings[0].message), - 'Flags not at the start of the expression %r' % p + 'Flags not at the start of the expression %r' + ' but at position 1' % p ) self.assertEqual(warns.warnings[0].filename, __file__) @@ -1452,7 +1453,8 @@ def test_inline_flags(self): self.assertTrue(re.match(p, lower_char)) self.assertEqual( str(warns.warnings[0].message), - 'Flags not at the start of the expression %r (truncated)' % p[:20] + 'Flags not at the start of the expression %r (truncated)' + ' but at position 1' % p[:20] ) self.assertEqual(warns.warnings[0].filename, __file__) @@ -1464,7 +1466,8 @@ def test_inline_flags(self): self.assertTrue(re.match(p, b'a')) self.assertEqual( str(warns.warnings[0].message), - 'Flags not at the start of the expression %r' % p + 'Flags not at the start of the expression %r' + ' but at position 1' % p ) self.assertEqual(warns.warnings[0].filename, __file__) diff --git a/Misc/NEWS.d/next/Library/2022-03-19-13-38-29.bpo-39394.7j6WL6.rst b/Misc/NEWS.d/next/Library/2022-03-19-13-38-29.bpo-39394.7j6WL6.rst new file mode 100644 index 0000000000000..9285179c9fdca --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-19-13-38-29.bpo-39394.7j6WL6.rst @@ -0,0 +1,2 @@ +A warning about inline flags not at the start of the regular expression now +contains the position of the flag. From webhook-mailer at python.org Sat Mar 19 10:10:49 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Sat, 19 Mar 2022 14:10:49 -0000 Subject: [Python-checkins] bpo-47066: Convert a warning about flags not at the start of the regular expression into error (GH-31994) Message-ID: https://github.com/python/cpython/commit/92a6abf72e7a8274f96edbb5297119d4ff055be7 commit: 92a6abf72e7a8274f96edbb5297119d4ff055be7 branch: main author: Serhiy Storchaka committer: serhiy-storchaka date: 2022-03-19T16:10:44+02:00 summary: bpo-47066: Convert a warning about flags not at the start of the regular expression into error (GH-31994) files: A Misc/NEWS.d/next/Library/2022-03-19-14-12-23.bpo-47066.we3YFx.rst M Doc/library/re.rst M Doc/whatsnew/3.11.rst M Lib/sre_parse.py M Lib/test/test_re.py diff --git a/Doc/library/re.rst b/Doc/library/re.rst index 8d62e3bf4d8d8..950a5b1fdc240 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -299,6 +299,9 @@ The special characters are: :func:`re.compile` function. Flags should be used first in the expression string. + .. versionchanged:: 3.11 + This construction can only be used at the start of the expression. + .. index:: single: (?:; in regular expressions ``(?:...)`` diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 8b3450ed404f2..b7e9dc6e9e37f 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -688,6 +688,11 @@ Changes in the Python API if no locale is specified. (Contributed by Victor Stinner in :issue:`46659`.) +* Global inline flags (e.g. ``(?i)``) can now only be used at the start of + the regular expressions. Using them not at the start of expression was + deprecated since Python 3.6. + (Contributed by Serhiy Storchaka in :issue:`47066`.) + Build Changes ============= diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py index 53706676e9f7b..bb95107393870 100644 --- a/Lib/sre_parse.py +++ b/Lib/sre_parse.py @@ -805,16 +805,9 @@ def _parse(source, state, verbose, nested, first=False): flags = _parse_flags(source, state, char) if flags is None: # global flags if not first or subpattern: - import warnings - warnings.warn( - 'Flags not at the start of the expression %r%s' - ' but at position %d' % ( - source.string[:20], # truncate long regexes - ' (truncated)' if len(source.string) > 20 else '', - start, - ), - DeprecationWarning, stacklevel=nested + 6 - ) + raise source.error('global flags not at the start ' + 'of the expression', + source.tell() - start) if (state.flags & SRE_FLAG_VERBOSE) and not verbose: raise Verbose continue diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 48dcb16f8fa57..f8bbe5178219a 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -1439,66 +1439,22 @@ def test_inline_flags(self): self.assertTrue(re.match('(?x) (?i) ' + upper_char, lower_char)) self.assertTrue(re.match(' (?x) (?i) ' + upper_char, lower_char, re.X)) - p = upper_char + '(?i)' - with self.assertWarns(DeprecationWarning) as warns: - self.assertTrue(re.match(p, lower_char)) - self.assertEqual( - str(warns.warnings[0].message), - 'Flags not at the start of the expression %r' - ' but at position 1' % p - ) - self.assertEqual(warns.warnings[0].filename, __file__) - - p = upper_char + '(?i)%s' % ('.?' * 100) - with self.assertWarns(DeprecationWarning) as warns: - self.assertTrue(re.match(p, lower_char)) - self.assertEqual( - str(warns.warnings[0].message), - 'Flags not at the start of the expression %r (truncated)' - ' but at position 1' % p[:20] - ) - self.assertEqual(warns.warnings[0].filename, __file__) + msg = "global flags not at the start of the expression" + self.checkPatternError(upper_char + '(?i)', msg, 1) # bpo-30605: Compiling a bytes instance regex was throwing a BytesWarning with warnings.catch_warnings(): warnings.simplefilter('error', BytesWarning) - p = b'A(?i)' - with self.assertWarns(DeprecationWarning) as warns: - self.assertTrue(re.match(p, b'a')) - self.assertEqual( - str(warns.warnings[0].message), - 'Flags not at the start of the expression %r' - ' but at position 1' % p - ) - self.assertEqual(warns.warnings[0].filename, __file__) - - with self.assertWarns(DeprecationWarning): - self.assertTrue(re.match('(?s).(?i)' + upper_char, '\n' + lower_char)) - with self.assertWarns(DeprecationWarning): - self.assertTrue(re.match('(?i) ' + upper_char + ' (?x)', lower_char)) - with self.assertWarns(DeprecationWarning): - self.assertTrue(re.match(' (?x) (?i) ' + upper_char, lower_char)) - with self.assertWarns(DeprecationWarning): - self.assertTrue(re.match('^(?i)' + upper_char, lower_char)) - with self.assertWarns(DeprecationWarning): - self.assertTrue(re.match('$|(?i)' + upper_char, lower_char)) - with self.assertWarns(DeprecationWarning) as warns: - self.assertTrue(re.match('(?:(?i)' + upper_char + ')', lower_char)) - self.assertRegex(str(warns.warnings[0].message), - 'Flags not at the start') - self.assertEqual(warns.warnings[0].filename, __file__) - with self.assertWarns(DeprecationWarning) as warns: - self.assertTrue(re.fullmatch('(^)?(?(1)(?i)' + upper_char + ')', - lower_char)) - self.assertRegex(str(warns.warnings[0].message), - 'Flags not at the start') - self.assertEqual(warns.warnings[0].filename, __file__) - with self.assertWarns(DeprecationWarning) as warns: - self.assertTrue(re.fullmatch('($)?(?(1)|(?i)' + upper_char + ')', - lower_char)) - self.assertRegex(str(warns.warnings[0].message), - 'Flags not at the start') - self.assertEqual(warns.warnings[0].filename, __file__) + self.checkPatternError(b'A(?i)', msg, 1) + + self.checkPatternError('(?s).(?i)' + upper_char, msg, 5) + self.checkPatternError('(?i) ' + upper_char + ' (?x)', msg, 7) + self.checkPatternError(' (?x) (?i) ' + upper_char, msg, 1) + self.checkPatternError('^(?i)' + upper_char, msg, 1) + self.checkPatternError('$|(?i)' + upper_char, msg, 2) + self.checkPatternError('(?:(?i)' + upper_char + ')', msg, 3) + self.checkPatternError('(^)?(?(1)(?i)' + upper_char + ')', msg, 9) + self.checkPatternError('($)?(?(1)|(?i)' + upper_char + ')', msg, 10) def test_dollar_matches_twice(self): diff --git a/Misc/NEWS.d/next/Library/2022-03-19-14-12-23.bpo-47066.we3YFx.rst b/Misc/NEWS.d/next/Library/2022-03-19-14-12-23.bpo-47066.we3YFx.rst new file mode 100644 index 0000000000000..f28275b0706bf --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-19-14-12-23.bpo-47066.we3YFx.rst @@ -0,0 +1,3 @@ +Global inline flags (e.g. ``(?i)``) can now only be used at the start of the +regular expressions. Using them not at the start of expression was +deprecated since Python 3.6. From webhook-mailer at python.org Sat Mar 19 11:12:57 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Sat, 19 Mar 2022 15:12:57 -0000 Subject: [Python-checkins] [3.9] bpo-40296: Fix supporting generic aliases in pydoc (GH-30253). (GH-31976) (GH-31981) Message-ID: https://github.com/python/cpython/commit/e207d721fcea01123f0e3edb83b6decdcb5e5e63 commit: e207d721fcea01123f0e3edb83b6decdcb5e5e63 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: serhiy-storchaka date: 2022-03-19T17:12:48+02:00 summary: [3.9] bpo-40296: Fix supporting generic aliases in pydoc (GH-30253). (GH-31976) (GH-31981) (cherry picked from commit cd44afc573e2e2de8d7e5a9119c347373066cd10) (cherry picked from commit a5b7678a67ac99edd50822827b772e7d9afc8e64) files: A Misc/NEWS.d/next/Library/2021-12-25-14-13-14.bpo-40296.p0YVGB.rst M Lib/pydoc.py M Lib/test/pydoc_mod.py M Lib/test/test_pydoc.py diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 4f9d227ff4603..ead678530768f 100755 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -69,6 +69,7 @@ class or function within a module or module in a package. If the import sysconfig import time import tokenize +import types import urllib.parse import warnings from collections import deque @@ -90,13 +91,16 @@ def pathdirs(): normdirs.append(normdir) return dirs +def _isclass(object): + return inspect.isclass(object) and not isinstance(object, types.GenericAlias) + def _findclass(func): cls = sys.modules.get(func.__module__) if cls is None: return None for name in func.__qualname__.split('.')[:-1]: cls = getattr(cls, name) - if not inspect.isclass(cls): + if not _isclass(cls): return None return cls @@ -104,7 +108,7 @@ def _finddoc(obj): if inspect.ismethod(obj): name = obj.__func__.__name__ self = obj.__self__ - if (inspect.isclass(self) and + if (_isclass(self) and getattr(getattr(self, name, None), '__func__') is obj.__func__): # classmethod cls = self @@ -118,7 +122,7 @@ def _finddoc(obj): elif inspect.isbuiltin(obj): name = obj.__name__ self = obj.__self__ - if (inspect.isclass(self) and + if (_isclass(self) and self.__qualname__ + '.' + name == obj.__qualname__): # classmethod cls = self @@ -205,7 +209,7 @@ def classname(object, modname): def isdata(object): """Check if an object is of a type that probably means it's data.""" - return not (inspect.ismodule(object) or inspect.isclass(object) or + return not (inspect.ismodule(object) or _isclass(object) or inspect.isroutine(object) or inspect.isframe(object) or inspect.istraceback(object) or inspect.iscode(object)) @@ -470,7 +474,7 @@ def document(self, object, name=None, *args): # by lacking a __name__ attribute) and an instance. try: if inspect.ismodule(object): return self.docmodule(*args) - if inspect.isclass(object): return self.docclass(*args) + if _isclass(object): return self.docclass(*args) if inspect.isroutine(object): return self.docroutine(*args) except AttributeError: pass @@ -775,7 +779,7 @@ def docmodule(self, object, name=None, mod=None, *ignored): modules = inspect.getmembers(object, inspect.ismodule) classes, cdict = [], {} - for key, value in inspect.getmembers(object, inspect.isclass): + for key, value in inspect.getmembers(object, _isclass): # if __all__ exists, believe it. Otherwise use old heuristic. if (all is not None or (inspect.getmodule(value) or object) is object): @@ -1217,7 +1221,7 @@ def docmodule(self, object, name=None, mod=None): result = result + self.section('DESCRIPTION', desc) classes = [] - for key, value in inspect.getmembers(object, inspect.isclass): + for key, value in inspect.getmembers(object, _isclass): # if __all__ exists, believe it. Otherwise use old heuristic. if (all is not None or (inspect.getmodule(value) or object) is object): @@ -1698,7 +1702,7 @@ def describe(thing): return 'member descriptor %s.%s.%s' % ( thing.__objclass__.__module__, thing.__objclass__.__name__, thing.__name__) - if inspect.isclass(thing): + if _isclass(thing): return 'class ' + thing.__name__ if inspect.isfunction(thing): return 'function ' + thing.__name__ @@ -1759,7 +1763,7 @@ def render_doc(thing, title='Python Library Documentation: %s', forceload=0, desc += ' in module ' + module.__name__ if not (inspect.ismodule(object) or - inspect.isclass(object) or + _isclass(object) or inspect.isroutine(object) or inspect.isdatadescriptor(object) or _getdoc(object)): diff --git a/Lib/test/pydoc_mod.py b/Lib/test/pydoc_mod.py index 9c1fff5c2f2c1..bc3677b7e0548 100644 --- a/Lib/test/pydoc_mod.py +++ b/Lib/test/pydoc_mod.py @@ -1,5 +1,8 @@ """This is a test module for test_pydoc""" +import types +import typing + __author__ = "Benjamin Peterson" __credits__ = "Nobody" __version__ = "1.2.3.4" @@ -24,6 +27,8 @@ def get_answer(self): def is_it_true(self): """ Return self.get_answer() """ return self.get_answer() + def __class_getitem__(self, item): + return types.GenericAlias(self, item) def doc_func(): """ @@ -35,3 +40,9 @@ def doc_func(): def nodoc_func(): pass + + +list_alias1 = typing.List[int] +list_alias2 = list[int] +c_alias = C[int] +type_union1 = typing.Union[int, str] diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py index 9b0e94de49d60..34188a158d179 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -95,6 +95,11 @@ class C(builtins.object) | say_no(self) |\x20\x20 | ---------------------------------------------------------------------- + | Class methods defined here: + |\x20\x20 + | __class_getitem__(item) from builtins.type + |\x20\x20 + | ---------------------------------------------------------------------- | Data descriptors defined here: |\x20\x20 | __dict__ @@ -114,6 +119,10 @@ class C(builtins.object) DATA __xyz__ = 'X, Y and Z' + c_alias = test.pydoc_mod.C[int] + list_alias1 = typing.List[int] + list_alias2 = list[int] + type_union1 = typing.Union[int, str] VERSION 1.2.3.4 @@ -141,6 +150,15 @@ class C(builtins.object)

This is a test module for test_pydoc

+ + +\x20\x20\x20\x20 + +
 
+Modules
       
types
+
typing
+

+ @@ -210,6 +228,10 @@ class C(builtins.object)
say_no(self)
+
+Class methods defined here:
+
__class_getitem__(item) from builtins.type
+
Data descriptors defined here:
__dict__
@@ -237,7 +259,11 @@ class C(builtins.object) Data \x20\x20\x20\x20
-
 
Classes
       __xyz__ = 'X, Y and Z'

+

__xyz__ = 'X, Y and Z'
+c_alias = test.pydoc_mod.C[int]
+list_alias1 = typing.List[int]
+list_alias2 = list[int]
+type_union1 = typing.Union[int, str]

 
@@ -1048,6 +1074,37 @@ class C: "New-style class" expected = 'C in module %s object' % __name__ self.assertIn(expected, pydoc.render_doc(c)) + def test_generic_alias(self): + self.assertEqual(pydoc.describe(typing.List[int]), '_GenericAlias') + doc = pydoc.render_doc(typing.List[int], renderer=pydoc.plaintext) + self.assertIn('_GenericAlias in module typing', doc) + self.assertIn('\nclass list(object)', doc) + self.assertIn(list.__doc__.strip().splitlines()[0], doc) + + self.assertEqual(pydoc.describe(list[int]), 'GenericAlias') + doc = pydoc.render_doc(list[int], renderer=pydoc.plaintext) + self.assertIn('GenericAlias in module builtins', doc) + self.assertIn('\nclass list(object)', doc) + self.assertIn(list.__doc__.strip().splitlines()[0], doc) + + def test_union_type(self): + self.assertEqual(pydoc.describe(typing.Union[int, str]), '_UnionGenericAlias') + doc = pydoc.render_doc(typing.Union[int, str], renderer=pydoc.plaintext) + self.assertIn('_UnionGenericAlias in module typing', doc) + self.assertIn('\ntyping.Union', doc) + if typing.Union.__doc__: + self.assertIn(typing.Union.__doc__.strip().splitlines()[0], doc) + + def test_special_form(self): + self.assertEqual(pydoc.describe(typing.Any), '_SpecialForm') + doc = pydoc.render_doc(typing.Any, renderer=pydoc.plaintext) + self.assertIn('_SpecialForm in module typing', doc) + if typing.Any.__doc__: + self.assertIn('\ntyping.Any', doc) + self.assertIn(typing.Any.__doc__.strip().splitlines()[0], doc) + else: + self.assertIn('\nclass _SpecialForm(_Final)', doc) + def test_typing_pydoc(self): def foo(data: typing.List[typing.Any], x: int) -> typing.Iterator[typing.Tuple[int, typing.Any]]: diff --git a/Misc/NEWS.d/next/Library/2021-12-25-14-13-14.bpo-40296.p0YVGB.rst b/Misc/NEWS.d/next/Library/2021-12-25-14-13-14.bpo-40296.p0YVGB.rst new file mode 100644 index 0000000000000..ea469c916b9db --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-12-25-14-13-14.bpo-40296.p0YVGB.rst @@ -0,0 +1 @@ +Fix supporting generic aliases in :mod:`pydoc`. From webhook-mailer at python.org Sat Mar 19 11:14:26 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Sat, 19 Mar 2022 15:14:26 -0000 Subject: [Python-checkins] bpo-46996: IDLE: Drop workarounds for old Tk versions (GH-31962) Message-ID: https://github.com/python/cpython/commit/383a3bec74f0bf0c1b1bef9e0048db389c618452 commit: 383a3bec74f0bf0c1b1bef9e0048db389c618452 branch: main author: Serhiy Storchaka committer: serhiy-storchaka date: 2022-03-19T17:14:21+02:00 summary: bpo-46996: IDLE: Drop workarounds for old Tk versions (GH-31962) files: M Lib/idlelib/configdialog.py M Lib/idlelib/macosx.py M Lib/idlelib/pyshell.py diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index 6d0893680274b..d5748a64a798b 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -1588,7 +1588,7 @@ def create_page_windows(self): win_height_int: Entry > win_height frame_cursor: Frame indent_title: Label - indent_chooser: Spinbox (Combobox < 8.5.9) > indent_spaces + indent_chooser: Spinbox > indent_spaces blink_on: Checkbutton > cursor_blink frame_autocomplete: Frame auto_wait_title: Label diff --git a/Lib/idlelib/macosx.py b/Lib/idlelib/macosx.py index 470de5d89cadd..53848fb079eab 100644 --- a/Lib/idlelib/macosx.py +++ b/Lib/idlelib/macosx.py @@ -68,27 +68,6 @@ def isXQuartz(): return _tk_type == "xquartz" -def tkVersionWarning(root): - """ - Returns a string warning message if the Tk version in use appears to - be one known to cause problems with IDLE. - 1. Apple Cocoa-based Tk 8.5.7 shipped with Mac OS X 10.6 is unusable. - 2. Apple Cocoa-based Tk 8.5.9 in OS X 10.7 and 10.8 is better but - can still crash unexpectedly. - """ - - if isCocoaTk(): - patchlevel = root.tk.call('info', 'patchlevel') - if patchlevel not in ('8.5.7', '8.5.9'): - return False - return ("WARNING: The version of Tcl/Tk ({0}) in use may" - " be unstable.\n" - "Visit https://www.python.org/download/mac/tcltk/" - " for current information.".format(patchlevel)) - else: - return False - - def readSystemPreferences(): """ Fetch the macOS system preferences. diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index 6c333b0bc3b81..2e54a81a1d38d 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -22,15 +22,6 @@ pass from tkinter import messagebox -if TkVersion < 8.5: - root = Tk() # otherwise create root in main - root.withdraw() - from idlelib.run import fix_scaling - fix_scaling(root) - messagebox.showerror("Idle Cannot Start", - "Idle requires tcl/tk 8.5+, not %s." % TkVersion, - parent=root) - raise SystemExit(1) from code import InteractiveInterpreter import itertools @@ -1690,11 +1681,6 @@ def main(): # the IDLE shell window; this is less intrusive than always # opening a separate window. - # Warn if using a problematic OS X Tk version. - tkversionwarning = macosx.tkVersionWarning(root) - if tkversionwarning: - shell.show_warning(tkversionwarning) - # Warn if the "Prefer tabs when opening documents" system # preference is set to "Always". prefer_tabs_preference_warning = macosx.preferTabsPreferenceWarning() From webhook-mailer at python.org Sat Mar 19 17:01:24 2022 From: webhook-mailer at python.org (ericvsmith) Date: Sat, 19 Mar 2022 21:01:24 -0000 Subject: [Python-checkins] bpo-46382 dataclass(slots=True) now takes inherited slots into account (GH-31980) Message-ID: https://github.com/python/cpython/commit/82e9b0bb0ac44d4942b9e01b2cdd2ca85c17e563 commit: 82e9b0bb0ac44d4942b9e01b2cdd2ca85c17e563 branch: main author: Arie Bovenberg committer: ericvsmith date: 2022-03-19T17:01:17-04:00 summary: bpo-46382 dataclass(slots=True) now takes inherited slots into account (GH-31980) Do not include any members in __slots__ that are already in a base class's __slots__. files: A Misc/NEWS.d/next/Library/2022-03-18-17-25-57.bpo-46382.zQUJ66.rst M Doc/library/dataclasses.rst M Lib/dataclasses.py M Lib/test/test_dataclasses.py diff --git a/Doc/library/dataclasses.rst b/Doc/library/dataclasses.rst index 0f6985f0ba8c4..08568da19d71a 100644 --- a/Doc/library/dataclasses.rst +++ b/Doc/library/dataclasses.rst @@ -188,6 +188,16 @@ Module contents .. versionadded:: 3.10 + .. versionchanged:: 3.11 + If a field name is already included in the ``__slots__`` + of a base class, it will not be included in the generated ``__slots__`` + to prevent `overriding them `_. + Therefore, do not use ``__slots__`` to retrieve the field names of a + dataclass. Use :func:`fields` instead. + To be able to determine inherited slots, + base class ``__slots__`` may be any iterable, but *not* an iterator. + + ``field``\s may optionally specify a default value, using normal Python syntax:: diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index b327462080f99..6be7c7b5de917 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -6,6 +6,7 @@ import keyword import builtins import functools +import itertools import abc import _thread from types import FunctionType, GenericAlias @@ -1122,6 +1123,20 @@ def _dataclass_setstate(self, state): object.__setattr__(self, field.name, value) +def _get_slots(cls): + match cls.__dict__.get('__slots__'): + case None: + return + case str(slot): + yield slot + # Slots may be any iterable, but we cannot handle an iterator + # because it will already be (partially) consumed. + case iterable if not hasattr(iterable, '__next__'): + yield from iterable + case _: + raise TypeError(f"Slots of '{cls.__name__}' cannot be determined") + + def _add_slots(cls, is_frozen): # Need to create a new class, since we can't set __slots__ # after a class has been created. @@ -1133,7 +1148,13 @@ def _add_slots(cls, is_frozen): # Create a new dict for our new class. cls_dict = dict(cls.__dict__) field_names = tuple(f.name for f in fields(cls)) - cls_dict['__slots__'] = field_names + # Make sure slots don't overlap with those in base classes. + inherited_slots = set( + itertools.chain.from_iterable(map(_get_slots, cls.__mro__[1:-1])) + ) + cls_dict["__slots__"] = tuple( + itertools.filterfalse(inherited_slots.__contains__, field_names) + ) for field_name in field_names: # Remove our attributes, if present. They'll still be # available in _MARKER. diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py index 2f37ecdfca6b4..847bcd46a6926 100644 --- a/Lib/test/test_dataclasses.py +++ b/Lib/test/test_dataclasses.py @@ -2926,23 +2926,58 @@ class C: x: int def test_generated_slots_value(self): - @dataclass(slots=True) - class Base: - x: int - self.assertEqual(Base.__slots__, ('x',)) + class Root: + __slots__ = {'x'} + + class Root2(Root): + __slots__ = {'k': '...', 'j': ''} + + class Root3(Root2): + __slots__ = ['h'] + + class Root4(Root3): + __slots__ = 'aa' @dataclass(slots=True) - class Delivered(Base): + class Base(Root4): y: int + j: str + h: str + + self.assertEqual(Base.__slots__, ('y', )) + + @dataclass(slots=True) + class Derived(Base): + aa: float + x: str + z: int + k: str + h: str - self.assertEqual(Delivered.__slots__, ('x', 'y')) + self.assertEqual(Derived.__slots__, ('z', )) @dataclass - class AnotherDelivered(Base): + class AnotherDerived(Base): z: int - self.assertTrue('__slots__' not in AnotherDelivered.__dict__) + self.assertNotIn('__slots__', AnotherDerived.__dict__) + + def test_cant_inherit_from_iterator_slots(self): + + class Root: + __slots__ = iter(['a']) + + class Root2(Root): + __slots__ = ('b', ) + + with self.assertRaisesRegex( + TypeError, + "^Slots of 'Root' cannot be determined" + ): + @dataclass(slots=True) + class C(Root2): + x: int def test_returns_new_class(self): class A: diff --git a/Misc/NEWS.d/next/Library/2022-03-18-17-25-57.bpo-46382.zQUJ66.rst b/Misc/NEWS.d/next/Library/2022-03-18-17-25-57.bpo-46382.zQUJ66.rst new file mode 100644 index 0000000000000..9bec94969cb4c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-18-17-25-57.bpo-46382.zQUJ66.rst @@ -0,0 +1,2 @@ +:func:`~dataclasses.dataclass` ``slots=True`` now correctly omits slots already +defined in base classes. Patch by Arie Bovenberg. From webhook-mailer at python.org Sat Mar 19 17:42:23 2022 From: webhook-mailer at python.org (gpshead) Date: Sat, 19 Mar 2022 21:42:23 -0000 Subject: [Python-checkins] bpo-47040: improve document of checksum functions (gh-31955) Message-ID: https://github.com/python/cpython/commit/b3f2d4c8bab52573605c96c809a1e2162eee9d7e commit: b3f2d4c8bab52573605c96c809a1e2162eee9d7e branch: main author: Ma Lin committer: gpshead date: 2022-03-19T14:42:04-07:00 summary: bpo-47040: improve document of checksum functions (gh-31955) Clarifies a versionchanged note on crc32 & adler32 docs that the workaround is only needed for Python 2 and earlier. Also cleans up an unnecessary intermediate variable in the implementation. Authored-By: Ma Lin / animalize Co-authored-by: Gregory P. Smith files: A Misc/NEWS.d/next/Documentation/2022-03-17-13-35-28.bpo-47040.4Dn48U.rst M Doc/library/binascii.rst M Doc/library/zlib.rst M Modules/zlibmodule.c diff --git a/Doc/library/binascii.rst b/Doc/library/binascii.rst index 62d7efe34ab36..19efc2df9483d 100644 --- a/Doc/library/binascii.rst +++ b/Doc/library/binascii.rst @@ -107,7 +107,7 @@ The :mod:`binascii` module defines the following functions: .. function:: crc32(data[, value]) - Compute CRC-32, the 32-bit checksum of *data*, starting with an + Compute CRC-32, the unsigned 32-bit checksum of *data*, starting with an initial CRC of *value*. The default initial CRC is zero. The algorithm is consistent with the ZIP file checksum. Since the algorithm is designed for use as a checksum algorithm, it is not suitable for use as a general hash @@ -121,9 +121,8 @@ The :mod:`binascii` module defines the following functions: .. versionchanged:: 3.0 The result is always unsigned. - To generate the same numeric value across all Python versions and - platforms, use ``crc32(data) & 0xffffffff``. - + To generate the same numeric value when using Python 2 or earlier, + use ``crc32(data) & 0xffffffff``. .. function:: b2a_hex(data[, sep[, bytes_per_sep=1]]) hexlify(data[, sep[, bytes_per_sep=1]]) diff --git a/Doc/library/zlib.rst b/Doc/library/zlib.rst index 793c90f3c4e7a..f0c67d5ae2584 100644 --- a/Doc/library/zlib.rst +++ b/Doc/library/zlib.rst @@ -42,10 +42,9 @@ The available exception and functions in this module are: for use as a general hash algorithm. .. versionchanged:: 3.0 - Always returns an unsigned value. - To generate the same numeric value across all Python versions and - platforms, use ``adler32(data) & 0xffffffff``. - + The result is always unsigned. + To generate the same numeric value when using Python 2 or earlier, + use ``adler32(data) & 0xffffffff``. .. function:: compress(data, /, level=-1, wbits=MAX_WBITS) @@ -137,10 +136,9 @@ The available exception and functions in this module are: for use as a general hash algorithm. .. versionchanged:: 3.0 - Always returns an unsigned value. - To generate the same numeric value across all Python versions and - platforms, use ``crc32(data) & 0xffffffff``. - + The result is always unsigned. + To generate the same numeric value when using Python 2 or earlier, + use ``crc32(data) & 0xffffffff``. .. function:: decompress(data, /, wbits=MAX_WBITS, bufsize=DEF_BUF_SIZE) diff --git a/Misc/NEWS.d/next/Documentation/2022-03-17-13-35-28.bpo-47040.4Dn48U.rst b/Misc/NEWS.d/next/Documentation/2022-03-17-13-35-28.bpo-47040.4Dn48U.rst new file mode 100644 index 0000000000000..e977fb5f59fbc --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-03-17-13-35-28.bpo-47040.4Dn48U.rst @@ -0,0 +1,2 @@ +Clarified the old Python versions compatiblity note of :func:`binascii.crc32` / +:func:`zlib.adler32` / :func:`zlib.crc32` functions. diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c index f9646568d7e01..4cf1b6eeba2f7 100644 --- a/Modules/zlibmodule.c +++ b/Modules/zlibmodule.c @@ -1436,8 +1436,6 @@ static PyObject * zlib_crc32_impl(PyObject *module, Py_buffer *data, unsigned int value) /*[clinic end generated code: output=63499fa20af7ea25 input=26c3ed430fa00b4c]*/ { - int signed_val; - /* Releasing the GIL for very small buffers is inefficient and may lower performance */ if (data->len > 1024*5) { @@ -1452,12 +1450,12 @@ zlib_crc32_impl(PyObject *module, Py_buffer *data, unsigned int value) buf += (size_t) UINT_MAX; len -= (size_t) UINT_MAX; } - signed_val = crc32(value, buf, (unsigned int)len); + value = crc32(value, buf, (unsigned int)len); Py_END_ALLOW_THREADS } else { - signed_val = crc32(value, data->buf, (unsigned int)data->len); + value = crc32(value, data->buf, (unsigned int)data->len); } - return PyLong_FromUnsignedLong(signed_val & 0xffffffffU); + return PyLong_FromUnsignedLong(value & 0xffffffffU); } From webhook-mailer at python.org Sun Mar 20 02:57:17 2022 From: webhook-mailer at python.org (gpshead) Date: Sun, 20 Mar 2022 06:57:17 -0000 Subject: [Python-checkins] [3.10] bpo-47040: improve document of checksum functions (GH-31955) (GH-32002) Message-ID: https://github.com/python/cpython/commit/6d290d5862375799e997f1192ef56abca4e9182e commit: 6d290d5862375799e997f1192ef56abca4e9182e branch: 3.10 author: Ma Lin committer: gpshead date: 2022-03-19T23:57:12-07:00 summary: [3.10] bpo-47040: improve document of checksum functions (GH-31955) (GH-32002) Clarifies a versionchanged note on crc32 & adler32 docs that the workaround is only needed for Python 2 and earlier. Also cleans up an unnecessary intermediate variable in the implementation. Authored-By: Ma Lin / animalize Co-authored-by: Gregory P. Smith files: M Doc/library/binascii.rst M Doc/library/zlib.rst diff --git a/Doc/library/binascii.rst b/Doc/library/binascii.rst index 2c0c1bce5d7f8..5cd058c0b6d74 100644 --- a/Doc/library/binascii.rst +++ b/Doc/library/binascii.rst @@ -135,7 +135,7 @@ The :mod:`binascii` module defines the following functions: .. function:: crc32(data[, value]) - Compute CRC-32, the 32-bit checksum of *data*, starting with an + Compute CRC-32, the unsigned 32-bit checksum of *data*, starting with an initial CRC of *value*. The default initial CRC is zero. The algorithm is consistent with the ZIP file checksum. Since the algorithm is designed for use as a checksum algorithm, it is not suitable for use as a general hash @@ -149,9 +149,8 @@ The :mod:`binascii` module defines the following functions: .. versionchanged:: 3.0 The result is always unsigned. - To generate the same numeric value across all Python versions and - platforms, use ``crc32(data) & 0xffffffff``. - + To generate the same numeric value when using Python 2 or earlier, + use ``crc32(data) & 0xffffffff``. .. function:: b2a_hex(data[, sep[, bytes_per_sep=1]]) hexlify(data[, sep[, bytes_per_sep=1]]) diff --git a/Doc/library/zlib.rst b/Doc/library/zlib.rst index ec60ea24db662..6758c615d74db 100644 --- a/Doc/library/zlib.rst +++ b/Doc/library/zlib.rst @@ -42,10 +42,9 @@ The available exception and functions in this module are: for use as a general hash algorithm. .. versionchanged:: 3.0 - Always returns an unsigned value. - To generate the same numeric value across all Python versions and - platforms, use ``adler32(data) & 0xffffffff``. - + The result is always unsigned. + To generate the same numeric value when using Python 2 or earlier, + use ``adler32(data) & 0xffffffff``. .. function:: compress(data, /, level=-1) @@ -127,10 +126,9 @@ The available exception and functions in this module are: for use as a general hash algorithm. .. versionchanged:: 3.0 - Always returns an unsigned value. - To generate the same numeric value across all Python versions and - platforms, use ``crc32(data) & 0xffffffff``. - + The result is always unsigned. + To generate the same numeric value when using Python 2 or earlier, + use ``crc32(data) & 0xffffffff``. .. function:: decompress(data, /, wbits=MAX_WBITS, bufsize=DEF_BUF_SIZE) From webhook-mailer at python.org Sun Mar 20 03:21:42 2022 From: webhook-mailer at python.org (miss-islington) Date: Sun, 20 Mar 2022 07:21:42 -0000 Subject: [Python-checkins] [3.10] bpo-47040: improve document of checksum functions (GH-31955) (GH-32002) Message-ID: https://github.com/python/cpython/commit/73f4b475d1d70c9ef0db9e6c79771d1a43d43a33 commit: 73f4b475d1d70c9ef0db9e6c79771d1a43d43a33 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-20T00:21:34-07:00 summary: [3.10] bpo-47040: improve document of checksum functions (GH-31955) (GH-32002) Clarifies a versionchanged note on crc32 & adler32 docs that the workaround is only needed for Python 2 and earlier. Also cleans up an unnecessary intermediate variable in the implementation. Authored-By: Ma Lin / animalize Co-authored-by: Gregory P. Smith (cherry picked from commit 6d290d5862375799e997f1192ef56abca4e9182e) Co-authored-by: Ma Lin files: M Doc/library/binascii.rst M Doc/library/zlib.rst diff --git a/Doc/library/binascii.rst b/Doc/library/binascii.rst index 2c0c1bce5d7f8..5cd058c0b6d74 100644 --- a/Doc/library/binascii.rst +++ b/Doc/library/binascii.rst @@ -135,7 +135,7 @@ The :mod:`binascii` module defines the following functions: .. function:: crc32(data[, value]) - Compute CRC-32, the 32-bit checksum of *data*, starting with an + Compute CRC-32, the unsigned 32-bit checksum of *data*, starting with an initial CRC of *value*. The default initial CRC is zero. The algorithm is consistent with the ZIP file checksum. Since the algorithm is designed for use as a checksum algorithm, it is not suitable for use as a general hash @@ -149,9 +149,8 @@ The :mod:`binascii` module defines the following functions: .. versionchanged:: 3.0 The result is always unsigned. - To generate the same numeric value across all Python versions and - platforms, use ``crc32(data) & 0xffffffff``. - + To generate the same numeric value when using Python 2 or earlier, + use ``crc32(data) & 0xffffffff``. .. function:: b2a_hex(data[, sep[, bytes_per_sep=1]]) hexlify(data[, sep[, bytes_per_sep=1]]) diff --git a/Doc/library/zlib.rst b/Doc/library/zlib.rst index ec60ea24db662..6758c615d74db 100644 --- a/Doc/library/zlib.rst +++ b/Doc/library/zlib.rst @@ -42,10 +42,9 @@ The available exception and functions in this module are: for use as a general hash algorithm. .. versionchanged:: 3.0 - Always returns an unsigned value. - To generate the same numeric value across all Python versions and - platforms, use ``adler32(data) & 0xffffffff``. - + The result is always unsigned. + To generate the same numeric value when using Python 2 or earlier, + use ``adler32(data) & 0xffffffff``. .. function:: compress(data, /, level=-1) @@ -127,10 +126,9 @@ The available exception and functions in this module are: for use as a general hash algorithm. .. versionchanged:: 3.0 - Always returns an unsigned value. - To generate the same numeric value across all Python versions and - platforms, use ``crc32(data) & 0xffffffff``. - + The result is always unsigned. + To generate the same numeric value when using Python 2 or earlier, + use ``crc32(data) & 0xffffffff``. .. function:: decompress(data, /, wbits=MAX_WBITS, bufsize=DEF_BUF_SIZE) From webhook-mailer at python.org Sun Mar 20 05:58:17 2022 From: webhook-mailer at python.org (iritkatriel) Date: Sun, 20 Mar 2022 09:58:17 -0000 Subject: [Python-checkins] bpo-46013: Fix confusing kerning on period in docs (GH-29989) Message-ID: https://github.com/python/cpython/commit/3af68fc77c528d4e7749046cf6e41fd79902e6e6 commit: 3af68fc77c528d4e7749046cf6e41fd79902e6e6 branch: main author: jmcb committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-03-20T09:58:13Z summary: bpo-46013: Fix confusing kerning on period in docs (GH-29989) files: M Doc/reference/datamodel.rst diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 0bcb9dc94f58a..804332ffab6fd 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1501,7 +1501,7 @@ Basic customization Called by built-in function :func:`hash` and for operations on members of hashed collections including :class:`set`, :class:`frozenset`, and - :class:`dict`. :meth:`__hash__` should return an integer. The only required + :class:`dict`. The ``__hash__()`` method should return an integer. The only required property is that objects which compare equal have the same hash value; it is advised to mix together the hash values of the components of the object that also play a part in comparison of objects by packing them into a tuple and From webhook-mailer at python.org Sun Mar 20 08:17:34 2022 From: webhook-mailer at python.org (iritkatriel) Date: Sun, 20 Mar 2022 12:17:34 -0000 Subject: [Python-checkins] bpo-46013: Fix confusing kerning on period in docs (GH-29989) (GH-32005) Message-ID: https://github.com/python/cpython/commit/87b3e202d46cdeb0a6b1ef041579a5ebc7c826a9 commit: 87b3e202d46cdeb0a6b1ef041579a5ebc7c826a9 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-03-20T12:17:19Z summary: bpo-46013: Fix confusing kerning on period in docs (GH-29989) (GH-32005) (cherry picked from commit 3af68fc77c528d4e7749046cf6e41fd79902e6e6) Co-authored-by: jmcb Co-authored-by: jmcb files: M Doc/reference/datamodel.rst diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 55ac99c392755..3c32210a6ac7b 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1466,7 +1466,7 @@ Basic customization Called by built-in function :func:`hash` and for operations on members of hashed collections including :class:`set`, :class:`frozenset`, and - :class:`dict`. :meth:`__hash__` should return an integer. The only required + :class:`dict`. The ``__hash__()`` method should return an integer. The only required property is that objects which compare equal have the same hash value; it is advised to mix together the hash values of the components of the object that also play a part in comparison of objects by packing them into a tuple and From webhook-mailer at python.org Sun Mar 20 08:18:06 2022 From: webhook-mailer at python.org (iritkatriel) Date: Sun, 20 Mar 2022 12:18:06 -0000 Subject: [Python-checkins] bpo-46013: Fix confusing kerning on period in docs (GH-29989) (GH-32006) Message-ID: https://github.com/python/cpython/commit/504973a13336d8a4d20459f68de9647a1fb25966 commit: 504973a13336d8a4d20459f68de9647a1fb25966 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-03-20T12:18:02Z summary: bpo-46013: Fix confusing kerning on period in docs (GH-29989) (GH-32006) (cherry picked from commit 3af68fc77c528d4e7749046cf6e41fd79902e6e6) Co-authored-by: jmcb Co-authored-by: jmcb files: M Doc/reference/datamodel.rst diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index f4320db60c92a..84320f41f6cae 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1435,7 +1435,7 @@ Basic customization Called by built-in function :func:`hash` and for operations on members of hashed collections including :class:`set`, :class:`frozenset`, and - :class:`dict`. :meth:`__hash__` should return an integer. The only required + :class:`dict`. The ``__hash__()`` method should return an integer. The only required property is that objects which compare equal have the same hash value; it is advised to mix together the hash values of the components of the object that also play a part in comparison of objects by packing them into a tuple and From webhook-mailer at python.org Sun Mar 20 10:26:24 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Sun, 20 Mar 2022 14:26:24 -0000 Subject: [Python-checkins] bpo-42369: Fix thread safety of zipfile._SharedFile.tell (GH-26974) Message-ID: https://github.com/python/cpython/commit/e730ae7effe4f13b24f1b5fb1fca005709c86acb commit: e730ae7effe4f13b24f1b5fb1fca005709c86acb branch: main author: Kevin Mehall committer: serhiy-storchaka date: 2022-03-20T16:26:09+02:00 summary: bpo-42369: Fix thread safety of zipfile._SharedFile.tell (GH-26974) The `_SharedFile` tracks its own virtual position into the file as `self._pos` and updates it after reading or seeking. `tell()` should return this position instead of calling into the underlying file object, since if multiple `_SharedFile` instances are being used concurrently on the same file, another one may have moved the real file position. Additionally, calling into the underlying `tell` may expose thread safety issues in the underlying file object because it was called without taking the lock. files: A Misc/NEWS.d/next/Library/2022-03-19-19-56-04.bpo-42369.Ok828t.rst M Lib/zipfile.py diff --git a/Lib/zipfile.py b/Lib/zipfile.py index 41bf49a8fe685..385adc897317f 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -747,7 +747,9 @@ def __init__(self, file, pos, close, lock, writing): self._lock = lock self._writing = writing self.seekable = file.seekable - self.tell = file.tell + + def tell(self): + return self._pos def seek(self, offset, whence=0): with self._lock: diff --git a/Misc/NEWS.d/next/Library/2022-03-19-19-56-04.bpo-42369.Ok828t.rst b/Misc/NEWS.d/next/Library/2022-03-19-19-56-04.bpo-42369.Ok828t.rst new file mode 100644 index 0000000000000..86dc3a0b81b9c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-19-19-56-04.bpo-42369.Ok828t.rst @@ -0,0 +1 @@ +Fix thread safety of :meth:`zipfile._SharedFile.tell` to avoid a "zipfile.BadZipFile: Bad CRC-32 for file" exception when reading a :class:`ZipFile` from multiple threads. From webhook-mailer at python.org Sun Mar 20 10:39:34 2022 From: webhook-mailer at python.org (asvetlov) Date: Sun, 20 Mar 2022 14:39:34 -0000 Subject: [Python-checkins] bpo-47015: Update test_os from asyncore to asyncio (GH-31876) Message-ID: https://github.com/python/cpython/commit/3ae975f1ac880c47d51cca6c9e305547bd365be7 commit: 3ae975f1ac880c47d51cca6c9e305547bd365be7 branch: main author: Oleg Iarygin committer: asvetlov date: 2022-03-20T16:39:12+02:00 summary: bpo-47015: Update test_os from asyncore to asyncio (GH-31876) files: A Misc/NEWS.d/next/Tests/2022-03-13-23-43-40.bpo-47015.FjmCsz.rst M Lib/test/test_os.py diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 426d2ae9373bc..9a60bf5f7fdd5 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -2,6 +2,7 @@ # does add tests for a few functions which have been determined to be more # portable than they had been thought to be. +import asyncio import codecs import contextlib import decimal @@ -23,7 +24,6 @@ import sys import sysconfig import tempfile -import threading import time import types import unittest @@ -33,15 +33,9 @@ from test.support import import_helper from test.support import os_helper from test.support import socket_helper -from test.support import threading_helper from test.support import warnings_helper from platform import win32_is_iot -with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - import asynchat - import asyncore - try: import resource except ImportError: @@ -101,6 +95,10 @@ def create_file(filename, content=b'content'): 'on AIX, splice() only accepts sockets') +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + class MiscTests(unittest.TestCase): def test_getcwd(self): cwd = os.getcwd() @@ -3228,94 +3226,8 @@ def test_set_get_priority(self): raise -class SendfileTestServer(asyncore.dispatcher, threading.Thread): - - class Handler(asynchat.async_chat): - - def __init__(self, conn): - asynchat.async_chat.__init__(self, conn) - self.in_buffer = [] - self.accumulate = True - self.closed = False - self.push(b"220 ready\r\n") - - def handle_read(self): - data = self.recv(4096) - if self.accumulate: - self.in_buffer.append(data) - - def get_data(self): - return b''.join(self.in_buffer) - - def handle_close(self): - self.close() - self.closed = True - - def handle_error(self): - raise - - def __init__(self, address): - threading.Thread.__init__(self) - asyncore.dispatcher.__init__(self) - self.create_socket(socket.AF_INET, socket.SOCK_STREAM) - self.bind(address) - self.listen(5) - self.host, self.port = self.socket.getsockname()[:2] - self.handler_instance = None - self._active = False - self._active_lock = threading.Lock() - - # --- public API - - @property - def running(self): - return self._active - - def start(self): - assert not self.running - self.__flag = threading.Event() - threading.Thread.start(self) - self.__flag.wait() - - def stop(self): - assert self.running - self._active = False - self.join() - - def wait(self): - # wait for handler connection to be closed, then stop the server - while not getattr(self.handler_instance, "closed", False): - time.sleep(0.001) - self.stop() - - # --- internals - - def run(self): - self._active = True - self.__flag.set() - while self._active and asyncore.socket_map: - self._active_lock.acquire() - asyncore.loop(timeout=0.001, count=1) - self._active_lock.release() - asyncore.close_all() - - def handle_accept(self): - conn, addr = self.accept() - self.handler_instance = self.Handler(conn) - - def handle_connect(self): - self.close() - handle_read = handle_connect - - def writable(self): - return 0 - - def handle_error(self): - raise - - @unittest.skipUnless(hasattr(os, 'sendfile'), "test needs os.sendfile()") -class TestSendfile(unittest.TestCase): +class TestSendfile(unittest.IsolatedAsyncioTestCase): DATA = b"12345abcde" * 16 * 1024 # 160 KiB SUPPORT_HEADERS_TRAILERS = not sys.platform.startswith("linux") and \ @@ -3328,40 +3240,52 @@ class TestSendfile(unittest.TestCase): @classmethod def setUpClass(cls): - cls.key = threading_helper.threading_setup() create_file(os_helper.TESTFN, cls.DATA) @classmethod def tearDownClass(cls): - threading_helper.threading_cleanup(*cls.key) os_helper.unlink(os_helper.TESTFN) - def setUp(self): - self.server = SendfileTestServer((socket_helper.HOST, 0)) - self.server.start() + @staticmethod + async def chunks(reader): + while not reader.at_eof(): + yield await reader.read() + + async def handle_new_client(self, reader, writer): + self.server_buffer = b''.join([x async for x in self.chunks(reader)]) + writer.close() + self.server.close() # The test server processes a single client only + + async def asyncSetUp(self): + self.server_buffer = b'' + self.server = await asyncio.start_server(self.handle_new_client, + socket_helper.HOSTv4) + server_name = self.server.sockets[0].getsockname() self.client = socket.socket() - self.client.connect((self.server.host, self.server.port)) - self.client.settimeout(1) - # synchronize by waiting for "220 ready" response - self.client.recv(1024) + self.client.setblocking(False) + await asyncio.get_running_loop().sock_connect(self.client, server_name) self.sockno = self.client.fileno() self.file = open(os_helper.TESTFN, 'rb') self.fileno = self.file.fileno() - def tearDown(self): + async def asyncTearDown(self): self.file.close() self.client.close() - if self.server.running: - self.server.stop() - self.server = None + await self.server.wait_closed() + + # Use the test subject instead of asyncio.loop.sendfile + @staticmethod + async def async_sendfile(*args, **kwargs): + return await asyncio.to_thread(os.sendfile, *args, **kwargs) - def sendfile_wrapper(self, *args, **kwargs): + @staticmethod + async def sendfile_wrapper(*args, **kwargs): """A higher level wrapper representing how an application is supposed to use sendfile(). """ while True: try: - return os.sendfile(*args, **kwargs) + return await TestSendfile.async_sendfile(*args, **kwargs) except OSError as err: if err.errno == errno.ECONNRESET: # disconnected @@ -3372,13 +3296,14 @@ def sendfile_wrapper(self, *args, **kwargs): else: raise - def test_send_whole_file(self): + async def test_send_whole_file(self): # normal send total_sent = 0 offset = 0 nbytes = 4096 while total_sent < len(self.DATA): - sent = self.sendfile_wrapper(self.sockno, self.fileno, offset, nbytes) + sent = await self.sendfile_wrapper(self.sockno, self.fileno, + offset, nbytes) if sent == 0: break offset += sent @@ -3389,19 +3314,19 @@ def test_send_whole_file(self): self.assertEqual(total_sent, len(self.DATA)) self.client.shutdown(socket.SHUT_RDWR) self.client.close() - self.server.wait() - data = self.server.handler_instance.get_data() - self.assertEqual(len(data), len(self.DATA)) - self.assertEqual(data, self.DATA) + await self.server.wait_closed() + self.assertEqual(len(self.server_buffer), len(self.DATA)) + self.assertEqual(self.server_buffer, self.DATA) - def test_send_at_certain_offset(self): + async def test_send_at_certain_offset(self): # start sending a file at a certain offset total_sent = 0 offset = len(self.DATA) // 2 must_send = len(self.DATA) - offset nbytes = 4096 while total_sent < must_send: - sent = self.sendfile_wrapper(self.sockno, self.fileno, offset, nbytes) + sent = await self.sendfile_wrapper(self.sockno, self.fileno, + offset, nbytes) if sent == 0: break offset += sent @@ -3410,18 +3335,18 @@ def test_send_at_certain_offset(self): self.client.shutdown(socket.SHUT_RDWR) self.client.close() - self.server.wait() - data = self.server.handler_instance.get_data() + await self.server.wait_closed() expected = self.DATA[len(self.DATA) // 2:] self.assertEqual(total_sent, len(expected)) - self.assertEqual(len(data), len(expected)) - self.assertEqual(data, expected) + self.assertEqual(len(self.server_buffer), len(expected)) + self.assertEqual(self.server_buffer, expected) - def test_offset_overflow(self): + async def test_offset_overflow(self): # specify an offset > file size offset = len(self.DATA) + 4096 try: - sent = os.sendfile(self.sockno, self.fileno, offset, 4096) + sent = await self.async_sendfile(self.sockno, self.fileno, + offset, 4096) except OSError as e: # Solaris can raise EINVAL if offset >= file length, ignore. if e.errno != errno.EINVAL: @@ -3430,39 +3355,38 @@ def test_offset_overflow(self): self.assertEqual(sent, 0) self.client.shutdown(socket.SHUT_RDWR) self.client.close() - self.server.wait() - data = self.server.handler_instance.get_data() - self.assertEqual(data, b'') + await self.server.wait_closed() + self.assertEqual(self.server_buffer, b'') - def test_invalid_offset(self): + async def test_invalid_offset(self): with self.assertRaises(OSError) as cm: - os.sendfile(self.sockno, self.fileno, -1, 4096) + await self.async_sendfile(self.sockno, self.fileno, -1, 4096) self.assertEqual(cm.exception.errno, errno.EINVAL) - def test_keywords(self): + async def test_keywords(self): # Keyword arguments should be supported - os.sendfile(out_fd=self.sockno, in_fd=self.fileno, - offset=0, count=4096) + await self.async_sendfile(out_fd=self.sockno, in_fd=self.fileno, + offset=0, count=4096) if self.SUPPORT_HEADERS_TRAILERS: - os.sendfile(out_fd=self.sockno, in_fd=self.fileno, - offset=0, count=4096, - headers=(), trailers=(), flags=0) + await self.async_sendfile(out_fd=self.sockno, in_fd=self.fileno, + offset=0, count=4096, + headers=(), trailers=(), flags=0) # --- headers / trailers tests @requires_headers_trailers - def test_headers(self): + async def test_headers(self): total_sent = 0 expected_data = b"x" * 512 + b"y" * 256 + self.DATA[:-1] - sent = os.sendfile(self.sockno, self.fileno, 0, 4096, - headers=[b"x" * 512, b"y" * 256]) + sent = await self.async_sendfile(self.sockno, self.fileno, 0, 4096, + headers=[b"x" * 512, b"y" * 256]) self.assertLessEqual(sent, 512 + 256 + 4096) total_sent += sent offset = 4096 while total_sent < len(expected_data): nbytes = min(len(expected_data) - total_sent, 4096) - sent = self.sendfile_wrapper(self.sockno, self.fileno, - offset, nbytes) + sent = await self.sendfile_wrapper(self.sockno, self.fileno, + offset, nbytes) if sent == 0: break self.assertLessEqual(sent, nbytes) @@ -3471,12 +3395,11 @@ def test_headers(self): self.assertEqual(total_sent, len(expected_data)) self.client.close() - self.server.wait() - data = self.server.handler_instance.get_data() - self.assertEqual(hash(data), hash(expected_data)) + await self.server.wait_closed() + self.assertEqual(hash(self.server_buffer), hash(expected_data)) @requires_headers_trailers - def test_trailers(self): + async def test_trailers(self): TESTFN2 = os_helper.TESTFN + "2" file_data = b"abcdef" @@ -3484,38 +3407,37 @@ def test_trailers(self): create_file(TESTFN2, file_data) with open(TESTFN2, 'rb') as f: - os.sendfile(self.sockno, f.fileno(), 0, 5, - trailers=[b"123456", b"789"]) + await self.async_sendfile(self.sockno, f.fileno(), 0, 5, + trailers=[b"123456", b"789"]) self.client.close() - self.server.wait() - data = self.server.handler_instance.get_data() - self.assertEqual(data, b"abcde123456789") + await self.server.wait_closed() + self.assertEqual(self.server_buffer, b"abcde123456789") @requires_headers_trailers @requires_32b - def test_headers_overflow_32bits(self): + async def test_headers_overflow_32bits(self): self.server.handler_instance.accumulate = False with self.assertRaises(OSError) as cm: - os.sendfile(self.sockno, self.fileno, 0, 0, - headers=[b"x" * 2**16] * 2**15) + await self.async_sendfile(self.sockno, self.fileno, 0, 0, + headers=[b"x" * 2**16] * 2**15) self.assertEqual(cm.exception.errno, errno.EINVAL) @requires_headers_trailers @requires_32b - def test_trailers_overflow_32bits(self): + async def test_trailers_overflow_32bits(self): self.server.handler_instance.accumulate = False with self.assertRaises(OSError) as cm: - os.sendfile(self.sockno, self.fileno, 0, 0, - trailers=[b"x" * 2**16] * 2**15) + await self.async_sendfile(self.sockno, self.fileno, 0, 0, + trailers=[b"x" * 2**16] * 2**15) self.assertEqual(cm.exception.errno, errno.EINVAL) @requires_headers_trailers @unittest.skipUnless(hasattr(os, 'SF_NODISKIO'), 'test needs os.SF_NODISKIO') - def test_flags(self): + async def test_flags(self): try: - os.sendfile(self.sockno, self.fileno, 0, 4096, - flags=os.SF_NODISKIO) + await self.async_sendfile(self.sockno, self.fileno, 0, 4096, + flags=os.SF_NODISKIO) except OSError as err: if err.errno not in (errno.EBUSY, errno.EAGAIN): raise diff --git a/Misc/NEWS.d/next/Tests/2022-03-13-23-43-40.bpo-47015.FjmCsz.rst b/Misc/NEWS.d/next/Tests/2022-03-13-23-43-40.bpo-47015.FjmCsz.rst new file mode 100644 index 0000000000000..12c527ad1f23b --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2022-03-13-23-43-40.bpo-47015.FjmCsz.rst @@ -0,0 +1,2 @@ +A test case for :func:`os.sendfile` is converted from deprecated +:mod:`asyncore` (see :pep:`594`) to :mod:`asyncio`. Patch by Oleg Iarygin. From webhook-mailer at python.org Sun Mar 20 10:51:23 2022 From: webhook-mailer at python.org (miss-islington) Date: Sun, 20 Mar 2022 14:51:23 -0000 Subject: [Python-checkins] bpo-42369: Fix thread safety of zipfile._SharedFile.tell (GH-26974) Message-ID: https://github.com/python/cpython/commit/4352ca234e979ad1c7158981addf899b119cd448 commit: 4352ca234e979ad1c7158981addf899b119cd448 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-20T07:51:11-07:00 summary: bpo-42369: Fix thread safety of zipfile._SharedFile.tell (GH-26974) The `_SharedFile` tracks its own virtual position into the file as `self._pos` and updates it after reading or seeking. `tell()` should return this position instead of calling into the underlying file object, since if multiple `_SharedFile` instances are being used concurrently on the same file, another one may have moved the real file position. Additionally, calling into the underlying `tell` may expose thread safety issues in the underlying file object because it was called without taking the lock. (cherry picked from commit e730ae7effe4f13b24f1b5fb1fca005709c86acb) Co-authored-by: Kevin Mehall files: A Misc/NEWS.d/next/Library/2022-03-19-19-56-04.bpo-42369.Ok828t.rst M Lib/zipfile.py diff --git a/Lib/zipfile.py b/Lib/zipfile.py index 67cfdfb6aafc4..34d2fa4b86422 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -721,7 +721,9 @@ def __init__(self, file, pos, close, lock, writing): self._lock = lock self._writing = writing self.seekable = file.seekable - self.tell = file.tell + + def tell(self): + return self._pos def seek(self, offset, whence=0): with self._lock: diff --git a/Misc/NEWS.d/next/Library/2022-03-19-19-56-04.bpo-42369.Ok828t.rst b/Misc/NEWS.d/next/Library/2022-03-19-19-56-04.bpo-42369.Ok828t.rst new file mode 100644 index 0000000000000..86dc3a0b81b9c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-19-19-56-04.bpo-42369.Ok828t.rst @@ -0,0 +1 @@ +Fix thread safety of :meth:`zipfile._SharedFile.tell` to avoid a "zipfile.BadZipFile: Bad CRC-32 for file" exception when reading a :class:`ZipFile` from multiple threads. From webhook-mailer at python.org Sun Mar 20 10:54:39 2022 From: webhook-mailer at python.org (miss-islington) Date: Sun, 20 Mar 2022 14:54:39 -0000 Subject: [Python-checkins] bpo-42369: Fix thread safety of zipfile._SharedFile.tell (GH-26974) Message-ID: https://github.com/python/cpython/commit/4aa8b802513340d12a6ffea3d5e2228ac6c7d5b8 commit: 4aa8b802513340d12a6ffea3d5e2228ac6c7d5b8 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-20T07:54:19-07:00 summary: bpo-42369: Fix thread safety of zipfile._SharedFile.tell (GH-26974) The `_SharedFile` tracks its own virtual position into the file as `self._pos` and updates it after reading or seeking. `tell()` should return this position instead of calling into the underlying file object, since if multiple `_SharedFile` instances are being used concurrently on the same file, another one may have moved the real file position. Additionally, calling into the underlying `tell` may expose thread safety issues in the underlying file object because it was called without taking the lock. (cherry picked from commit e730ae7effe4f13b24f1b5fb1fca005709c86acb) Co-authored-by: Kevin Mehall files: A Misc/NEWS.d/next/Library/2022-03-19-19-56-04.bpo-42369.Ok828t.rst M Lib/zipfile.py diff --git a/Lib/zipfile.py b/Lib/zipfile.py index f72c6a4e0c253..1e942a503e8ee 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -720,7 +720,9 @@ def __init__(self, file, pos, close, lock, writing): self._lock = lock self._writing = writing self.seekable = file.seekable - self.tell = file.tell + + def tell(self): + return self._pos def seek(self, offset, whence=0): with self._lock: diff --git a/Misc/NEWS.d/next/Library/2022-03-19-19-56-04.bpo-42369.Ok828t.rst b/Misc/NEWS.d/next/Library/2022-03-19-19-56-04.bpo-42369.Ok828t.rst new file mode 100644 index 0000000000000..86dc3a0b81b9c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-19-19-56-04.bpo-42369.Ok828t.rst @@ -0,0 +1 @@ +Fix thread safety of :meth:`zipfile._SharedFile.tell` to avoid a "zipfile.BadZipFile: Bad CRC-32 for file" exception when reading a :class:`ZipFile` from multiple threads. From webhook-mailer at python.org Sun Mar 20 15:28:40 2022 From: webhook-mailer at python.org (gpshead) Date: Sun, 20 Mar 2022 19:28:40 -0000 Subject: [Python-checkins] bpo-38256: Fix binascii.crc32() when inputs are 4+GiB (GH-32000) Message-ID: https://github.com/python/cpython/commit/9d1c4d69dbc800ac344565119337fcf490cdc800 commit: 9d1c4d69dbc800ac344565119337fcf490cdc800 branch: main author: Gregory P. Smith committer: gpshead date: 2022-03-20T12:28:15-07:00 summary: bpo-38256: Fix binascii.crc32() when inputs are 4+GiB (GH-32000) When compiled with `USE_ZLIB_CRC32` defined (`configure` sets this on POSIX systems), `binascii.crc32(...)` failed to compute the correct value when the input data was >= 4GiB. Because the zlib crc32 API is limited to a 32-bit length. This lines it up with the `zlib.crc32(...)` implementation that doesn't have that flaw. **Performance:** This also adopts the same GIL releasing for larger inputs logic that `zlib.crc32` has, and causes the Windows build to always use zlib's crc32 instead of our slow C code as zlib is a required build dependency on Windows. files: A Misc/NEWS.d/next/Library/2022-03-19-15-54-41.bpo-38256.FoMbjE.rst M Lib/test/test_binascii.py M Modules/binascii.c M Modules/clinic/zlibmodule.c.h M Modules/zlibmodule.c M PCbuild/pythoncore.vcxproj diff --git a/Lib/test/test_binascii.py b/Lib/test/test_binascii.py index b5aa847b943e6..7087d7a471d3f 100644 --- a/Lib/test/test_binascii.py +++ b/Lib/test/test_binascii.py @@ -4,7 +4,7 @@ import binascii import array import re -from test.support import warnings_helper +from test.support import bigmemtest, _1G, _4G, warnings_helper # Note: "*_hex" functions are aliases for "(un)hexlify" @@ -441,6 +441,14 @@ class BytearrayBinASCIITest(BinASCIITest): class MemoryviewBinASCIITest(BinASCIITest): type2test = memoryview +class ChecksumBigBufferTestCase(unittest.TestCase): + """bpo-38256 - check that inputs >=4 GiB are handled correctly.""" + + @bigmemtest(size=_4G + 4, memuse=1, dry_run=False) + def test_big_buffer(self, size): + data = b"nyan" * (_1G + 1) + self.assertEqual(binascii.crc32(data), 1044521549) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2022-03-19-15-54-41.bpo-38256.FoMbjE.rst b/Misc/NEWS.d/next/Library/2022-03-19-15-54-41.bpo-38256.FoMbjE.rst new file mode 100644 index 0000000000000..ea1763fca4138 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-19-15-54-41.bpo-38256.FoMbjE.rst @@ -0,0 +1,14 @@ +Fix :func:`binascii.crc32` when it is compiled to use zlib'c crc32 to +work properly on inputs 4+GiB in length instead of returning the wrong +result. The workaround prior to this was to always feed the function +data in increments smaller than 4GiB or to just call the zlib module +function. + +We also have :func:`binascii.crc32` release the GIL when computing +on larger inputs as :func:`zlib.crc32` and :mod:`hashlib` do. + +This also boosts performance on Windows as it now uses the zlib crc32 +implementation for :func:`binascii.crc32` for a 2-3x speedup. + +That the stdlib has a crc32 API in two modules is a known historical +oddity. This moves us closer to a single implementation behind them. diff --git a/Modules/binascii.c b/Modules/binascii.c index fec0d82a39cdd..afe4988549171 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -737,6 +737,21 @@ static const unsigned int crc_32_tab[256] = { 0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, 0x2d02ef8dU }; + +static unsigned int +internal_crc32(const unsigned char *bin_data, Py_ssize_t len, unsigned int crc) +{ /* By Jim Ahlstrom; All rights transferred to CNRI */ + unsigned int result; + + crc = ~ crc; + while (len-- > 0) { + crc = crc_32_tab[(crc ^ *bin_data++) & 0xff] ^ (crc >> 8); + /* Note: (crc >> 8) MUST zero fill on left */ + } + + result = (crc ^ 0xFFFFFFFF); + return result & 0xffffffff; +} #endif /* USE_ZLIB_CRC32 */ /*[clinic input] @@ -754,34 +769,46 @@ binascii_crc32_impl(PyObject *module, Py_buffer *data, unsigned int crc) /*[clinic end generated code: output=52cf59056a78593b input=bbe340bc99d25aa8]*/ #ifdef USE_ZLIB_CRC32 -/* This was taken from zlibmodule.c PyZlib_crc32 (but is PY_SSIZE_T_CLEAN) */ +/* This is the same as zlibmodule.c zlib_crc32_impl. It exists in two + * modules for historical reasons. */ { - const Byte *buf; - Py_ssize_t len; - int signed_val; - - buf = (Byte*)data->buf; - len = data->len; - signed_val = crc32(crc, buf, len); - return (unsigned int)signed_val & 0xffffffffU; + /* Releasing the GIL for very small buffers is inefficient + and may lower performance */ + if (data->len > 1024*5) { + unsigned char *buf = data->buf; + Py_ssize_t len = data->len; + + Py_BEGIN_ALLOW_THREADS + /* Avoid truncation of length for very large buffers. crc32() takes + length as an unsigned int, which may be narrower than Py_ssize_t. */ + while ((size_t)len > UINT_MAX) { + crc = crc32(crc, buf, UINT_MAX); + buf += (size_t) UINT_MAX; + len -= (size_t) UINT_MAX; + } + crc = crc32(crc, buf, (unsigned int)len); + Py_END_ALLOW_THREADS + } else { + crc = crc32(crc, data->buf, (unsigned int)data->len); + } + return crc & 0xffffffff; } #else /* USE_ZLIB_CRC32 */ -{ /* By Jim Ahlstrom; All rights transferred to CNRI */ - const unsigned char *bin_data; - Py_ssize_t len; - unsigned int result; - - bin_data = data->buf; - len = data->len; - - crc = ~ crc; - while (len-- > 0) { - crc = crc_32_tab[(crc ^ *bin_data++) & 0xff] ^ (crc >> 8); - /* Note: (crc >> 8) MUST zero fill on left */ +{ + const unsigned char *bin_data = data->buf; + Py_ssize_t len = data->len; + + /* Releasing the GIL for very small buffers is inefficient + and may lower performance */ + if (len > 1024*5) { + unsigned int result; + Py_BEGIN_ALLOW_THREADS + result = internal_crc32(bin_data, len, crc); + Py_END_ALLOW_THREADS + return result; + } else { + return internal_crc32(bin_data, len, crc); } - - result = (crc ^ 0xFFFFFFFF); - return result & 0xffffffff; } #endif /* USE_ZLIB_CRC32 */ diff --git a/Modules/clinic/zlibmodule.c.h b/Modules/clinic/zlibmodule.c.h index e2a5fccd36c54..71136d31db0e0 100644 --- a/Modules/clinic/zlibmodule.c.h +++ b/Modules/clinic/zlibmodule.c.h @@ -753,7 +753,7 @@ PyDoc_STRVAR(zlib_crc32__doc__, #define ZLIB_CRC32_METHODDEF \ {"crc32", (PyCFunction)(void(*)(void))zlib_crc32, METH_FASTCALL, zlib_crc32__doc__}, -static PyObject * +static unsigned int zlib_crc32_impl(PyObject *module, Py_buffer *data, unsigned int value); static PyObject * @@ -762,6 +762,7 @@ zlib_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) PyObject *return_value = NULL; Py_buffer data = {NULL, NULL}; unsigned int value = 0; + unsigned int _return_value; if (!_PyArg_CheckPositional("crc32", nargs, 1, 2)) { goto exit; @@ -781,7 +782,11 @@ zlib_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } skip_optional: - return_value = zlib_crc32_impl(module, &data, value); + _return_value = zlib_crc32_impl(module, &data, value); + if ((_return_value == (unsigned int)-1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromUnsignedLong((unsigned long)_return_value); exit: /* Cleanup for data */ @@ -815,4 +820,4 @@ zlib_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) #ifndef ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF #define ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF #endif /* !defined(ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF) */ -/*[clinic end generated code: output=e3e8a6142ea045a7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f009d194565416d1 input=a9049054013a1b77]*/ diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c index 4cf1b6eeba2f7..2fc39a3bd5620 100644 --- a/Modules/zlibmodule.c +++ b/Modules/zlibmodule.c @@ -1420,7 +1420,7 @@ zlib_adler32_impl(PyObject *module, Py_buffer *data, unsigned int value) } /*[clinic input] -zlib.crc32 +zlib.crc32 -> unsigned_int data: Py_buffer value: unsigned_int(bitwise=True) = 0 @@ -1432,9 +1432,9 @@ Compute a CRC-32 checksum of data. The returned checksum is an integer. [clinic start generated code]*/ -static PyObject * +static unsigned int zlib_crc32_impl(PyObject *module, Py_buffer *data, unsigned int value) -/*[clinic end generated code: output=63499fa20af7ea25 input=26c3ed430fa00b4c]*/ +/*[clinic end generated code: output=b217562e4fe6d6a6 input=1229cb2fb5ea948a]*/ { /* Releasing the GIL for very small buffers is inefficient and may lower performance */ @@ -1455,7 +1455,7 @@ zlib_crc32_impl(PyObject *module, Py_buffer *data, unsigned int value) } else { value = crc32(value, data->buf, (unsigned int)data->len); } - return PyLong_FromUnsignedLong(value & 0xffffffffU); + return value; } diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 3686233a1ad50..5e6e703df9123 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -366,7 +366,9 @@ - + + USE_ZLIB_CRC32;%(PreprocessorDefinitions) + From webhook-mailer at python.org Sun Mar 20 16:38:10 2022 From: webhook-mailer at python.org (asvetlov) Date: Sun, 20 Mar 2022 20:38:10 -0000 Subject: [Python-checkins] [3.10] bpo-47022: Document asynchat, asyncore and smtpd removals in 3.12 (GH-31891) (#31997) Message-ID: https://github.com/python/cpython/commit/94f038cbb27dc6d1a74ae2bfedea674911f8e8c6 commit: 94f038cbb27dc6d1a74ae2bfedea674911f8e8c6 branch: 3.10 author: Hugo van Kemenade committer: asvetlov date: 2022-03-20T22:38:01+02:00 summary: [3.10] bpo-47022: Document asynchat, asyncore and smtpd removals in 3.12 (GH-31891) (#31997) Document the deprecation of asyncore, asynchat, and smtpd with a slated removal in Python 3.12 thanks to PEP 594.. (cherry picked from commit 77473846439b8a3eae66de1a1cfe931619f38513) Co-authored-by: Hugo van Kemenade files: A Misc/NEWS.d/next/Library/2022-03-15-09-29-52.bpo-47022.uaEDcI.rst M Doc/library/asynchat.rst M Doc/library/asyncore.rst M Doc/library/smtpd.rst M Doc/library/superseded.rst M Lib/asynchat.py M Lib/asyncore.py M Lib/smtpd.py diff --git a/Doc/library/asynchat.rst b/Doc/library/asynchat.rst index 9e51416b83a57..4354444a1d331 100644 --- a/Doc/library/asynchat.rst +++ b/Doc/library/asynchat.rst @@ -3,6 +3,7 @@ .. module:: asynchat :synopsis: Support for asynchronous command/response protocols. + :deprecated: .. moduleauthor:: Sam Rushing .. sectionauthor:: Steve Holden @@ -10,6 +11,7 @@ **Source code:** :source:`Lib/asynchat.py` .. deprecated:: 3.6 + :mod:`asynchat` will be removed in Python 3.12 (:pep:`594`). Please use :mod:`asyncio` instead. -------------- diff --git a/Doc/library/asyncore.rst b/Doc/library/asyncore.rst index a86518ebff277..e481e13db76f7 100644 --- a/Doc/library/asyncore.rst +++ b/Doc/library/asyncore.rst @@ -4,6 +4,7 @@ .. module:: asyncore :synopsis: A base class for developing asynchronous socket handling services. + :deprecated: .. moduleauthor:: Sam Rushing .. sectionauthor:: Christopher Petrilli @@ -13,6 +14,7 @@ **Source code:** :source:`Lib/asyncore.py` .. deprecated:: 3.6 + :mod:`asyncore` will be removed in Python 3.12 (:pep:`594`). Please use :mod:`asyncio` instead. -------------- diff --git a/Doc/library/smtpd.rst b/Doc/library/smtpd.rst index 803430f1bde17..a39bc024047fd 100644 --- a/Doc/library/smtpd.rst +++ b/Doc/library/smtpd.rst @@ -3,6 +3,7 @@ .. module:: smtpd :synopsis: A SMTP server implementation in Python. + :deprecated: .. moduleauthor:: Barry Warsaw .. sectionauthor:: Moshe Zadka @@ -14,6 +15,7 @@ This module offers several classes to implement SMTP (email) servers. .. deprecated:: 3.6 + :mod:`smtpd` will be removed in Python 3.12 (:pep:`594`). The `aiosmtpd `_ package is a recommended replacement for this module. It is based on :mod:`asyncio` and provides a more straightforward API. diff --git a/Doc/library/superseded.rst b/Doc/library/superseded.rst index 50a5983236e76..fd23e4d1536d3 100644 --- a/Doc/library/superseded.rst +++ b/Doc/library/superseded.rst @@ -10,5 +10,8 @@ backwards compatibility. They have been superseded by other modules. .. toctree:: - optparse.rst + asynchat.rst + asyncore.rst + smtpd.rst imp.rst + optparse.rst diff --git a/Lib/asynchat.py b/Lib/asynchat.py index de26ffa648ffe..e081e67c75acb 100644 --- a/Lib/asynchat.py +++ b/Lib/asynchat.py @@ -50,7 +50,7 @@ from warnings import warn warn( - 'The asynchat module is deprecated. ' + 'The asynchat module is deprecated and will be removed in Python 3.12. ' 'The recommended replacement is asyncio', DeprecationWarning, stacklevel=2) diff --git a/Lib/asyncore.py b/Lib/asyncore.py index b1eea4bf65211..a360d404395e5 100644 --- a/Lib/asyncore.py +++ b/Lib/asyncore.py @@ -58,7 +58,7 @@ errorcode warnings.warn( - 'The asyncore module is deprecated. ' + 'The asyncore module is deprecated and will be removed in Python 3.12. ' 'The recommended replacement is asyncio', DeprecationWarning, stacklevel=2) diff --git a/Lib/smtpd.py b/Lib/smtpd.py index bc43331251009..963e0a7689c26 100755 --- a/Lib/smtpd.py +++ b/Lib/smtpd.py @@ -93,7 +93,8 @@ ] warn( - 'The smtpd module is deprecated and unmaintained. Please see aiosmtpd ' + 'The smtpd module is deprecated and unmaintained and will be removed ' + 'in Python 3.12. Please see aiosmtpd ' '(https://aiosmtpd.readthedocs.io/) for the recommended replacement.', DeprecationWarning, stacklevel=2) diff --git a/Misc/NEWS.d/next/Library/2022-03-15-09-29-52.bpo-47022.uaEDcI.rst b/Misc/NEWS.d/next/Library/2022-03-15-09-29-52.bpo-47022.uaEDcI.rst new file mode 100644 index 0000000000000..0e867b9506484 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-15-09-29-52.bpo-47022.uaEDcI.rst @@ -0,0 +1,4 @@ +The :mod:`asynchat`, :mod:`asyncore` and :mod:`smtpd` modules have been +deprecated since at least Python 3.6. Their documentation and deprecation +warnings and have now been updated to note they will removed in Python 3.12 +(:pep:`594`). From webhook-mailer at python.org Sun Mar 20 17:47:06 2022 From: webhook-mailer at python.org (gpshead) Date: Sun, 20 Mar 2022 21:47:06 -0000 Subject: [Python-checkins] [3.10] bpo-38256: Fix binascii.crc32 large input. (GH-32000) (GH-32013) Message-ID: https://github.com/python/cpython/commit/4c989e19c84ec224655bbbde9422e16d4a838a80 commit: 4c989e19c84ec224655bbbde9422e16d4a838a80 branch: 3.10 author: Gregory P. Smith committer: gpshead date: 2022-03-20T14:46:52-07:00 summary: [3.10] bpo-38256: Fix binascii.crc32 large input. (GH-32000) (GH-32013) Inputs >= 4GiB to `binascii.crc32(...)` when compiled to use the zlib crc32 implementation (the norm on POSIX) no longer return the wrong result. files: A Misc/NEWS.d/next/Library/2022-03-19-15-54-41.bpo-38256.FoMbjE.rst M Lib/test/test_binascii.py M Modules/binascii.c diff --git a/Lib/test/test_binascii.py b/Lib/test/test_binascii.py index 4d1bf2cce1f1e..13d4e67e586e9 100644 --- a/Lib/test/test_binascii.py +++ b/Lib/test/test_binascii.py @@ -4,7 +4,7 @@ import binascii import array import re -from test.support import warnings_helper +from test.support import bigmemtest, _1G, _4G, warnings_helper # Note: "*_hex" functions are aliases for "(un)hexlify" @@ -449,6 +449,14 @@ class BytearrayBinASCIITest(BinASCIITest): class MemoryviewBinASCIITest(BinASCIITest): type2test = memoryview +class ChecksumBigBufferTestCase(unittest.TestCase): + """bpo-38256 - check that inputs >=4 GiB are handled correctly.""" + + @bigmemtest(size=_4G + 4, memuse=1, dry_run=False) + def test_big_buffer(self, size): + data = b"nyan" * (_1G + 1) + self.assertEqual(binascii.crc32(data), 1044521549) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2022-03-19-15-54-41.bpo-38256.FoMbjE.rst b/Misc/NEWS.d/next/Library/2022-03-19-15-54-41.bpo-38256.FoMbjE.rst new file mode 100644 index 0000000000000..d9b57513b0631 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-19-15-54-41.bpo-38256.FoMbjE.rst @@ -0,0 +1,5 @@ +Fix :func:`binascii.crc32` when it is compiled to use zlib'c crc32 to +work properly on inputs 4+GiB in length instead of returning the wrong +result. The workaround prior to this was to always feed the function +data in increments smaller than 4GiB or to just call the zlib module +function. diff --git a/Modules/binascii.c b/Modules/binascii.c index 1f3248b6049b3..3777580a79f2a 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -1120,16 +1120,20 @@ binascii_crc32_impl(PyObject *module, Py_buffer *data, unsigned int crc) /*[clinic end generated code: output=52cf59056a78593b input=bbe340bc99d25aa8]*/ #ifdef USE_ZLIB_CRC32 -/* This was taken from zlibmodule.c PyZlib_crc32 (but is PY_SSIZE_T_CLEAN) */ +/* The same core as zlibmodule.c zlib_crc32_impl. */ { - const Byte *buf; - Py_ssize_t len; - int signed_val; - - buf = (Byte*)data->buf; - len = data->len; - signed_val = crc32(crc, buf, len); - return (unsigned int)signed_val & 0xffffffffU; + unsigned char *buf = data->buf; + Py_ssize_t len = data->len; + + /* Avoid truncation of length for very large buffers. crc32() takes + length as an unsigned int, which may be narrower than Py_ssize_t. */ + while ((size_t)len > UINT_MAX) { + crc = crc32(crc, buf, UINT_MAX); + buf += (size_t) UINT_MAX; + len -= (size_t) UINT_MAX; + } + crc = crc32(crc, buf, (unsigned int)len); + return crc & 0xffffffff; } #else /* USE_ZLIB_CRC32 */ { /* By Jim Ahlstrom; All rights transferred to CNRI */ From webhook-mailer at python.org Sun Mar 20 20:15:52 2022 From: webhook-mailer at python.org (vstinner) Date: Mon, 21 Mar 2022 00:15:52 -0000 Subject: [Python-checkins] bpo-46850: Remove _PyEval_SetAsyncGenFinalizer() (GH-32017) Message-ID: https://github.com/python/cpython/commit/332b04bac35cd7305c60da2d5733940dc089949a commit: 332b04bac35cd7305c60da2d5733940dc089949a branch: main author: Victor Stinner committer: vstinner date: 2022-03-21T01:15:32+01:00 summary: bpo-46850: Remove _PyEval_SetAsyncGenFinalizer() (GH-32017) Remove the following private undocumented functions from the C API: * _PyEval_GetAsyncGenFirstiter() * _PyEval_GetAsyncGenFinalizer() * _PyEval_SetAsyncGenFirstiter() * _PyEval_SetAsyncGenFinalizer() Call the public sys.get_asyncgen_hooks() and sys.set_asyncgen_hooks() functions instead. files: A Misc/NEWS.d/next/C API/2022-03-21-00-41-29.bpo-46850.rOt771.rst M Include/cpython/ceval.h M Include/internal/pycore_ceval.h M Python/sysmodule.c diff --git a/Include/cpython/ceval.h b/Include/cpython/ceval.h index 5a904bd3f08e9..47c86f9da202f 100644 --- a/Include/cpython/ceval.h +++ b/Include/cpython/ceval.h @@ -9,10 +9,6 @@ PyAPI_DATA(int) _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyO PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *); PyAPI_FUNC(int) _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg); PyAPI_FUNC(int) _PyEval_GetCoroutineOriginTrackingDepth(void); -PyAPI_FUNC(int) _PyEval_SetAsyncGenFirstiter(PyObject *); -PyAPI_FUNC(PyObject *) _PyEval_GetAsyncGenFirstiter(void); -PyAPI_FUNC(int) _PyEval_SetAsyncGenFinalizer(PyObject *); -PyAPI_FUNC(PyObject *) _PyEval_GetAsyncGenFinalizer(void); /* Helper to look up a builtin object */ PyAPI_FUNC(PyObject *) _PyEval_GetBuiltin(PyObject *); diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 70178e38650cf..3efd13d01c7c5 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -37,6 +37,14 @@ PyAPI_FUNC(void) _PyEval_SetCoroutineOriginTrackingDepth( PyThreadState *tstate, int new_depth); +// Used by sys.get_asyncgen_hooks() +extern PyObject* _PyEval_GetAsyncGenFirstiter(void); +extern PyObject* _PyEval_GetAsyncGenFinalizer(void); + +// Used by sys.set_asyncgen_hooks() +extern int _PyEval_SetAsyncGenFirstiter(PyObject *); +extern int _PyEval_SetAsyncGenFinalizer(PyObject *); + void _PyEval_Fini(void); diff --git a/Misc/NEWS.d/next/C API/2022-03-21-00-41-29.bpo-46850.rOt771.rst b/Misc/NEWS.d/next/C API/2022-03-21-00-41-29.bpo-46850.rOt771.rst new file mode 100644 index 0000000000000..b3740ae740987 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2022-03-21-00-41-29.bpo-46850.rOt771.rst @@ -0,0 +1,9 @@ +Remove the following private undocumented functions from the C API: + +* ``_PyEval_GetAsyncGenFirstiter()`` +* ``_PyEval_GetAsyncGenFinalizer()`` +* ``_PyEval_SetAsyncGenFirstiter()`` +* ``_PyEval_SetAsyncGenFinalizer()`` + +Call the public :func:`sys.get_asyncgen_hooks` and +:func:`sys.set_asyncgen_hooks` functions instead. Patch by Victor Stinner. diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 99540b09c1f46..ae6d7c2955f81 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -16,7 +16,7 @@ Data members: #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() -#include "pycore_ceval.h" // _Py_RecursionLimitLowerWaterMark() +#include "pycore_ceval.h" // _PyEval_SetAsyncGenFinalizer() #include "pycore_code.h" // _Py_QuickenedCount #include "pycore_frame.h" // _PyInterpreterFrame #include "pycore_initconfig.h" // _PyStatus_EXCEPTION() From webhook-mailer at python.org Sun Mar 20 21:24:18 2022 From: webhook-mailer at python.org (vstinner) Date: Mon, 21 Mar 2022 01:24:18 -0000 Subject: [Python-checkins] bpo-46850: Remove _PyEval_GetCoroutineOriginTrackingDepth() (GH-32018) Message-ID: https://github.com/python/cpython/commit/9087243e2c167e38570e819b228efc3492c38c9c commit: 9087243e2c167e38570e819b228efc3492c38c9c branch: main author: Victor Stinner committer: vstinner date: 2022-03-21T02:24:00+01:00 summary: bpo-46850: Remove _PyEval_GetCoroutineOriginTrackingDepth() (GH-32018) Remove the private undocumented function _PyEval_GetCoroutineOriginTrackingDepth() from the C API. Call the public sys.get_coroutine_origin_tracking_depth() function instead. Change the internal function _PyEval_SetCoroutineOriginTrackingDepth(): * Remove the 'tstate' parameter; * Add return value and raises an exception if depth is negative; * No longer export the function: call the public sys.set_coroutine_origin_tracking_depth() function instead. Uniformize also function declarations in pycore_ceval.h. files: A Misc/NEWS.d/next/C API/2022-03-21-01-30-14.bpo-46850.Tfxde5.rst M Include/cpython/ceval.h M Include/internal/pycore_ceval.h M Python/ceval.c M Python/sysmodule.c diff --git a/Include/cpython/ceval.h b/Include/cpython/ceval.h index 47c86f9da202f..e0a68876015d6 100644 --- a/Include/cpython/ceval.h +++ b/Include/cpython/ceval.h @@ -8,7 +8,6 @@ PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *); PyAPI_DATA(int) _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg); PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *); PyAPI_FUNC(int) _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg); -PyAPI_FUNC(int) _PyEval_GetCoroutineOriginTrackingDepth(void); /* Helper to look up a builtin object */ PyAPI_FUNC(PyObject *) _PyEval_GetBuiltin(PyObject *); diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 3efd13d01c7c5..59a3453f9fd3b 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -33,9 +33,6 @@ PyAPI_FUNC(void) _PyEval_SignalAsyncExc(PyInterpreterState *interp); #ifdef HAVE_FORK extern PyStatus _PyEval_ReInitThreads(PyThreadState *tstate); #endif -PyAPI_FUNC(void) _PyEval_SetCoroutineOriginTrackingDepth( - PyThreadState *tstate, - int new_depth); // Used by sys.get_asyncgen_hooks() extern PyObject* _PyEval_GetAsyncGenFirstiter(void); @@ -45,11 +42,16 @@ extern PyObject* _PyEval_GetAsyncGenFinalizer(void); extern int _PyEval_SetAsyncGenFirstiter(PyObject *); extern int _PyEval_SetAsyncGenFinalizer(PyObject *); -void _PyEval_Fini(void); +// Used by sys.get_coroutine_origin_tracking_depth() +// and sys.set_coroutine_origin_tracking_depth() +extern int _PyEval_GetCoroutineOriginTrackingDepth(void); +extern int _PyEval_SetCoroutineOriginTrackingDepth(int depth); + +extern void _PyEval_Fini(void); extern PyObject* _PyEval_GetBuiltins(PyThreadState *tstate); -extern PyObject *_PyEval_BuiltinsFromGlobals( +extern PyObject* _PyEval_BuiltinsFromGlobals( PyThreadState *tstate, PyObject *globals); @@ -63,7 +65,7 @@ _PyEval_EvalFrame(PyThreadState *tstate, struct _PyInterpreterFrame *frame, int return tstate->interp->eval_frame(tstate, frame, throwflag); } -extern PyObject * +extern PyObject* _PyEval_Vector(PyThreadState *tstate, PyFunctionObject *func, PyObject *locals, PyObject* const* args, size_t argcount, @@ -124,9 +126,9 @@ static inline void _Py_LeaveRecursiveCall_inline(void) { #define Py_LeaveRecursiveCall() _Py_LeaveRecursiveCall_inline() -struct _PyInterpreterFrame *_PyEval_GetFrame(void); +extern struct _PyInterpreterFrame* _PyEval_GetFrame(void); -PyObject *_Py_MakeCoro(PyFunctionObject *func); +extern PyObject* _Py_MakeCoro(PyFunctionObject *func); #ifdef __cplusplus } diff --git a/Misc/NEWS.d/next/C API/2022-03-21-01-30-14.bpo-46850.Tfxde5.rst b/Misc/NEWS.d/next/C API/2022-03-21-01-30-14.bpo-46850.Tfxde5.rst new file mode 100644 index 0000000000000..0dc01fe6ea6ce --- /dev/null +++ b/Misc/NEWS.d/next/C API/2022-03-21-01-30-14.bpo-46850.Tfxde5.rst @@ -0,0 +1,4 @@ +Remove the private undocumented function +``_PyEval_GetCoroutineOriginTrackingDepth()`` from the C API. Call the +public :func:`sys.get_coroutine_origin_tracking_depth` function instead. +Patch by Victor Stinner. diff --git a/Python/ceval.c b/Python/ceval.c index 1a120bba83f8c..04f2dde3cbdf9 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -6852,13 +6852,19 @@ PyEval_SetTrace(Py_tracefunc func, PyObject *arg) } -void -_PyEval_SetCoroutineOriginTrackingDepth(PyThreadState *tstate, int new_depth) +int +_PyEval_SetCoroutineOriginTrackingDepth(int depth) { - assert(new_depth >= 0); - tstate->coroutine_origin_tracking_depth = new_depth; + PyThreadState *tstate = _PyThreadState_GET(); + if (depth < 0) { + _PyErr_SetString(tstate, PyExc_ValueError, "depth must be >= 0"); + return -1; + } + tstate->coroutine_origin_tracking_depth = depth; + return 0; } + int _PyEval_GetCoroutineOriginTrackingDepth(void) { diff --git a/Python/sysmodule.c b/Python/sysmodule.c index ae6d7c2955f81..c89f81f689f7e 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -1186,12 +1186,9 @@ static PyObject * sys_set_coroutine_origin_tracking_depth_impl(PyObject *module, int depth) /*[clinic end generated code: output=0a2123c1cc6759c5 input=a1d0a05f89d2c426]*/ { - PyThreadState *tstate = _PyThreadState_GET(); - if (depth < 0) { - _PyErr_SetString(tstate, PyExc_ValueError, "depth must be >= 0"); + if (_PyEval_SetCoroutineOriginTrackingDepth(depth) < 0) { return NULL; } - _PyEval_SetCoroutineOriginTrackingDepth(tstate, depth); Py_RETURN_NONE; } From webhook-mailer at python.org Sun Mar 20 22:03:36 2022 From: webhook-mailer at python.org (vstinner) Date: Mon, 21 Mar 2022 02:03:36 -0000 Subject: [Python-checkins] bpo-46850: Remove _PyEval_CallTracing() function (GH-32019) Message-ID: https://github.com/python/cpython/commit/e63894b3eed8ad2dd7690695f7f07bfbff59c05a commit: e63894b3eed8ad2dd7690695f7f07bfbff59c05a branch: main author: Victor Stinner committer: vstinner date: 2022-03-21T03:03:22+01:00 summary: bpo-46850: Remove _PyEval_CallTracing() function (GH-32019) Remove the private undocumented function _PyEval_CallTracing() from the C API. Call the public sys.call_tracing() function instead. files: A Misc/NEWS.d/next/C API/2022-03-21-02-26-27.bpo-46850.hU3c-O.rst M Include/cpython/ceval.h M Include/internal/pycore_ceval.h M Python/ceval.c diff --git a/Include/cpython/ceval.h b/Include/cpython/ceval.h index e0a68876015d6..9d4eeafb427eb 100644 --- a/Include/cpython/ceval.h +++ b/Include/cpython/ceval.h @@ -2,8 +2,6 @@ # error "this header file must not be included directly" #endif -PyAPI_FUNC(PyObject *) _PyEval_CallTracing(PyObject *func, PyObject *args); - PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *); PyAPI_DATA(int) _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg); PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *); diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 59a3453f9fd3b..45d26a37a34c6 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -34,6 +34,9 @@ PyAPI_FUNC(void) _PyEval_SignalAsyncExc(PyInterpreterState *interp); extern PyStatus _PyEval_ReInitThreads(PyThreadState *tstate); #endif +// Used by sys.call_tracing() +extern PyObject* _PyEval_CallTracing(PyObject *func, PyObject *args); + // Used by sys.get_asyncgen_hooks() extern PyObject* _PyEval_GetAsyncGenFirstiter(void); extern PyObject* _PyEval_GetAsyncGenFinalizer(void); diff --git a/Misc/NEWS.d/next/C API/2022-03-21-02-26-27.bpo-46850.hU3c-O.rst b/Misc/NEWS.d/next/C API/2022-03-21-02-26-27.bpo-46850.hU3c-O.rst new file mode 100644 index 0000000000000..f600ea8ea24f3 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2022-03-21-02-26-27.bpo-46850.hU3c-O.rst @@ -0,0 +1,3 @@ +Remove the private undocumented function ``_PyEval_CallTracing()`` from the +C API. Call the public :func:`sys.call_tracing` function instead. Patch by +Victor Stinner. diff --git a/Python/ceval.c b/Python/ceval.c index 04f2dde3cbdf9..6f449e3172d08 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -6708,16 +6708,19 @@ call_trace(Py_tracefunc func, PyObject *obj, return result; } -PyObject * +PyObject* _PyEval_CallTracing(PyObject *func, PyObject *args) { + // Save and disable tracing PyThreadState *tstate = _PyThreadState_GET(); int save_tracing = tstate->tracing; int save_use_tracing = tstate->cframe->use_tracing; - PyObject *result; - tstate->tracing = 0; - result = PyObject_Call(func, args, NULL); + + // Call the tracing function + PyObject *result = PyObject_Call(func, args, NULL); + + // Restore tracing tstate->tracing = save_tracing; tstate->cframe->use_tracing = save_use_tracing; return result; From webhook-mailer at python.org Mon Mar 21 02:34:50 2022 From: webhook-mailer at python.org (gpshead) Date: Mon, 21 Mar 2022 06:34:50 -0000 Subject: [Python-checkins] bpo-38256: Fix binascii.crc32 large input. (GH-32000) (GH-32013) (GH-32015) Message-ID: https://github.com/python/cpython/commit/58a7e130375776b192a99b013bc563205a639edc commit: 58a7e130375776b192a99b013bc563205a639edc branch: 3.9 author: Gregory P. Smith committer: gpshead date: 2022-03-20T23:34:45-07:00 summary: bpo-38256: Fix binascii.crc32 large input. (GH-32000) (GH-32013) (GH-32015) Inputs >= 4GiB to `binascii.crc32(...)` when compiled to use the zlib crc32 implementation (the norm on POSIX) no longer return the wrong result. (cherry picked from commit 4c989e19c84ec224655bbbde9422e16d4a838a80) files: A Misc/NEWS.d/next/Library/2022-03-19-15-54-41.bpo-38256.FoMbjE.rst M Lib/test/test_binascii.py M Modules/binascii.c diff --git a/Lib/test/test_binascii.py b/Lib/test/test_binascii.py index 45327953a7701..745329102f77b 100644 --- a/Lib/test/test_binascii.py +++ b/Lib/test/test_binascii.py @@ -5,6 +5,8 @@ import array import re from test import support +from test.support import bigmemtest, _1G, _4G, warnings_helper + # Note: "*_hex" functions are aliases for "(un)hexlify" b2a_functions = ['b2a_base64', 'b2a_hex', 'b2a_hqx', 'b2a_qp', 'b2a_uu', @@ -448,6 +450,14 @@ class BytearrayBinASCIITest(BinASCIITest): class MemoryviewBinASCIITest(BinASCIITest): type2test = memoryview +class ChecksumBigBufferTestCase(unittest.TestCase): + """bpo-38256 - check that inputs >=4 GiB are handled correctly.""" + + @bigmemtest(size=_4G + 4, memuse=1, dry_run=False) + def test_big_buffer(self, size): + data = b"nyan" * (_1G + 1) + self.assertEqual(binascii.crc32(data), 1044521549) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2022-03-19-15-54-41.bpo-38256.FoMbjE.rst b/Misc/NEWS.d/next/Library/2022-03-19-15-54-41.bpo-38256.FoMbjE.rst new file mode 100644 index 0000000000000..d9b57513b0631 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-19-15-54-41.bpo-38256.FoMbjE.rst @@ -0,0 +1,5 @@ +Fix :func:`binascii.crc32` when it is compiled to use zlib'c crc32 to +work properly on inputs 4+GiB in length instead of returning the wrong +result. The workaround prior to this was to always feed the function +data in increments smaller than 4GiB or to just call the zlib module +function. diff --git a/Modules/binascii.c b/Modules/binascii.c index 1f3248b6049b3..3777580a79f2a 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -1120,16 +1120,20 @@ binascii_crc32_impl(PyObject *module, Py_buffer *data, unsigned int crc) /*[clinic end generated code: output=52cf59056a78593b input=bbe340bc99d25aa8]*/ #ifdef USE_ZLIB_CRC32 -/* This was taken from zlibmodule.c PyZlib_crc32 (but is PY_SSIZE_T_CLEAN) */ +/* The same core as zlibmodule.c zlib_crc32_impl. */ { - const Byte *buf; - Py_ssize_t len; - int signed_val; - - buf = (Byte*)data->buf; - len = data->len; - signed_val = crc32(crc, buf, len); - return (unsigned int)signed_val & 0xffffffffU; + unsigned char *buf = data->buf; + Py_ssize_t len = data->len; + + /* Avoid truncation of length for very large buffers. crc32() takes + length as an unsigned int, which may be narrower than Py_ssize_t. */ + while ((size_t)len > UINT_MAX) { + crc = crc32(crc, buf, UINT_MAX); + buf += (size_t) UINT_MAX; + len -= (size_t) UINT_MAX; + } + crc = crc32(crc, buf, (unsigned int)len); + return crc & 0xffffffff; } #else /* USE_ZLIB_CRC32 */ { /* By Jim Ahlstrom; All rights transferred to CNRI */ From webhook-mailer at python.org Mon Mar 21 07:00:47 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Mon, 21 Mar 2022 11:00:47 -0000 Subject: [Python-checkins] bpo-23691: Protect the re.finditer() iterator from re-entering (GH-32012) Message-ID: https://github.com/python/cpython/commit/08eb754d840696914928355014c2d424131f8835 commit: 08eb754d840696914928355014c2d424131f8835 branch: main author: Serhiy Storchaka committer: serhiy-storchaka date: 2022-03-21T13:00:43+02:00 summary: bpo-23691: Protect the re.finditer() iterator from re-entering (GH-32012) files: A Misc/NEWS.d/next/Library/2022-03-20-22-13-24.bpo-23691.Nc2TrW.rst M Modules/_sre.c M Modules/sre.h diff --git a/Misc/NEWS.d/next/Library/2022-03-20-22-13-24.bpo-23691.Nc2TrW.rst b/Misc/NEWS.d/next/Library/2022-03-20-22-13-24.bpo-23691.Nc2TrW.rst new file mode 100644 index 0000000000000..053a2b2709ee8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-20-22-13-24.bpo-23691.Nc2TrW.rst @@ -0,0 +1 @@ +Protect the :func:`re.finditer` iterator from re-entering. diff --git a/Modules/_sre.c b/Modules/_sre.c index 213730860cfb5..ab321eafb6d79 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -2511,6 +2511,25 @@ scanner_dealloc(ScannerObject* self) Py_DECREF(tp); } +static int +scanner_begin(ScannerObject* self) +{ + if (self->executing) { + PyErr_SetString(PyExc_ValueError, + "regular expression scanner already executing"); + return 0; + } + self->executing = 1; + return 1; +} + +static void +scanner_end(ScannerObject* self) +{ + assert(self->executing); + self->executing = 0; +} + /*[clinic input] _sre.SRE_Scanner.match @@ -2528,16 +2547,23 @@ _sre_SRE_Scanner_match_impl(ScannerObject *self, PyTypeObject *cls) PyObject* match; Py_ssize_t status; - if (state->start == NULL) + if (!scanner_begin(self)) { + return NULL; + } + if (state->start == NULL) { + scanner_end(self); Py_RETURN_NONE; + } state_reset(state); state->ptr = state->start; status = sre_match(state, PatternObject_GetCode(self->pattern)); - if (PyErr_Occurred()) + if (PyErr_Occurred()) { + scanner_end(self); return NULL; + } match = pattern_new_match(module_state, (PatternObject*) self->pattern, state, status); @@ -2549,6 +2575,7 @@ _sre_SRE_Scanner_match_impl(ScannerObject *self, PyTypeObject *cls) state->start = state->ptr; } + scanner_end(self); return match; } @@ -2570,16 +2597,23 @@ _sre_SRE_Scanner_search_impl(ScannerObject *self, PyTypeObject *cls) PyObject* match; Py_ssize_t status; - if (state->start == NULL) + if (!scanner_begin(self)) { + return NULL; + } + if (state->start == NULL) { + scanner_end(self); Py_RETURN_NONE; + } state_reset(state); state->ptr = state->start; status = sre_search(state, PatternObject_GetCode(self->pattern)); - if (PyErr_Occurred()) + if (PyErr_Occurred()) { + scanner_end(self); return NULL; + } match = pattern_new_match(module_state, (PatternObject*) self->pattern, state, status); @@ -2591,6 +2625,7 @@ _sre_SRE_Scanner_search_impl(ScannerObject *self, PyTypeObject *cls) state->start = state->ptr; } + scanner_end(self); return match; } @@ -2608,6 +2643,7 @@ pattern_scanner(_sremodulestate *module_state, if (!scanner) return NULL; scanner->pattern = NULL; + scanner->executing = 0; /* create search state object */ if (!state_init(&scanner->state, self, string, pos, endpos)) { diff --git a/Modules/sre.h b/Modules/sre.h index 9b0d8b190426a..785adbd003e7f 100644 --- a/Modules/sre.h +++ b/Modules/sre.h @@ -89,6 +89,7 @@ typedef struct { PyObject_HEAD PyObject* pattern; SRE_STATE state; + int executing; } ScannerObject; #endif From webhook-mailer at python.org Mon Mar 21 07:11:48 2022 From: webhook-mailer at python.org (markshannon) Date: Mon, 21 Mar 2022 11:11:48 -0000 Subject: [Python-checkins] bpo-46841: Quicken code in-place (GH-31888) Message-ID: https://github.com/python/cpython/commit/2bde6827ea4f136297b2d882480b981ff26262b6 commit: 2bde6827ea4f136297b2d882480b981ff26262b6 branch: main author: Brandt Bucher committer: markshannon date: 2022-03-21T11:11:17Z summary: bpo-46841: Quicken code in-place (GH-31888) * Moves the bytecode to the end of the corresponding PyCodeObject, and quickens it in-place. * Removes the almost-always-unused co_varnames, co_freevars, and co_cellvars member caches * _PyOpcode_Deopt is a new mapping from all opcodes to their un-quickened forms. * _PyOpcode_InlineCacheEntries is renamed to _PyOpcode_Caches * _Py_IncrementCountAndMaybeQuicken is renamed to _PyCode_Warmup * _Py_Quicken is renamed to _PyCode_Quicken * _co_quickened is renamed to _co_code_adaptive (and is now a read-only memoryview). * Do not emit unused nonzero opargs anymore in the compiler. files: A Misc/NEWS.d/next/Core and Builtins/2022-03-16-11-05-35.bpo-46841.yUoIHg.rst M Include/cpython/code.h M Include/internal/pycore_code.h M Include/opcode.h M Lib/opcode.py M Lib/test/test_compile.py M Objects/clinic/codeobject.c.h M Objects/codeobject.c M Objects/frameobject.c M Objects/genobject.c M Objects/typeobject.c M Python/ceval.c M Python/compile.c M Python/marshal.c M Python/opcode_targets.h M Python/specialize.c M Tools/scripts/deepfreeze.py M Tools/scripts/generate_opcode_h.py diff --git a/Include/cpython/code.h b/Include/cpython/code.h index ab827c5ae87ff..157678317931e 100644 --- a/Include/cpython/code.h +++ b/Include/cpython/code.h @@ -26,91 +26,80 @@ typedef uint16_t _Py_CODEUNIT; // Use "unsigned char" instead of "uint8_t" here to avoid illegal aliasing: #define _Py_SET_OPCODE(word, opcode) (((unsigned char *)&(word))[0] = (opcode)) +// To avoid repeating ourselves in deepfreeze.py, all PyCodeObject members are +// defined in this macro: +#define _PyCode_DEF(SIZE) { \ + PyObject_VAR_HEAD \ + \ + /* Note only the following fields are used in hash and/or comparisons \ + * \ + * - co_name \ + * - co_argcount \ + * - co_posonlyargcount \ + * - co_kwonlyargcount \ + * - co_nlocals \ + * - co_stacksize \ + * - co_flags \ + * - co_firstlineno \ + * - co_consts \ + * - co_names \ + * - co_localsplusnames \ + * This is done to preserve the name and line number for tracebacks \ + * and debuggers; otherwise, constant de-duplication would collapse \ + * identical functions/lambdas defined on different lines. \ + */ \ + \ + /* These fields are set with provided values on new code objects. */ \ + \ + /* The hottest fields (in the eval loop) are grouped here at the top. */ \ + PyObject *co_consts; /* list (constants used) */ \ + PyObject *co_names; /* list of strings (names used) */ \ + PyObject *co_exceptiontable; /* Byte string encoding exception handling \ + table */ \ + int co_flags; /* CO_..., see below */ \ + int co_warmup; /* Warmup counter for quickening */ \ + \ + /* The rest are not so impactful on performance. */ \ + int co_argcount; /* #arguments, except *args */ \ + int co_posonlyargcount; /* #positional only arguments */ \ + int co_kwonlyargcount; /* #keyword only arguments */ \ + int co_stacksize; /* #entries needed for evaluation stack */ \ + int co_firstlineno; /* first source line number */ \ + \ + /* redundant values (derived from co_localsplusnames and \ + co_localspluskinds) */ \ + int co_nlocalsplus; /* number of local + cell + free variables \ + */ \ + int co_nlocals; /* number of local variables */ \ + int co_nplaincellvars; /* number of non-arg cell variables */ \ + int co_ncellvars; /* total number of cell variables */ \ + int co_nfreevars; /* number of free variables */ \ + \ + PyObject *co_localsplusnames; /* tuple mapping offsets to names */ \ + PyObject *co_localspluskinds; /* Bytes mapping to local kinds (one byte \ + per variable) */ \ + PyObject *co_filename; /* unicode (where it was loaded from) */ \ + PyObject *co_name; /* unicode (name, for reference) */ \ + PyObject *co_qualname; /* unicode (qualname, for reference) */ \ + PyObject *co_linetable; /* bytes (encoding addr<->lineno mapping) \ + See Objects/lnotab_notes.txt for details. \ + */ \ + PyObject *co_endlinetable; /* bytes object that holds end lineno for \ + instructions separated across different \ + lines */ \ + PyObject *co_columntable; /* bytes object that holds start/end column \ + offset each instruction */ \ + \ + PyObject *co_weakreflist; /* to support weakrefs to code objects */ \ + /* Scratch space for extra data relating to the code object. \ + Type is a void* to keep the format private in codeobject.c to force \ + people to go through the proper APIs. */ \ + void *co_extra; \ + char co_code_adaptive[(SIZE)]; \ +} /* Bytecode object */ -struct PyCodeObject { - PyObject_HEAD - - /* Note only the following fields are used in hash and/or comparisons - * - * - co_name - * - co_argcount - * - co_posonlyargcount - * - co_kwonlyargcount - * - co_nlocals - * - co_stacksize - * - co_flags - * - co_firstlineno - * - co_code - * - co_consts - * - co_names - * - co_varnames - * - co_freevars - * - co_cellvars - * - * This is done to preserve the name and line number for tracebacks - * and debuggers; otherwise, constant de-duplication would collapse - * identical functions/lambdas defined on different lines. - */ - - /* These fields are set with provided values on new code objects. */ - - // The hottest fields (in the eval loop) are grouped here at the top. - PyObject *co_consts; /* list (constants used) */ - PyObject *co_names; /* list of strings (names used) */ - _Py_CODEUNIT *co_firstinstr; /* Pointer to first instruction, used for quickening. - Unlike the other "hot" fields, this one is - actually derived from co_code. */ - PyObject *co_exceptiontable; /* Byte string encoding exception handling table */ - int co_flags; /* CO_..., see below */ - int co_warmup; /* Warmup counter for quickening */ - - // The rest are not so impactful on performance. - int co_argcount; /* #arguments, except *args */ - int co_posonlyargcount; /* #positional only arguments */ - int co_kwonlyargcount; /* #keyword only arguments */ - int co_stacksize; /* #entries needed for evaluation stack */ - int co_firstlineno; /* first source line number */ - PyObject *co_code; /* instruction opcodes */ - PyObject *co_localsplusnames; /* tuple mapping offsets to names */ - PyObject *co_localspluskinds; /* Bytes mapping to local kinds (one byte per variable) */ - PyObject *co_filename; /* unicode (where it was loaded from) */ - PyObject *co_name; /* unicode (name, for reference) */ - PyObject *co_qualname; /* unicode (qualname, for reference) */ - PyObject *co_linetable; /* bytes (encoding addr<->lineno mapping) See - Objects/lnotab_notes.txt for details. */ - PyObject *co_endlinetable; /* bytes object that holds end lineno for - instructions separated across different - lines */ - PyObject *co_columntable; /* bytes object that holds start/end column - offset each instruction */ - - /* These fields are set with computed values on new code objects. */ - - // redundant values (derived from co_localsplusnames and co_localspluskinds) - int co_nlocalsplus; /* number of local + cell + free variables */ - int co_nlocals; /* number of local variables */ - int co_nplaincellvars; /* number of non-arg cell variables */ - int co_ncellvars; /* total number of cell variables */ - int co_nfreevars; /* number of free variables */ - // lazily-computed values - PyObject *co_varnames; /* tuple of strings (local variable names) */ - PyObject *co_cellvars; /* tuple of strings (cell variable names) */ - PyObject *co_freevars; /* tuple of strings (free variable names) */ - - /* The remaining fields are zeroed out on new code objects. */ - - PyObject *co_weakreflist; /* to support weakrefs to code objects */ - /* Scratch space for extra data relating to the code object. - Type is a void* to keep the format private in codeobject.c to force - people to go through the proper APIs. */ - void *co_extra; - /* Quickened instructions and cache, or NULL - This should be treated as opaque by all code except the specializer and - interpreter. */ - _Py_CODEUNIT *co_quickened; - -}; +struct PyCodeObject _PyCode_DEF(1); /* Masks for co_flags above */ #define CO_OPTIMIZED 0x0001 @@ -151,6 +140,8 @@ PyAPI_DATA(PyTypeObject) PyCode_Type; #define PyCode_Check(op) Py_IS_TYPE(op, &PyCode_Type) #define PyCode_GetNumFree(op) ((op)->co_nfreevars) +#define _PyCode_CODE(CO) ((_Py_CODEUNIT *)(CO)->co_code_adaptive) +#define _PyCode_NBYTES(CO) (Py_SIZE(CO) * (Py_ssize_t)sizeof(_Py_CODEUNIT)) /* Public interface */ PyAPI_FUNC(PyCodeObject *) PyCode_New( diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index 0d324e9e4c0f5..82dc9e4bdc62f 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -92,30 +92,22 @@ typedef struct { #define INLINE_CACHE_ENTRIES_STORE_SUBSCR CACHE_ENTRIES(_PyStoreSubscrCache) -/* Maximum size of code to quicken, in code units. */ -#define MAX_SIZE_TO_QUICKEN 10000 - #define QUICKENING_WARMUP_DELAY 8 /* We want to compare to zero for efficiency, so we offset values accordingly */ #define QUICKENING_INITIAL_WARMUP_VALUE (-QUICKENING_WARMUP_DELAY) -#define QUICKENING_WARMUP_COLDEST 1 -int _Py_Quicken(PyCodeObject *code); +void _PyCode_Quicken(PyCodeObject *code); -/* Returns 1 if quickening occurs. - * -1 if an error occurs - * 0 otherwise */ -static inline int -_Py_IncrementCountAndMaybeQuicken(PyCodeObject *code) +static inline void +_PyCode_Warmup(PyCodeObject *code) { if (code->co_warmup != 0) { code->co_warmup++; if (code->co_warmup == 0) { - return _Py_Quicken(code) ? -1 : 1; + _PyCode_Quicken(code); } } - return 0; } extern Py_ssize_t _Py_QuickenedCount; @@ -225,6 +217,7 @@ PyAPI_FUNC(PyCodeObject *) _PyCode_New(struct _PyCodeConstructor *); extern PyObject* _PyCode_GetVarnames(PyCodeObject *); extern PyObject* _PyCode_GetCellvars(PyCodeObject *); extern PyObject* _PyCode_GetFreevars(PyCodeObject *); +extern PyObject* _PyCode_GetCode(PyCodeObject *); /* Return the ending source code line number from a bytecode index. */ extern int _PyCode_Addr2EndLine(PyCodeObject *, int); diff --git a/Include/opcode.h b/Include/opcode.h index 7bf0ba70fd7de..dfc7b72e3cdc6 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -7,185 +7,187 @@ extern "C" { /* Instruction opcodes for compiled code */ -#define CACHE 0 -#define POP_TOP 1 -#define PUSH_NULL 2 -#define NOP 9 -#define UNARY_POSITIVE 10 -#define UNARY_NEGATIVE 11 -#define UNARY_NOT 12 -#define UNARY_INVERT 15 -#define BINARY_SUBSCR 25 -#define GET_LEN 30 -#define MATCH_MAPPING 31 -#define MATCH_SEQUENCE 32 -#define MATCH_KEYS 33 -#define PUSH_EXC_INFO 35 -#define WITH_EXCEPT_START 49 -#define GET_AITER 50 -#define GET_ANEXT 51 -#define BEFORE_ASYNC_WITH 52 -#define BEFORE_WITH 53 -#define END_ASYNC_FOR 54 -#define STORE_SUBSCR 60 -#define DELETE_SUBSCR 61 -#define GET_ITER 68 -#define GET_YIELD_FROM_ITER 69 -#define PRINT_EXPR 70 -#define LOAD_BUILD_CLASS 71 -#define LOAD_ASSERTION_ERROR 74 -#define RETURN_GENERATOR 75 -#define LIST_TO_TUPLE 82 -#define RETURN_VALUE 83 -#define IMPORT_STAR 84 -#define SETUP_ANNOTATIONS 85 -#define YIELD_VALUE 86 -#define ASYNC_GEN_WRAP 87 -#define PREP_RERAISE_STAR 88 -#define POP_EXCEPT 89 -#define HAVE_ARGUMENT 90 -#define STORE_NAME 90 -#define DELETE_NAME 91 -#define UNPACK_SEQUENCE 92 -#define FOR_ITER 93 -#define UNPACK_EX 94 -#define STORE_ATTR 95 -#define DELETE_ATTR 96 -#define STORE_GLOBAL 97 -#define DELETE_GLOBAL 98 -#define SWAP 99 -#define LOAD_CONST 100 -#define LOAD_NAME 101 -#define BUILD_TUPLE 102 -#define BUILD_LIST 103 -#define BUILD_SET 104 -#define BUILD_MAP 105 -#define LOAD_ATTR 106 -#define COMPARE_OP 107 -#define IMPORT_NAME 108 -#define IMPORT_FROM 109 -#define JUMP_FORWARD 110 -#define JUMP_IF_FALSE_OR_POP 111 -#define JUMP_IF_TRUE_OR_POP 112 -#define JUMP_ABSOLUTE 113 -#define POP_JUMP_IF_FALSE 114 -#define POP_JUMP_IF_TRUE 115 -#define LOAD_GLOBAL 116 -#define IS_OP 117 -#define CONTAINS_OP 118 -#define RERAISE 119 -#define COPY 120 -#define JUMP_IF_NOT_EXC_MATCH 121 -#define BINARY_OP 122 -#define SEND 123 -#define LOAD_FAST 124 -#define STORE_FAST 125 -#define DELETE_FAST 126 -#define JUMP_IF_NOT_EG_MATCH 127 -#define POP_JUMP_IF_NOT_NONE 128 -#define POP_JUMP_IF_NONE 129 -#define RAISE_VARARGS 130 -#define GET_AWAITABLE 131 -#define MAKE_FUNCTION 132 -#define BUILD_SLICE 133 -#define JUMP_NO_INTERRUPT 134 -#define MAKE_CELL 135 -#define LOAD_CLOSURE 136 -#define LOAD_DEREF 137 -#define STORE_DEREF 138 -#define DELETE_DEREF 139 -#define CALL_FUNCTION_EX 142 -#define EXTENDED_ARG 144 -#define LIST_APPEND 145 -#define SET_ADD 146 -#define MAP_ADD 147 -#define LOAD_CLASSDEREF 148 -#define COPY_FREE_VARS 149 -#define RESUME 151 -#define MATCH_CLASS 152 -#define FORMAT_VALUE 155 -#define BUILD_CONST_KEY_MAP 156 -#define BUILD_STRING 157 -#define LOAD_METHOD 160 -#define LIST_EXTEND 162 -#define SET_UPDATE 163 -#define DICT_MERGE 164 -#define DICT_UPDATE 165 -#define PRECALL 166 -#define CALL 171 -#define KW_NAMES 172 -#define BINARY_OP_ADAPTIVE 3 -#define BINARY_OP_ADD_INT 4 -#define BINARY_OP_ADD_FLOAT 5 -#define BINARY_OP_ADD_UNICODE 6 -#define BINARY_OP_INPLACE_ADD_UNICODE 7 -#define BINARY_OP_MULTIPLY_INT 8 -#define BINARY_OP_MULTIPLY_FLOAT 13 -#define BINARY_OP_SUBTRACT_INT 14 -#define BINARY_OP_SUBTRACT_FLOAT 16 -#define COMPARE_OP_ADAPTIVE 17 -#define COMPARE_OP_FLOAT_JUMP 18 -#define COMPARE_OP_INT_JUMP 19 -#define COMPARE_OP_STR_JUMP 20 -#define BINARY_SUBSCR_ADAPTIVE 21 -#define BINARY_SUBSCR_GETITEM 22 -#define BINARY_SUBSCR_LIST_INT 23 -#define BINARY_SUBSCR_TUPLE_INT 24 -#define BINARY_SUBSCR_DICT 26 -#define STORE_SUBSCR_ADAPTIVE 27 -#define STORE_SUBSCR_LIST_INT 28 -#define STORE_SUBSCR_DICT 29 -#define CALL_ADAPTIVE 34 -#define CALL_PY_EXACT_ARGS 36 -#define CALL_PY_WITH_DEFAULTS 37 -#define JUMP_ABSOLUTE_QUICK 38 -#define LOAD_ATTR_ADAPTIVE 39 -#define LOAD_ATTR_INSTANCE_VALUE 40 -#define LOAD_ATTR_WITH_HINT 41 -#define LOAD_ATTR_SLOT 42 -#define LOAD_ATTR_MODULE 43 -#define LOAD_GLOBAL_ADAPTIVE 44 -#define LOAD_GLOBAL_MODULE 45 -#define LOAD_GLOBAL_BUILTIN 46 -#define LOAD_METHOD_ADAPTIVE 47 -#define LOAD_METHOD_CLASS 48 -#define LOAD_METHOD_MODULE 55 -#define LOAD_METHOD_NO_DICT 56 -#define LOAD_METHOD_WITH_DICT 57 -#define LOAD_METHOD_WITH_VALUES 58 -#define PRECALL_ADAPTIVE 59 -#define PRECALL_BUILTIN_CLASS 62 -#define PRECALL_NO_KW_BUILTIN_O 63 -#define PRECALL_NO_KW_BUILTIN_FAST 64 -#define PRECALL_BUILTIN_FAST_WITH_KEYWORDS 65 -#define PRECALL_NO_KW_LEN 66 -#define PRECALL_NO_KW_ISINSTANCE 67 -#define PRECALL_NO_KW_LIST_APPEND 72 -#define PRECALL_NO_KW_METHOD_DESCRIPTOR_O 73 -#define PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS 76 -#define PRECALL_NO_KW_STR_1 77 -#define PRECALL_NO_KW_TUPLE_1 78 -#define PRECALL_NO_KW_TYPE_1 79 -#define PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST 80 -#define PRECALL_BOUND_METHOD 81 -#define PRECALL_PYFUNC 140 -#define RESUME_QUICK 141 -#define STORE_ATTR_ADAPTIVE 143 -#define STORE_ATTR_INSTANCE_VALUE 150 -#define STORE_ATTR_SLOT 153 -#define STORE_ATTR_WITH_HINT 154 -#define UNPACK_SEQUENCE_ADAPTIVE 158 -#define UNPACK_SEQUENCE_LIST 159 -#define UNPACK_SEQUENCE_TUPLE 161 -#define UNPACK_SEQUENCE_TWO_TUPLE 167 -#define LOAD_FAST__LOAD_FAST 168 -#define STORE_FAST__LOAD_FAST 169 -#define LOAD_FAST__LOAD_CONST 170 -#define LOAD_CONST__LOAD_FAST 173 -#define STORE_FAST__STORE_FAST 174 -#define DO_TRACING 255 +#define CACHE 0 +#define POP_TOP 1 +#define PUSH_NULL 2 +#define NOP 9 +#define UNARY_POSITIVE 10 +#define UNARY_NEGATIVE 11 +#define UNARY_NOT 12 +#define UNARY_INVERT 15 +#define BINARY_SUBSCR 25 +#define GET_LEN 30 +#define MATCH_MAPPING 31 +#define MATCH_SEQUENCE 32 +#define MATCH_KEYS 33 +#define PUSH_EXC_INFO 35 +#define WITH_EXCEPT_START 49 +#define GET_AITER 50 +#define GET_ANEXT 51 +#define BEFORE_ASYNC_WITH 52 +#define BEFORE_WITH 53 +#define END_ASYNC_FOR 54 +#define STORE_SUBSCR 60 +#define DELETE_SUBSCR 61 +#define GET_ITER 68 +#define GET_YIELD_FROM_ITER 69 +#define PRINT_EXPR 70 +#define LOAD_BUILD_CLASS 71 +#define LOAD_ASSERTION_ERROR 74 +#define RETURN_GENERATOR 75 +#define LIST_TO_TUPLE 82 +#define RETURN_VALUE 83 +#define IMPORT_STAR 84 +#define SETUP_ANNOTATIONS 85 +#define YIELD_VALUE 86 +#define ASYNC_GEN_WRAP 87 +#define PREP_RERAISE_STAR 88 +#define POP_EXCEPT 89 +#define HAVE_ARGUMENT 90 +#define STORE_NAME 90 +#define DELETE_NAME 91 +#define UNPACK_SEQUENCE 92 +#define FOR_ITER 93 +#define UNPACK_EX 94 +#define STORE_ATTR 95 +#define DELETE_ATTR 96 +#define STORE_GLOBAL 97 +#define DELETE_GLOBAL 98 +#define SWAP 99 +#define LOAD_CONST 100 +#define LOAD_NAME 101 +#define BUILD_TUPLE 102 +#define BUILD_LIST 103 +#define BUILD_SET 104 +#define BUILD_MAP 105 +#define LOAD_ATTR 106 +#define COMPARE_OP 107 +#define IMPORT_NAME 108 +#define IMPORT_FROM 109 +#define JUMP_FORWARD 110 +#define JUMP_IF_FALSE_OR_POP 111 +#define JUMP_IF_TRUE_OR_POP 112 +#define JUMP_ABSOLUTE 113 +#define POP_JUMP_IF_FALSE 114 +#define POP_JUMP_IF_TRUE 115 +#define LOAD_GLOBAL 116 +#define IS_OP 117 +#define CONTAINS_OP 118 +#define RERAISE 119 +#define COPY 120 +#define JUMP_IF_NOT_EXC_MATCH 121 +#define BINARY_OP 122 +#define SEND 123 +#define LOAD_FAST 124 +#define STORE_FAST 125 +#define DELETE_FAST 126 +#define JUMP_IF_NOT_EG_MATCH 127 +#define POP_JUMP_IF_NOT_NONE 128 +#define POP_JUMP_IF_NONE 129 +#define RAISE_VARARGS 130 +#define GET_AWAITABLE 131 +#define MAKE_FUNCTION 132 +#define BUILD_SLICE 133 +#define JUMP_NO_INTERRUPT 134 +#define MAKE_CELL 135 +#define LOAD_CLOSURE 136 +#define LOAD_DEREF 137 +#define STORE_DEREF 138 +#define DELETE_DEREF 139 +#define CALL_FUNCTION_EX 142 +#define EXTENDED_ARG 144 +#define LIST_APPEND 145 +#define SET_ADD 146 +#define MAP_ADD 147 +#define LOAD_CLASSDEREF 148 +#define COPY_FREE_VARS 149 +#define RESUME 151 +#define MATCH_CLASS 152 +#define FORMAT_VALUE 155 +#define BUILD_CONST_KEY_MAP 156 +#define BUILD_STRING 157 +#define LOAD_METHOD 160 +#define LIST_EXTEND 162 +#define SET_UPDATE 163 +#define DICT_MERGE 164 +#define DICT_UPDATE 165 +#define PRECALL 166 +#define CALL 171 +#define KW_NAMES 172 +#define BINARY_OP_ADAPTIVE 3 +#define BINARY_OP_ADD_FLOAT 4 +#define BINARY_OP_ADD_INT 5 +#define BINARY_OP_ADD_UNICODE 6 +#define BINARY_OP_INPLACE_ADD_UNICODE 7 +#define BINARY_OP_MULTIPLY_FLOAT 8 +#define BINARY_OP_MULTIPLY_INT 13 +#define BINARY_OP_SUBTRACT_FLOAT 14 +#define BINARY_OP_SUBTRACT_INT 16 +#define BINARY_SUBSCR_ADAPTIVE 17 +#define BINARY_SUBSCR_DICT 18 +#define BINARY_SUBSCR_GETITEM 19 +#define BINARY_SUBSCR_LIST_INT 20 +#define BINARY_SUBSCR_TUPLE_INT 21 +#define CALL_ADAPTIVE 22 +#define CALL_PY_EXACT_ARGS 23 +#define CALL_PY_WITH_DEFAULTS 24 +#define COMPARE_OP_ADAPTIVE 26 +#define COMPARE_OP_FLOAT_JUMP 27 +#define COMPARE_OP_INT_JUMP 28 +#define COMPARE_OP_STR_JUMP 29 +#define JUMP_ABSOLUTE_QUICK 34 +#define LOAD_ATTR_ADAPTIVE 36 +#define LOAD_ATTR_INSTANCE_VALUE 37 +#define LOAD_ATTR_MODULE 38 +#define LOAD_ATTR_SLOT 39 +#define LOAD_ATTR_WITH_HINT 40 +#define LOAD_CONST__LOAD_FAST 41 +#define LOAD_FAST__LOAD_CONST 42 +#define LOAD_FAST__LOAD_FAST 43 +#define LOAD_GLOBAL_ADAPTIVE 44 +#define LOAD_GLOBAL_BUILTIN 45 +#define LOAD_GLOBAL_MODULE 46 +#define LOAD_METHOD_ADAPTIVE 47 +#define LOAD_METHOD_CLASS 48 +#define LOAD_METHOD_MODULE 55 +#define LOAD_METHOD_NO_DICT 56 +#define LOAD_METHOD_WITH_DICT 57 +#define LOAD_METHOD_WITH_VALUES 58 +#define PRECALL_ADAPTIVE 59 +#define PRECALL_BOUND_METHOD 62 +#define PRECALL_BUILTIN_CLASS 63 +#define PRECALL_BUILTIN_FAST_WITH_KEYWORDS 64 +#define PRECALL_NO_KW_BUILTIN_FAST 65 +#define PRECALL_NO_KW_BUILTIN_O 66 +#define PRECALL_NO_KW_ISINSTANCE 67 +#define PRECALL_NO_KW_LEN 72 +#define PRECALL_NO_KW_LIST_APPEND 73 +#define PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST 76 +#define PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS 77 +#define PRECALL_NO_KW_METHOD_DESCRIPTOR_O 78 +#define PRECALL_NO_KW_STR_1 79 +#define PRECALL_NO_KW_TUPLE_1 80 +#define PRECALL_NO_KW_TYPE_1 81 +#define PRECALL_PYFUNC 140 +#define RESUME_QUICK 141 +#define STORE_ATTR_ADAPTIVE 143 +#define STORE_ATTR_INSTANCE_VALUE 150 +#define STORE_ATTR_SLOT 153 +#define STORE_ATTR_WITH_HINT 154 +#define STORE_FAST__LOAD_FAST 158 +#define STORE_FAST__STORE_FAST 159 +#define STORE_SUBSCR_ADAPTIVE 161 +#define STORE_SUBSCR_DICT 167 +#define STORE_SUBSCR_LIST_INT 168 +#define UNPACK_SEQUENCE_ADAPTIVE 169 +#define UNPACK_SEQUENCE_LIST 170 +#define UNPACK_SEQUENCE_TUPLE 173 +#define UNPACK_SEQUENCE_TWO_TUPLE 174 +#define DO_TRACING 255 -extern const uint8_t _PyOpcode_InlineCacheEntries[256]; +extern const uint8_t _PyOpcode_Caches[256]; + +extern const uint8_t _PyOpcode_Deopt[256]; #ifdef NEED_OPCODE_TABLES static const uint32_t _PyOpcode_RelativeJump[8] = { @@ -209,7 +211,7 @@ static const uint32_t _PyOpcode_Jump[8] = { 0U, }; -const uint8_t _PyOpcode_InlineCacheEntries[256] = { +const uint8_t _PyOpcode_Caches[256] = { [BINARY_SUBSCR] = 4, [STORE_SUBSCR] = 1, [UNPACK_SEQUENCE] = 1, @@ -222,6 +224,184 @@ const uint8_t _PyOpcode_InlineCacheEntries[256] = { [PRECALL] = 1, [CALL] = 4, }; + +const uint8_t _PyOpcode_Deopt[256] = { + [ASYNC_GEN_WRAP] = ASYNC_GEN_WRAP, + [BEFORE_ASYNC_WITH] = BEFORE_ASYNC_WITH, + [BEFORE_WITH] = BEFORE_WITH, + [BINARY_OP] = BINARY_OP, + [BINARY_OP_ADAPTIVE] = BINARY_OP, + [BINARY_OP_ADD_FLOAT] = BINARY_OP, + [BINARY_OP_ADD_INT] = BINARY_OP, + [BINARY_OP_ADD_UNICODE] = BINARY_OP, + [BINARY_OP_INPLACE_ADD_UNICODE] = BINARY_OP, + [BINARY_OP_MULTIPLY_FLOAT] = BINARY_OP, + [BINARY_OP_MULTIPLY_INT] = BINARY_OP, + [BINARY_OP_SUBTRACT_FLOAT] = BINARY_OP, + [BINARY_OP_SUBTRACT_INT] = BINARY_OP, + [BINARY_SUBSCR] = BINARY_SUBSCR, + [BINARY_SUBSCR_ADAPTIVE] = BINARY_SUBSCR, + [BINARY_SUBSCR_DICT] = BINARY_SUBSCR, + [BINARY_SUBSCR_GETITEM] = BINARY_SUBSCR, + [BINARY_SUBSCR_LIST_INT] = BINARY_SUBSCR, + [BINARY_SUBSCR_TUPLE_INT] = BINARY_SUBSCR, + [BUILD_CONST_KEY_MAP] = BUILD_CONST_KEY_MAP, + [BUILD_LIST] = BUILD_LIST, + [BUILD_MAP] = BUILD_MAP, + [BUILD_SET] = BUILD_SET, + [BUILD_SLICE] = BUILD_SLICE, + [BUILD_STRING] = BUILD_STRING, + [BUILD_TUPLE] = BUILD_TUPLE, + [CACHE] = CACHE, + [CALL] = CALL, + [CALL_ADAPTIVE] = CALL, + [CALL_FUNCTION_EX] = CALL_FUNCTION_EX, + [CALL_PY_EXACT_ARGS] = CALL, + [CALL_PY_WITH_DEFAULTS] = CALL, + [COMPARE_OP] = COMPARE_OP, + [COMPARE_OP_ADAPTIVE] = COMPARE_OP, + [COMPARE_OP_FLOAT_JUMP] = COMPARE_OP, + [COMPARE_OP_INT_JUMP] = COMPARE_OP, + [COMPARE_OP_STR_JUMP] = COMPARE_OP, + [CONTAINS_OP] = CONTAINS_OP, + [COPY] = COPY, + [COPY_FREE_VARS] = COPY_FREE_VARS, + [DELETE_ATTR] = DELETE_ATTR, + [DELETE_DEREF] = DELETE_DEREF, + [DELETE_FAST] = DELETE_FAST, + [DELETE_GLOBAL] = DELETE_GLOBAL, + [DELETE_NAME] = DELETE_NAME, + [DELETE_SUBSCR] = DELETE_SUBSCR, + [DICT_MERGE] = DICT_MERGE, + [DICT_UPDATE] = DICT_UPDATE, + [END_ASYNC_FOR] = END_ASYNC_FOR, + [EXTENDED_ARG] = EXTENDED_ARG, + [FORMAT_VALUE] = FORMAT_VALUE, + [FOR_ITER] = FOR_ITER, + [GET_AITER] = GET_AITER, + [GET_ANEXT] = GET_ANEXT, + [GET_AWAITABLE] = GET_AWAITABLE, + [GET_ITER] = GET_ITER, + [GET_LEN] = GET_LEN, + [GET_YIELD_FROM_ITER] = GET_YIELD_FROM_ITER, + [IMPORT_FROM] = IMPORT_FROM, + [IMPORT_NAME] = IMPORT_NAME, + [IMPORT_STAR] = IMPORT_STAR, + [IS_OP] = IS_OP, + [JUMP_ABSOLUTE] = JUMP_ABSOLUTE, + [JUMP_ABSOLUTE_QUICK] = JUMP_ABSOLUTE, + [JUMP_FORWARD] = JUMP_FORWARD, + [JUMP_IF_FALSE_OR_POP] = JUMP_IF_FALSE_OR_POP, + [JUMP_IF_NOT_EG_MATCH] = JUMP_IF_NOT_EG_MATCH, + [JUMP_IF_NOT_EXC_MATCH] = JUMP_IF_NOT_EXC_MATCH, + [JUMP_IF_TRUE_OR_POP] = JUMP_IF_TRUE_OR_POP, + [JUMP_NO_INTERRUPT] = JUMP_NO_INTERRUPT, + [KW_NAMES] = KW_NAMES, + [LIST_APPEND] = LIST_APPEND, + [LIST_EXTEND] = LIST_EXTEND, + [LIST_TO_TUPLE] = LIST_TO_TUPLE, + [LOAD_ASSERTION_ERROR] = LOAD_ASSERTION_ERROR, + [LOAD_ATTR] = LOAD_ATTR, + [LOAD_ATTR_ADAPTIVE] = LOAD_ATTR, + [LOAD_ATTR_INSTANCE_VALUE] = LOAD_ATTR, + [LOAD_ATTR_MODULE] = LOAD_ATTR, + [LOAD_ATTR_SLOT] = LOAD_ATTR, + [LOAD_ATTR_WITH_HINT] = LOAD_ATTR, + [LOAD_BUILD_CLASS] = LOAD_BUILD_CLASS, + [LOAD_CLASSDEREF] = LOAD_CLASSDEREF, + [LOAD_CLOSURE] = LOAD_CLOSURE, + [LOAD_CONST] = LOAD_CONST, + [LOAD_CONST__LOAD_FAST] = LOAD_CONST, + [LOAD_DEREF] = LOAD_DEREF, + [LOAD_FAST] = LOAD_FAST, + [LOAD_FAST__LOAD_CONST] = LOAD_FAST, + [LOAD_FAST__LOAD_FAST] = LOAD_FAST, + [LOAD_GLOBAL] = LOAD_GLOBAL, + [LOAD_GLOBAL_ADAPTIVE] = LOAD_GLOBAL, + [LOAD_GLOBAL_BUILTIN] = LOAD_GLOBAL, + [LOAD_GLOBAL_MODULE] = LOAD_GLOBAL, + [LOAD_METHOD] = LOAD_METHOD, + [LOAD_METHOD_ADAPTIVE] = LOAD_METHOD, + [LOAD_METHOD_CLASS] = LOAD_METHOD, + [LOAD_METHOD_MODULE] = LOAD_METHOD, + [LOAD_METHOD_NO_DICT] = LOAD_METHOD, + [LOAD_METHOD_WITH_DICT] = LOAD_METHOD, + [LOAD_METHOD_WITH_VALUES] = LOAD_METHOD, + [LOAD_NAME] = LOAD_NAME, + [MAKE_CELL] = MAKE_CELL, + [MAKE_FUNCTION] = MAKE_FUNCTION, + [MAP_ADD] = MAP_ADD, + [MATCH_CLASS] = MATCH_CLASS, + [MATCH_KEYS] = MATCH_KEYS, + [MATCH_MAPPING] = MATCH_MAPPING, + [MATCH_SEQUENCE] = MATCH_SEQUENCE, + [NOP] = NOP, + [POP_EXCEPT] = POP_EXCEPT, + [POP_JUMP_IF_FALSE] = POP_JUMP_IF_FALSE, + [POP_JUMP_IF_NONE] = POP_JUMP_IF_NONE, + [POP_JUMP_IF_NOT_NONE] = POP_JUMP_IF_NOT_NONE, + [POP_JUMP_IF_TRUE] = POP_JUMP_IF_TRUE, + [POP_TOP] = POP_TOP, + [PRECALL] = PRECALL, + [PRECALL_ADAPTIVE] = PRECALL, + [PRECALL_BOUND_METHOD] = PRECALL, + [PRECALL_BUILTIN_CLASS] = PRECALL, + [PRECALL_BUILTIN_FAST_WITH_KEYWORDS] = PRECALL, + [PRECALL_NO_KW_BUILTIN_FAST] = PRECALL, + [PRECALL_NO_KW_BUILTIN_O] = PRECALL, + [PRECALL_NO_KW_ISINSTANCE] = PRECALL, + [PRECALL_NO_KW_LEN] = PRECALL, + [PRECALL_NO_KW_LIST_APPEND] = PRECALL, + [PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST] = PRECALL, + [PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = PRECALL, + [PRECALL_NO_KW_METHOD_DESCRIPTOR_O] = PRECALL, + [PRECALL_NO_KW_STR_1] = PRECALL, + [PRECALL_NO_KW_TUPLE_1] = PRECALL, + [PRECALL_NO_KW_TYPE_1] = PRECALL, + [PRECALL_PYFUNC] = PRECALL, + [PREP_RERAISE_STAR] = PREP_RERAISE_STAR, + [PRINT_EXPR] = PRINT_EXPR, + [PUSH_EXC_INFO] = PUSH_EXC_INFO, + [PUSH_NULL] = PUSH_NULL, + [RAISE_VARARGS] = RAISE_VARARGS, + [RERAISE] = RERAISE, + [RESUME] = RESUME, + [RESUME_QUICK] = RESUME, + [RETURN_GENERATOR] = RETURN_GENERATOR, + [RETURN_VALUE] = RETURN_VALUE, + [SEND] = SEND, + [SETUP_ANNOTATIONS] = SETUP_ANNOTATIONS, + [SET_ADD] = SET_ADD, + [SET_UPDATE] = SET_UPDATE, + [STORE_ATTR] = STORE_ATTR, + [STORE_ATTR_ADAPTIVE] = STORE_ATTR, + [STORE_ATTR_INSTANCE_VALUE] = STORE_ATTR, + [STORE_ATTR_SLOT] = STORE_ATTR, + [STORE_ATTR_WITH_HINT] = STORE_ATTR, + [STORE_DEREF] = STORE_DEREF, + [STORE_FAST] = STORE_FAST, + [STORE_FAST__LOAD_FAST] = STORE_FAST, + [STORE_FAST__STORE_FAST] = STORE_FAST, + [STORE_GLOBAL] = STORE_GLOBAL, + [STORE_NAME] = STORE_NAME, + [STORE_SUBSCR] = STORE_SUBSCR, + [STORE_SUBSCR_ADAPTIVE] = STORE_SUBSCR, + [STORE_SUBSCR_DICT] = STORE_SUBSCR, + [STORE_SUBSCR_LIST_INT] = STORE_SUBSCR, + [SWAP] = SWAP, + [UNARY_INVERT] = UNARY_INVERT, + [UNARY_NEGATIVE] = UNARY_NEGATIVE, + [UNARY_NOT] = UNARY_NOT, + [UNARY_POSITIVE] = UNARY_POSITIVE, + [UNPACK_EX] = UNPACK_EX, + [UNPACK_SEQUENCE] = UNPACK_SEQUENCE, + [UNPACK_SEQUENCE_ADAPTIVE] = UNPACK_SEQUENCE, + [UNPACK_SEQUENCE_LIST] = UNPACK_SEQUENCE, + [UNPACK_SEQUENCE_TUPLE] = UNPACK_SEQUENCE, + [UNPACK_SEQUENCE_TWO_TUPLE] = UNPACK_SEQUENCE, + [WITH_EXCEPT_START] = WITH_EXCEPT_START, + [YIELD_VALUE] = YIELD_VALUE, +}; #endif /* OPCODE_TABLES */ #define HAS_CONST(op) (false\ @@ -229,32 +409,32 @@ const uint8_t _PyOpcode_InlineCacheEntries[256] = { || ((op) == 172) \ ) -#define NB_ADD 0 -#define NB_AND 1 -#define NB_FLOOR_DIVIDE 2 -#define NB_LSHIFT 3 -#define NB_MATRIX_MULTIPLY 4 -#define NB_MULTIPLY 5 -#define NB_REMAINDER 6 -#define NB_OR 7 -#define NB_POWER 8 -#define NB_RSHIFT 9 -#define NB_SUBTRACT 10 -#define NB_TRUE_DIVIDE 11 -#define NB_XOR 12 -#define NB_INPLACE_ADD 13 -#define NB_INPLACE_AND 14 -#define NB_INPLACE_FLOOR_DIVIDE 15 -#define NB_INPLACE_LSHIFT 16 -#define NB_INPLACE_MATRIX_MULTIPLY 17 -#define NB_INPLACE_MULTIPLY 18 -#define NB_INPLACE_REMAINDER 19 -#define NB_INPLACE_OR 20 -#define NB_INPLACE_POWER 21 -#define NB_INPLACE_RSHIFT 22 -#define NB_INPLACE_SUBTRACT 23 -#define NB_INPLACE_TRUE_DIVIDE 24 -#define NB_INPLACE_XOR 25 +#define NB_ADD 0 +#define NB_AND 1 +#define NB_FLOOR_DIVIDE 2 +#define NB_LSHIFT 3 +#define NB_MATRIX_MULTIPLY 4 +#define NB_MULTIPLY 5 +#define NB_REMAINDER 6 +#define NB_OR 7 +#define NB_POWER 8 +#define NB_RSHIFT 9 +#define NB_SUBTRACT 10 +#define NB_TRUE_DIVIDE 11 +#define NB_XOR 12 +#define NB_INPLACE_ADD 13 +#define NB_INPLACE_AND 14 +#define NB_INPLACE_FLOOR_DIVIDE 15 +#define NB_INPLACE_LSHIFT 16 +#define NB_INPLACE_MATRIX_MULTIPLY 17 +#define NB_INPLACE_MULTIPLY 18 +#define NB_INPLACE_REMAINDER 19 +#define NB_INPLACE_OR 20 +#define NB_INPLACE_POWER 21 +#define NB_INPLACE_RSHIFT 22 +#define NB_INPLACE_SUBTRACT 23 +#define NB_INPLACE_TRUE_DIVIDE 24 +#define NB_INPLACE_XOR 25 #define HAS_ARG(op) ((op) >= HAVE_ARGUMENT) diff --git a/Lib/opcode.py b/Lib/opcode.py index eb9dd35fabf8d..7a52c13579af7 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -229,77 +229,111 @@ def jabs_op(name, op, entries=0): ("NB_INPLACE_XOR", "^="), ] +_specializations = { + "BINARY_OP": [ + "BINARY_OP_ADAPTIVE", + "BINARY_OP_ADD_FLOAT", + "BINARY_OP_ADD_INT", + "BINARY_OP_ADD_UNICODE", + "BINARY_OP_INPLACE_ADD_UNICODE", + "BINARY_OP_MULTIPLY_FLOAT", + "BINARY_OP_MULTIPLY_INT", + "BINARY_OP_SUBTRACT_FLOAT", + "BINARY_OP_SUBTRACT_INT", + ], + "BINARY_SUBSCR": [ + "BINARY_SUBSCR_ADAPTIVE", + "BINARY_SUBSCR_DICT", + "BINARY_SUBSCR_GETITEM", + "BINARY_SUBSCR_LIST_INT", + "BINARY_SUBSCR_TUPLE_INT", + ], + "CALL": [ + "CALL_ADAPTIVE", + "CALL_PY_EXACT_ARGS", + "CALL_PY_WITH_DEFAULTS", + ], + "COMPARE_OP": [ + "COMPARE_OP_ADAPTIVE", + "COMPARE_OP_FLOAT_JUMP", + "COMPARE_OP_INT_JUMP", + "COMPARE_OP_STR_JUMP", + ], + "JUMP_ABSOLUTE": [ + "JUMP_ABSOLUTE_QUICK", + ], + "LOAD_ATTR": [ + "LOAD_ATTR_ADAPTIVE", + "LOAD_ATTR_INSTANCE_VALUE", + "LOAD_ATTR_MODULE", + "LOAD_ATTR_SLOT", + "LOAD_ATTR_WITH_HINT", + ], + "LOAD_CONST": [ + "LOAD_CONST__LOAD_FAST", + ], + "LOAD_FAST": [ + "LOAD_FAST__LOAD_CONST", + "LOAD_FAST__LOAD_FAST", + ], + "LOAD_GLOBAL": [ + "LOAD_GLOBAL_ADAPTIVE", + "LOAD_GLOBAL_BUILTIN", + "LOAD_GLOBAL_MODULE", + ], + "LOAD_METHOD": [ + "LOAD_METHOD_ADAPTIVE", + "LOAD_METHOD_CLASS", + "LOAD_METHOD_MODULE", + "LOAD_METHOD_NO_DICT", + "LOAD_METHOD_WITH_DICT", + "LOAD_METHOD_WITH_VALUES", + ], + "PRECALL": [ + "PRECALL_ADAPTIVE", + "PRECALL_BOUND_METHOD", + "PRECALL_BUILTIN_CLASS", + "PRECALL_BUILTIN_FAST_WITH_KEYWORDS", + "PRECALL_NO_KW_BUILTIN_FAST", + "PRECALL_NO_KW_BUILTIN_O", + "PRECALL_NO_KW_ISINSTANCE", + "PRECALL_NO_KW_LEN", + "PRECALL_NO_KW_LIST_APPEND", + "PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST", + "PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS", + "PRECALL_NO_KW_METHOD_DESCRIPTOR_O", + "PRECALL_NO_KW_STR_1", + "PRECALL_NO_KW_TUPLE_1", + "PRECALL_NO_KW_TYPE_1", + "PRECALL_PYFUNC", + ], + "RESUME": [ + "RESUME_QUICK", + ], + "STORE_ATTR": [ + "STORE_ATTR_ADAPTIVE", + "STORE_ATTR_INSTANCE_VALUE", + "STORE_ATTR_SLOT", + "STORE_ATTR_WITH_HINT", + ], + "STORE_FAST": [ + "STORE_FAST__LOAD_FAST", + "STORE_FAST__STORE_FAST", + ], + "STORE_SUBSCR": [ + "STORE_SUBSCR_ADAPTIVE", + "STORE_SUBSCR_DICT", + "STORE_SUBSCR_LIST_INT", + ], + "UNPACK_SEQUENCE": [ + "UNPACK_SEQUENCE_ADAPTIVE", + "UNPACK_SEQUENCE_LIST", + "UNPACK_SEQUENCE_TUPLE", + "UNPACK_SEQUENCE_TWO_TUPLE", + ], +} _specialized_instructions = [ - "BINARY_OP_ADAPTIVE", - "BINARY_OP_ADD_INT", - "BINARY_OP_ADD_FLOAT", - "BINARY_OP_ADD_UNICODE", - "BINARY_OP_INPLACE_ADD_UNICODE", - "BINARY_OP_MULTIPLY_INT", - "BINARY_OP_MULTIPLY_FLOAT", - "BINARY_OP_SUBTRACT_INT", - "BINARY_OP_SUBTRACT_FLOAT", - "COMPARE_OP_ADAPTIVE", - "COMPARE_OP_FLOAT_JUMP", - "COMPARE_OP_INT_JUMP", - "COMPARE_OP_STR_JUMP", - "BINARY_SUBSCR_ADAPTIVE", - "BINARY_SUBSCR_GETITEM", - "BINARY_SUBSCR_LIST_INT", - "BINARY_SUBSCR_TUPLE_INT", - "BINARY_SUBSCR_DICT", - "STORE_SUBSCR_ADAPTIVE", - "STORE_SUBSCR_LIST_INT", - "STORE_SUBSCR_DICT", - "CALL_ADAPTIVE", - "CALL_PY_EXACT_ARGS", - "CALL_PY_WITH_DEFAULTS", - "JUMP_ABSOLUTE_QUICK", - "LOAD_ATTR_ADAPTIVE", - "LOAD_ATTR_INSTANCE_VALUE", - "LOAD_ATTR_WITH_HINT", - "LOAD_ATTR_SLOT", - "LOAD_ATTR_MODULE", - "LOAD_GLOBAL_ADAPTIVE", - "LOAD_GLOBAL_MODULE", - "LOAD_GLOBAL_BUILTIN", - "LOAD_METHOD_ADAPTIVE", - "LOAD_METHOD_CLASS", - "LOAD_METHOD_MODULE", - "LOAD_METHOD_NO_DICT", - "LOAD_METHOD_WITH_DICT", - "LOAD_METHOD_WITH_VALUES", - "PRECALL_ADAPTIVE", - "PRECALL_BUILTIN_CLASS", - "PRECALL_NO_KW_BUILTIN_O", - "PRECALL_NO_KW_BUILTIN_FAST", - "PRECALL_BUILTIN_FAST_WITH_KEYWORDS", - "PRECALL_NO_KW_LEN", - "PRECALL_NO_KW_ISINSTANCE", - "PRECALL_NO_KW_LIST_APPEND", - "PRECALL_NO_KW_METHOD_DESCRIPTOR_O", - "PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS", - "PRECALL_NO_KW_STR_1", - "PRECALL_NO_KW_TUPLE_1", - "PRECALL_NO_KW_TYPE_1", - "PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST", - "PRECALL_BOUND_METHOD", - "PRECALL_PYFUNC", - "RESUME_QUICK", - "STORE_ATTR_ADAPTIVE", - "STORE_ATTR_INSTANCE_VALUE", - "STORE_ATTR_SLOT", - "STORE_ATTR_WITH_HINT", - "UNPACK_SEQUENCE_ADAPTIVE", - "UNPACK_SEQUENCE_LIST", - "UNPACK_SEQUENCE_TUPLE", - "UNPACK_SEQUENCE_TWO_TUPLE", - # Super instructions - "LOAD_FAST__LOAD_FAST", - "STORE_FAST__LOAD_FAST", - "LOAD_FAST__LOAD_CONST", - "LOAD_CONST__LOAD_FAST", - "STORE_FAST__STORE_FAST", + opcode for family in _specializations.values() for opcode in family ] _specialization_stats = [ "success", diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 8499d2855bdd4..a4e80805d3e5c 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -641,7 +641,7 @@ def check_same_constant(const): self.check_constant(f1, frozenset({0})) self.assertTrue(f1(0)) - # Merging equal co_linetable and co_code is not a strict requirement + # Merging equal co_linetable is not a strict requirement # for the Python semantics, it's a more an implementation detail. @support.cpython_only def test_merge_code_attrs(self): @@ -650,7 +650,6 @@ def test_merge_code_attrs(self): f2 = lambda a: a.b.c self.assertIs(f1.__code__.co_linetable, f2.__code__.co_linetable) - self.assertIs(f1.__code__.co_code, f2.__code__.co_code) # Stripping unused constants is not a strict requirement for the # Python semantics, it's a more an implementation detail. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-16-11-05-35.bpo-46841.yUoIHg.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-16-11-05-35.bpo-46841.yUoIHg.rst new file mode 100644 index 0000000000000..99fad382d13bb --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-16-11-05-35.bpo-46841.yUoIHg.rst @@ -0,0 +1,2 @@ +Quicken bytecode in-place by storing it as part of the corresponding +``PyCodeObject``. diff --git a/Objects/clinic/codeobject.c.h b/Objects/clinic/codeobject.c.h index ee425f61bb113..272bcd6ea17b2 100644 --- a/Objects/clinic/codeobject.c.h +++ b/Objects/clinic/codeobject.c.h @@ -203,12 +203,12 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje int co_stacksize = self->co_stacksize; int co_flags = self->co_flags; int co_firstlineno = self->co_firstlineno; - PyBytesObject *co_code = (PyBytesObject *)self->co_code; + PyBytesObject *co_code = NULL; PyObject *co_consts = self->co_consts; PyObject *co_names = self->co_names; - PyObject *co_varnames = self->co_varnames; - PyObject *co_freevars = self->co_freevars; - PyObject *co_cellvars = self->co_cellvars; + PyObject *co_varnames = NULL; + PyObject *co_freevars = NULL; + PyObject *co_cellvars = NULL; PyObject *co_filename = self->co_filename; PyObject *co_name = self->co_name; PyObject *co_qualname = self->co_qualname; @@ -456,4 +456,4 @@ code__varname_from_oparg(PyCodeObject *self, PyObject *const *args, Py_ssize_t n exit: return return_value; } -/*[clinic end generated code: output=9e8c4a19474ec520 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b1b83a70ffc5b7cd input=a9049054013a1b77]*/ diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 5279f6ce17064..224493edb19ea 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -305,9 +305,6 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con) co->co_qualname = con->qualname; co->co_flags = con->flags; - Py_INCREF(con->code); - co->co_code = con->code; - co->co_firstinstr = (_Py_CODEUNIT *)PyBytes_AS_STRING(con->code); co->co_firstlineno = con->firstlineno; Py_INCREF(con->linetable); co->co_linetable = con->linetable; @@ -341,16 +338,14 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con) co->co_nplaincellvars = nplaincellvars; co->co_ncellvars = ncellvars; co->co_nfreevars = nfreevars; - co->co_varnames = NULL; - co->co_cellvars = NULL; - co->co_freevars = NULL; /* not set */ co->co_weakreflist = NULL; co->co_extra = NULL; co->co_warmup = QUICKENING_INITIAL_WARMUP_VALUE; - co->co_quickened = NULL; + memcpy(_PyCode_CODE(co), PyBytes_AS_STRING(con->code), + PyBytes_GET_SIZE(con->code)); } /* The caller is responsible for ensuring that the given data is valid. */ @@ -386,7 +381,8 @@ _PyCode_New(struct _PyCodeConstructor *con) con->columntable = Py_None; } - PyCodeObject *co = PyObject_New(PyCodeObject, &PyCode_Type); + Py_ssize_t size = PyBytes_GET_SIZE(con->code) / sizeof(_Py_CODEUNIT); + PyCodeObject *co = PyObject_NewVar(PyCodeObject, &PyCode_Type, size); if (co == NULL) { PyErr_NoMemory(); return NULL; @@ -521,13 +517,6 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, goto error; } - Py_INCREF(varnames); - co->co_varnames = varnames; - Py_INCREF(cellvars); - co->co_cellvars = cellvars; - Py_INCREF(freevars); - co->co_freevars = freevars; - error: Py_XDECREF(localsplusnames); Py_XDECREF(localspluskinds); @@ -611,7 +600,7 @@ PyCode_Addr2Line(PyCodeObject *co, int addrq) if (addrq < 0) { return co->co_firstlineno; } - assert(addrq >= 0 && addrq < PyBytes_GET_SIZE(co->co_code)); + assert(addrq >= 0 && addrq < _PyCode_NBYTES(co)); PyCodeAddressRange bounds; _PyCode_InitAddressRange(co, &bounds); return _PyCode_CheckLineNumber(addrq, &bounds); @@ -639,7 +628,7 @@ _PyCode_Addr2EndLine(PyCodeObject* co, int addrq) return -1; } - assert(addrq >= 0 && addrq < PyBytes_GET_SIZE(co->co_code)); + assert(addrq >= 0 && addrq < _PyCode_NBYTES(co)); PyCodeAddressRange bounds; _PyCode_InitEndAddressRange(co, &bounds); return _PyCode_CheckLineNumber(addrq, &bounds); @@ -995,7 +984,7 @@ _source_offset_converter(int* value) { static PyObject* positionsiter_next(positionsiterator* pi) { - if (pi->pi_offset >= PyBytes_GET_SIZE(pi->pi_code->co_code)) { + if (pi->pi_offset >= _PyCode_NBYTES(pi->pi_code)) { return NULL; } @@ -1151,46 +1140,39 @@ _PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra) PyObject * _PyCode_GetVarnames(PyCodeObject *co) { - if (co->co_varnames == NULL) { - // PyCodeObject owns this reference. - co->co_varnames = get_localsplus_names(co, CO_FAST_LOCAL, - co->co_nlocals); - if (co->co_varnames == NULL) { - return NULL; - } - } - Py_INCREF(co->co_varnames); - return co->co_varnames; + return get_localsplus_names(co, CO_FAST_LOCAL, co->co_nlocals); } PyObject * _PyCode_GetCellvars(PyCodeObject *co) { - if (co->co_cellvars == NULL) { - // PyCodeObject owns this reference. - co->co_cellvars = get_localsplus_names(co, CO_FAST_CELL, - co->co_ncellvars); - if (co->co_cellvars == NULL) { - return NULL; - } - } - Py_INCREF(co->co_cellvars); - return co->co_cellvars; + return get_localsplus_names(co, CO_FAST_CELL, co->co_ncellvars); } PyObject * _PyCode_GetFreevars(PyCodeObject *co) { - if (co->co_freevars == NULL) { - // PyCodeObject owns this reference. - co->co_freevars = get_localsplus_names(co, CO_FAST_FREE, - co->co_nfreevars); - if (co->co_freevars == NULL) { - return NULL; + return get_localsplus_names(co, CO_FAST_FREE, co->co_nfreevars); +} + +PyObject * +_PyCode_GetCode(PyCodeObject *co) +{ + PyObject *code = PyBytes_FromStringAndSize(NULL, _PyCode_NBYTES(co)); + if (code == NULL) { + return NULL; + } + _Py_CODEUNIT *instructions = (_Py_CODEUNIT *)PyBytes_AS_STRING(code); + for (int i = 0; i < Py_SIZE(co); i++) { + _Py_CODEUNIT instruction = _PyCode_CODE(co)[i]; + int opcode = _PyOpcode_Deopt[_Py_OPCODE(instruction)]; + int caches = _PyOpcode_Caches[opcode]; + instructions[i] = _Py_MAKECODEUNIT(opcode, _Py_OPARG(instruction)); + while (caches--) { + instructions[++i] = _Py_MAKECODEUNIT(CACHE, 0); } } - Py_INCREF(co->co_freevars); - return co->co_freevars; + return code; } @@ -1348,14 +1330,10 @@ code_dealloc(PyCodeObject *co) PyMem_Free(co_extra); } - Py_XDECREF(co->co_code); Py_XDECREF(co->co_consts); Py_XDECREF(co->co_names); Py_XDECREF(co->co_localsplusnames); Py_XDECREF(co->co_localspluskinds); - Py_XDECREF(co->co_varnames); - Py_XDECREF(co->co_freevars); - Py_XDECREF(co->co_cellvars); Py_XDECREF(co->co_filename); Py_XDECREF(co->co_name); Py_XDECREF(co->co_qualname); @@ -1363,10 +1341,10 @@ code_dealloc(PyCodeObject *co) Py_XDECREF(co->co_endlinetable); Py_XDECREF(co->co_columntable); Py_XDECREF(co->co_exceptiontable); - if (co->co_weakreflist != NULL) + if (co->co_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject*)co); - if (co->co_quickened) { - PyMem_Free(co->co_quickened); + } + if (co->co_warmup == 0) { _Py_QuickenedCount--; } PyObject_Free(co); @@ -1420,8 +1398,21 @@ code_richcompare(PyObject *self, PyObject *other, int op) if (!eq) goto unequal; eq = co->co_firstlineno == cp->co_firstlineno; if (!eq) goto unequal; - eq = PyObject_RichCompareBool(co->co_code, cp->co_code, Py_EQ); - if (eq <= 0) goto unequal; + PyObject *co_code = _PyCode_GetCode(co); + if (co_code == NULL) { + return NULL; + } + PyObject *cp_code = _PyCode_GetCode(cp); + if (cp_code == NULL) { + Py_DECREF(co_code); + return NULL; + } + eq = PyObject_RichCompareBool(co_code, cp_code, Py_EQ); + Py_DECREF(co_code); + Py_DECREF(cp_code); + if (eq <= 0) { + goto unequal; + } /* compare constants */ consts1 = _PyCode_ConstantKey(co->co_consts); @@ -1465,18 +1456,16 @@ code_richcompare(PyObject *self, PyObject *other, int op) static Py_hash_t code_hash(PyCodeObject *co) { - Py_hash_t h, h0, h1, h2, h3, h4; + Py_hash_t h, h0, h1, h2, h3; h0 = PyObject_Hash(co->co_name); if (h0 == -1) return -1; - h1 = PyObject_Hash(co->co_code); + h1 = PyObject_Hash(co->co_consts); if (h1 == -1) return -1; - h2 = PyObject_Hash(co->co_consts); + h2 = PyObject_Hash(co->co_names); if (h2 == -1) return -1; - h3 = PyObject_Hash(co->co_names); + h3 = PyObject_Hash(co->co_localsplusnames); if (h3 == -1) return -1; - h4 = PyObject_Hash(co->co_localsplusnames); - if (h4 == -1) return -1; - h = h0 ^ h1 ^ h2 ^ h3 ^ h4 ^ + h = h0 ^ h1 ^ h2 ^ h3 ^ co->co_argcount ^ co->co_posonlyargcount ^ co->co_kwonlyargcount ^ co->co_flags; if (h == -1) h = -2; @@ -1487,22 +1476,22 @@ code_hash(PyCodeObject *co) #define OFF(x) offsetof(PyCodeObject, x) static PyMemberDef code_memberlist[] = { - {"co_argcount", T_INT, OFF(co_argcount), READONLY}, - {"co_posonlyargcount", T_INT, OFF(co_posonlyargcount), READONLY}, - {"co_kwonlyargcount", T_INT, OFF(co_kwonlyargcount), READONLY}, - {"co_stacksize",T_INT, OFF(co_stacksize), READONLY}, - {"co_flags", T_INT, OFF(co_flags), READONLY}, - {"co_code", T_OBJECT, OFF(co_code), READONLY}, - {"co_consts", T_OBJECT, OFF(co_consts), READONLY}, - {"co_names", T_OBJECT, OFF(co_names), READONLY}, - {"co_filename", T_OBJECT, OFF(co_filename), READONLY}, - {"co_name", T_OBJECT, OFF(co_name), READONLY}, - {"co_qualname", T_OBJECT, OFF(co_qualname), READONLY}, - {"co_firstlineno", T_INT, OFF(co_firstlineno), READONLY}, - {"co_linetable", T_OBJECT, OFF(co_linetable), READONLY}, - {"co_endlinetable", T_OBJECT, OFF(co_endlinetable), READONLY}, - {"co_columntable", T_OBJECT, OFF(co_columntable), READONLY}, - {"co_exceptiontable", T_OBJECT, OFF(co_exceptiontable), READONLY}, + {"co_argcount", T_INT, OFF(co_argcount), READONLY}, + {"co_posonlyargcount", T_INT, OFF(co_posonlyargcount), READONLY}, + {"co_kwonlyargcount", T_INT, OFF(co_kwonlyargcount), READONLY}, + {"co_stacksize", T_INT, OFF(co_stacksize), READONLY}, + {"co_flags", T_INT, OFF(co_flags), READONLY}, + {"co_nlocals", T_INT, OFF(co_nlocals), READONLY}, + {"co_consts", T_OBJECT, OFF(co_consts), READONLY}, + {"co_names", T_OBJECT, OFF(co_names), READONLY}, + {"co_filename", T_OBJECT, OFF(co_filename), READONLY}, + {"co_name", T_OBJECT, OFF(co_name), READONLY}, + {"co_qualname", T_OBJECT, OFF(co_qualname), READONLY}, + {"co_firstlineno", T_INT, OFF(co_firstlineno), READONLY}, + {"co_linetable", T_OBJECT, OFF(co_linetable), READONLY}, + {"co_endlinetable", T_OBJECT, OFF(co_endlinetable), READONLY}, + {"co_columntable", T_OBJECT, OFF(co_columntable), READONLY}, + {"co_exceptiontable", T_OBJECT, OFF(co_exceptiontable), READONLY}, {NULL} /* Sentinel */ }; @@ -1513,12 +1502,6 @@ code_getlnotab(PyCodeObject *code, void *closure) return decode_linetable(code); } -static PyObject * -code_getnlocals(PyCodeObject *code, void *closure) -{ - return PyLong_FromLong(code->co_nlocals); -} - static PyObject * code_getvarnames(PyCodeObject *code, void *closure) { @@ -1538,23 +1521,26 @@ code_getfreevars(PyCodeObject *code, void *closure) } static PyObject * -code_getquickened(PyCodeObject *code, void *closure) +code_getcodeadaptive(PyCodeObject *code, void *closure) { - if (code->co_quickened == NULL) { - Py_RETURN_NONE; - } - return PyBytes_FromStringAndSize((char *)code->co_firstinstr, - PyBytes_Size(code->co_code)); + return PyMemoryView_FromMemory(code->co_code_adaptive, _PyCode_NBYTES(code), + PyBUF_READ); +} + +static PyObject * +code_getcode(PyCodeObject *code, void *closure) +{ + return _PyCode_GetCode(code); } static PyGetSetDef code_getsetlist[] = { - {"co_lnotab", (getter)code_getlnotab, NULL, NULL}, + {"co_lnotab", (getter)code_getlnotab, NULL, NULL}, + {"_co_code_adaptive", (getter)code_getcodeadaptive, NULL, NULL}, // The following old names are kept for backward compatibility. - {"co_nlocals", (getter)code_getnlocals, NULL, NULL}, - {"co_varnames", (getter)code_getvarnames, NULL, NULL}, - {"co_cellvars", (getter)code_getcellvars, NULL, NULL}, - {"co_freevars", (getter)code_getfreevars, NULL, NULL}, - {"_co_quickened", (getter)code_getquickened, NULL, NULL}, + {"co_varnames", (getter)code_getvarnames, NULL, NULL}, + {"co_cellvars", (getter)code_getcellvars, NULL, NULL}, + {"co_freevars", (getter)code_getfreevars, NULL, NULL}, + {"co_code", (getter)code_getcode, NULL, NULL}, {0} }; @@ -1562,7 +1548,7 @@ static PyGetSetDef code_getsetlist[] = { static PyObject * code_sizeof(PyCodeObject *co, PyObject *Py_UNUSED(args)) { - Py_ssize_t res = _PyObject_SIZE(Py_TYPE(co)); + Py_ssize_t res = _PyObject_VAR_SIZE(Py_TYPE(co), Py_SIZE(co)); _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) co->co_extra; if (co_extra != NULL) { @@ -1570,10 +1556,6 @@ code_sizeof(PyCodeObject *co, PyObject *Py_UNUSED(args)) (co_extra->ce_size-1) * sizeof(co_extra->ce_extras[0]); } - if (co->co_quickened != NULL) { - res += PyBytes_GET_SIZE(co->co_code); - } - return PyLong_FromSsize_t(res); } @@ -1594,12 +1576,12 @@ code.replace co_stacksize: int(c_default="self->co_stacksize") = -1 co_flags: int(c_default="self->co_flags") = -1 co_firstlineno: int(c_default="self->co_firstlineno") = -1 - co_code: PyBytesObject(c_default="(PyBytesObject *)self->co_code") = None + co_code: PyBytesObject(c_default="NULL") = None co_consts: object(subclass_of="&PyTuple_Type", c_default="self->co_consts") = None co_names: object(subclass_of="&PyTuple_Type", c_default="self->co_names") = None - co_varnames: object(subclass_of="&PyTuple_Type", c_default="self->co_varnames") = None - co_freevars: object(subclass_of="&PyTuple_Type", c_default="self->co_freevars") = None - co_cellvars: object(subclass_of="&PyTuple_Type", c_default="self->co_cellvars") = None + co_varnames: object(subclass_of="&PyTuple_Type", c_default="NULL") = None + co_freevars: object(subclass_of="&PyTuple_Type", c_default="NULL") = None + co_cellvars: object(subclass_of="&PyTuple_Type", c_default="NULL") = None co_filename: unicode(c_default="self->co_filename") = None co_name: unicode(c_default="self->co_name") = None co_qualname: unicode(c_default="self->co_qualname") = None @@ -1622,7 +1604,7 @@ code_replace_impl(PyCodeObject *self, int co_argcount, PyObject *co_name, PyObject *co_qualname, PyBytesObject *co_linetable, PyObject *co_endlinetable, PyObject *co_columntable, PyBytesObject *co_exceptiontable) -/*[clinic end generated code: output=f046bf0be3bab91f input=a63d09f248f00794]*/ +/*[clinic end generated code: output=f046bf0be3bab91f input=78dbe204dbd06c2f]*/ { #define CHECK_INT_ARG(ARG) \ if (ARG < 0) { \ @@ -1641,6 +1623,15 @@ code_replace_impl(PyCodeObject *self, int co_argcount, #undef CHECK_INT_ARG + PyObject *code = NULL; + if (co_code == NULL) { + code = _PyCode_GetCode(self); + if (code == NULL) { + return NULL; + } + co_code = (PyBytesObject *)code; + } + if (PySys_Audit("code.__new__", "OOOiiiiii", co_code, co_filename, co_name, co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals, @@ -1694,6 +1685,7 @@ code_replace_impl(PyCodeObject *self, int co_argcount, (PyObject*)co_exceptiontable); error: + Py_XDECREF(code); Py_XDECREF(varnames); Py_XDECREF(cellvars); Py_XDECREF(freevars); @@ -1737,8 +1729,8 @@ static struct PyMethodDef code_methods[] = { PyTypeObject PyCode_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "code", - sizeof(PyCodeObject), - 0, + offsetof(PyCodeObject, co_code_adaptive), + sizeof(_Py_CODEUNIT), (destructor)code_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ @@ -1913,15 +1905,12 @@ _PyCode_ConstantKey(PyObject *op) void _PyStaticCode_Dealloc(PyCodeObject *co) { - if (co->co_quickened) { - PyMem_Free(co->co_quickened); - co->co_quickened = NULL; + if (co->co_warmup == 0) { _Py_QuickenedCount--; } co->co_warmup = QUICKENING_INITIAL_WARMUP_VALUE; PyMem_Free(co->co_extra); co->co_extra = NULL; - co->co_firstinstr = (_Py_CODEUNIT *)PyBytes_AS_STRING(co->co_code); if (co->co_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject *)co); co->co_weakreflist = NULL; diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 73b6c3d9f8ab7..7ccd300e2b454 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -105,8 +105,9 @@ frame_getback(PyFrameObject *f, void *closure) return res; } -/* Given the index of the effective opcode, - scan back to construct the oparg with EXTENDED_ARG */ +// Given the index of the effective opcode, scan back to construct the oparg +// with EXTENDED_ARG. This only works correctly with *unquickened* code, +// obtained via a call to _PyCode_GetCode! static unsigned int get_arg(const _Py_CODEUNIT *codestr, Py_ssize_t i) { @@ -170,13 +171,17 @@ top_of_stack(int64_t stack) static int64_t * mark_stacks(PyCodeObject *code_obj, int len) { - const _Py_CODEUNIT *code = - (const _Py_CODEUNIT *)PyBytes_AS_STRING(code_obj->co_code); + PyObject *co_code = _PyCode_GetCode(code_obj); + if (co_code == NULL) { + return NULL; + } + _Py_CODEUNIT *code = (_Py_CODEUNIT *)PyBytes_AS_STRING(co_code); int64_t *stacks = PyMem_New(int64_t, len+1); int i, j, opcode; if (stacks == NULL) { PyErr_NoMemory(); + Py_DECREF(co_code); return NULL; } for (int i = 1; i <= len; i++) { @@ -304,6 +309,7 @@ mark_stacks(PyCodeObject *code_obj, int len) } } } + Py_DECREF(co_code); return stacks; } @@ -493,7 +499,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore /* PyCode_NewWithPosOnlyArgs limits co_code to be under INT_MAX so this * should never overflow. */ - int len = (int)(PyBytes_GET_SIZE(f->f_frame->f_code->co_code) / sizeof(_Py_CODEUNIT)); + int len = (int)Py_SIZE(f->f_frame->f_code); int *lines = marklines(f->f_frame->f_code, len); if (lines == NULL) { return -1; @@ -838,12 +844,23 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, static int _PyFrame_OpAlreadyRan(_PyInterpreterFrame *frame, int opcode, int oparg) { - const _Py_CODEUNIT *code = - (const _Py_CODEUNIT *)PyBytes_AS_STRING(frame->f_code->co_code); + // This only works when opcode is a non-quickened form: + assert(_PyOpcode_Deopt[opcode] == opcode); + int check_oparg = 0; for (int i = 0; i < frame->f_lasti; i++) { - if (_Py_OPCODE(code[i]) == opcode && _Py_OPARG(code[i]) == oparg) { + _Py_CODEUNIT instruction = _PyCode_CODE(frame->f_code)[i]; + int check_opcode = _PyOpcode_Deopt[_Py_OPCODE(instruction)]; + check_oparg |= _Py_OPARG(instruction); + if (check_opcode == opcode && check_oparg == oparg) { return 1; } + if (check_opcode == EXTENDED_ARG) { + check_oparg <<= 8; + } + else { + check_oparg = 0; + } + i += _PyOpcode_Caches[check_opcode]; } return 0; } @@ -862,7 +879,10 @@ _PyFrame_FastToLocalsWithError(_PyInterpreterFrame *frame) { } co = frame->f_code; fast = _PyFrame_GetLocalsArray(frame); - if (frame->f_lasti < 0 && _Py_OPCODE(co->co_firstinstr[0]) == COPY_FREE_VARS) { + // COPY_FREE_VARS has no quickened forms, so no need to use _PyOpcode_Deopt + // here: + if (frame->f_lasti < 0 && _Py_OPCODE(_PyCode_CODE(co)[0]) == COPY_FREE_VARS) + { /* Free vars have not been initialized -- Do that */ PyCodeObject *co = frame->f_code; PyObject *closure = frame->f_func->func_closure; @@ -872,6 +892,7 @@ _PyFrame_FastToLocalsWithError(_PyInterpreterFrame *frame) { Py_INCREF(o); frame->localsplus[offset + i] = o; } + // COPY_FREE_VARS doesn't have inline CACHEs, either: frame->f_lasti = 0; } for (int i = 0; i < co->co_nlocalsplus; i++) { diff --git a/Objects/genobject.c b/Objects/genobject.c index 6551b939c4590..3ad8dc1c45942 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -349,19 +349,17 @@ _PyGen_yf(PyGenObject *gen) if (gen->gi_frame_valid) { _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe; - PyObject *bytecode = gen->gi_code->co_code; - unsigned char *code = (unsigned char *)PyBytes_AS_STRING(bytecode); if (frame->f_lasti < 1) { /* Return immediately if the frame didn't start yet. SEND always come after LOAD_CONST: a code object should not start with SEND */ - assert(code[0] != SEND); + assert(_Py_OPCODE(_PyCode_CODE(gen->gi_code)[0]) != SEND); return NULL; } - int opcode = code[(frame->f_lasti+1)*sizeof(_Py_CODEUNIT)]; - int oparg = code[(frame->f_lasti+1)*sizeof(_Py_CODEUNIT)+1]; - if (opcode != RESUME || oparg < 2) { + _Py_CODEUNIT next = _PyCode_CODE(gen->gi_code)[frame->f_lasti + 1]; + if (_PyOpcode_Deopt[_Py_OPCODE(next)] != RESUME || _Py_OPARG(next) < 2) + { /* Not in a yield from */ return NULL; } @@ -485,14 +483,15 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, ret = _PyFrame_StackPop((_PyInterpreterFrame *)gen->gi_iframe); assert(ret == yf); Py_DECREF(ret); + // XXX: Performing this jump ourselves is awkward and problematic. + // See https://github.com/python/cpython/pull/31968. /* Termination repetition of SEND loop */ assert(frame->f_lasti >= 0); - PyObject *bytecode = gen->gi_code->co_code; - unsigned char *code = (unsigned char *)PyBytes_AS_STRING(bytecode); + _Py_CODEUNIT *code = _PyCode_CODE(gen->gi_code); /* Backup to SEND */ frame->f_lasti--; - assert(code[frame->f_lasti*sizeof(_Py_CODEUNIT)] == SEND); - int jump = code[frame->f_lasti*sizeof(_Py_CODEUNIT)+1]; + assert(_Py_OPCODE(code[frame->f_lasti]) == SEND); + int jump = _Py_OPARG(code[frame->f_lasti]); frame->f_lasti += jump; if (_PyGen_FetchStopIterationValue(&val) == 0) { ret = gen_send(gen, val); diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 7879515075613..4bed3ef49289a 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -8949,7 +8949,10 @@ super_init_without_args(_PyInterpreterFrame *cframe, PyCodeObject *co, // "firstarg" is a cell here unless (very unlikely) super() // was called from the C-API before the first MAKE_CELL op. if (cframe->f_lasti >= 0) { - assert(_Py_OPCODE(*co->co_firstinstr) == MAKE_CELL || _Py_OPCODE(*co->co_firstinstr) == COPY_FREE_VARS); + // MAKE_CELL and COPY_FREE_VARS have no quickened forms, so no need + // to use _PyOpcode_Deopt here: + assert(_Py_OPCODE(_PyCode_CODE(co)[0]) == MAKE_CELL || + _Py_OPCODE(_PyCode_CODE(co)[0]) == COPY_FREE_VARS); assert(PyCell_Check(firstarg)); firstarg = PyCell_GET(firstarg); } diff --git a/Python/ceval.c b/Python/ceval.c index 6f449e3172d08..7c6bfd46900e6 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1327,9 +1327,8 @@ eval_frame_handle_pending(PyThreadState *tstate) /* Get opcode and oparg from original instructions, not quickened form. */ #define TRACING_NEXTOPARG() do { \ - _Py_CODEUNIT word = ((_Py_CODEUNIT *)PyBytes_AS_STRING(frame->f_code->co_code))[INSTR_OFFSET()]; \ - opcode = _Py_OPCODE(word); \ - oparg = _Py_OPARG(word); \ + NEXTOPARG(); \ + opcode = _PyOpcode_Deopt[opcode]; \ } while (0) /* OpCode prediction macros @@ -1650,9 +1649,10 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int PyCodeObject *co = frame->f_code; \ names = co->co_names; \ consts = co->co_consts; \ - first_instr = co->co_firstinstr; \ + first_instr = _PyCode_CODE(co); \ } \ assert(frame->f_lasti >= -1); \ + /* Jump back to the last instruction executed... */ \ next_instr = first_instr + frame->f_lasti + 1; \ stack_pointer = _PyFrame_GetStackPointer(frame); \ /* Set stackdepth to -1. \ @@ -1722,16 +1722,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } TARGET(RESUME) { - int err = _Py_IncrementCountAndMaybeQuicken(frame->f_code); - if (err) { - if (err < 0) { - goto error; - } - /* Update first_instr and next_instr to point to newly quickened code */ - int nexti = INSTR_OFFSET(); - first_instr = frame->f_code->co_firstinstr; - next_instr = first_instr + nexti; - } + _PyCode_Warmup(frame->f_code); JUMP_TO_INSTRUCTION(RESUME_QUICK); } @@ -4067,16 +4058,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int TARGET(JUMP_ABSOLUTE) { PREDICTED(JUMP_ABSOLUTE); - int err = _Py_IncrementCountAndMaybeQuicken(frame->f_code); - if (err) { - if (err < 0) { - goto error; - } - /* Update first_instr and next_instr to point to newly quickened code */ - int nexti = INSTR_OFFSET(); - first_instr = frame->f_code->co_firstinstr; - next_instr = first_instr + nexti; - } + _PyCode_Warmup(frame->f_code); JUMP_TO_INSTRUCTION(JUMP_ABSOLUTE_QUICK); } @@ -5425,6 +5407,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } TARGET(EXTENDED_ARG) { + assert(oparg); int oldoparg = oparg; NEXTOPARG(); oparg |= oldoparg << 8; @@ -6739,8 +6722,8 @@ maybe_call_line_trace(Py_tracefunc func, PyObject *obj, */ initialize_trace_info(&tstate->trace_info, frame); int entry_point = 0; - _Py_CODEUNIT *code = (_Py_CODEUNIT *)PyBytes_AS_STRING(frame->f_code->co_code); - while (_Py_OPCODE(code[entry_point]) != RESUME) { + _Py_CODEUNIT *code = _PyCode_CODE(frame->f_code); + while (_PyOpcode_Deopt[_Py_OPCODE(code[entry_point])] != RESUME) { entry_point++; } int lastline; @@ -6759,7 +6742,9 @@ maybe_call_line_trace(Py_tracefunc func, PyObject *obj, /* Trace backward edges (except in 'yield from') or if line number has changed */ int trace = line != lastline || (frame->f_lasti < instr_prev && - _Py_OPCODE(frame->f_code->co_firstinstr[frame->f_lasti]) != SEND); + // SEND has no quickened forms, so no need to use _PyOpcode_Deopt + // here: + _Py_OPCODE(_PyCode_CODE(frame->f_code)[frame->f_lasti]) != SEND); if (trace) { result = call_trace(func, obj, tstate, frame, PyTrace_LINE, Py_None); } diff --git a/Python/compile.c b/Python/compile.c index 950c44a749fc6..e24f425229b6a 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -134,9 +134,9 @@ static int instr_size(struct instr *instruction) { int opcode = instruction->i_opcode; - int oparg = instruction->i_oparg; + int oparg = HAS_ARG(opcode) ? instruction->i_oparg : 0; int extended_args = (0xFFFFFF < oparg) + (0xFFFF < oparg) + (0xFF < oparg); - int caches = _PyOpcode_InlineCacheEntries[opcode]; + int caches = _PyOpcode_Caches[opcode]; return extended_args + 1 + caches; } @@ -144,8 +144,8 @@ static void write_instr(_Py_CODEUNIT *codestr, struct instr *instruction, int ilen) { int opcode = instruction->i_opcode; - int oparg = instruction->i_oparg; - int caches = _PyOpcode_InlineCacheEntries[opcode]; + int oparg = HAS_ARG(opcode) ? instruction->i_oparg : 0; + int caches = _PyOpcode_Caches[opcode]; switch (ilen - caches) { case 4: *codestr++ = _Py_MAKECODEUNIT(EXTENDED_ARG, (oparg >> 24) & 0xFF); diff --git a/Python/marshal.c b/Python/marshal.c index 810244ba8ac78..e7cf6553bd142 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -544,13 +544,18 @@ w_complex_object(PyObject *v, char flag, WFILE *p) } else if (PyCode_Check(v)) { PyCodeObject *co = (PyCodeObject *)v; + PyObject *co_code = _PyCode_GetCode(co); + if (co_code == NULL) { + p->error = WFERR_NOMEMORY; + return; + } W_TYPE(TYPE_CODE, p); w_long(co->co_argcount, p); w_long(co->co_posonlyargcount, p); w_long(co->co_kwonlyargcount, p); w_long(co->co_stacksize, p); w_long(co->co_flags, p); - w_object(co->co_code, p); + w_object(co_code, p); w_object(co->co_consts, p); w_object(co->co_names, p); w_object(co->co_localsplusnames, p); @@ -563,6 +568,7 @@ w_complex_object(PyObject *v, char flag, WFILE *p) w_object(co->co_endlinetable, p); w_object(co->co_columntable, p); w_object(co->co_exceptiontable, p); + Py_DECREF(co_code); } else if (PyObject_CheckBuffer(v)) { /* Write unknown bytes-like objects as a bytes object */ diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index 7c94999bfdfe4..2aa6471abf99a 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -3,49 +3,49 @@ static void *opcode_targets[256] = { &&TARGET_POP_TOP, &&TARGET_PUSH_NULL, &&TARGET_BINARY_OP_ADAPTIVE, - &&TARGET_BINARY_OP_ADD_INT, &&TARGET_BINARY_OP_ADD_FLOAT, + &&TARGET_BINARY_OP_ADD_INT, &&TARGET_BINARY_OP_ADD_UNICODE, &&TARGET_BINARY_OP_INPLACE_ADD_UNICODE, - &&TARGET_BINARY_OP_MULTIPLY_INT, + &&TARGET_BINARY_OP_MULTIPLY_FLOAT, &&TARGET_NOP, &&TARGET_UNARY_POSITIVE, &&TARGET_UNARY_NEGATIVE, &&TARGET_UNARY_NOT, - &&TARGET_BINARY_OP_MULTIPLY_FLOAT, - &&TARGET_BINARY_OP_SUBTRACT_INT, - &&TARGET_UNARY_INVERT, + &&TARGET_BINARY_OP_MULTIPLY_INT, &&TARGET_BINARY_OP_SUBTRACT_FLOAT, - &&TARGET_COMPARE_OP_ADAPTIVE, - &&TARGET_COMPARE_OP_FLOAT_JUMP, - &&TARGET_COMPARE_OP_INT_JUMP, - &&TARGET_COMPARE_OP_STR_JUMP, + &&TARGET_UNARY_INVERT, + &&TARGET_BINARY_OP_SUBTRACT_INT, &&TARGET_BINARY_SUBSCR_ADAPTIVE, + &&TARGET_BINARY_SUBSCR_DICT, &&TARGET_BINARY_SUBSCR_GETITEM, &&TARGET_BINARY_SUBSCR_LIST_INT, &&TARGET_BINARY_SUBSCR_TUPLE_INT, + &&TARGET_CALL_ADAPTIVE, + &&TARGET_CALL_PY_EXACT_ARGS, + &&TARGET_CALL_PY_WITH_DEFAULTS, &&TARGET_BINARY_SUBSCR, - &&TARGET_BINARY_SUBSCR_DICT, - &&TARGET_STORE_SUBSCR_ADAPTIVE, - &&TARGET_STORE_SUBSCR_LIST_INT, - &&TARGET_STORE_SUBSCR_DICT, + &&TARGET_COMPARE_OP_ADAPTIVE, + &&TARGET_COMPARE_OP_FLOAT_JUMP, + &&TARGET_COMPARE_OP_INT_JUMP, + &&TARGET_COMPARE_OP_STR_JUMP, &&TARGET_GET_LEN, &&TARGET_MATCH_MAPPING, &&TARGET_MATCH_SEQUENCE, &&TARGET_MATCH_KEYS, - &&TARGET_CALL_ADAPTIVE, - &&TARGET_PUSH_EXC_INFO, - &&TARGET_CALL_PY_EXACT_ARGS, - &&TARGET_CALL_PY_WITH_DEFAULTS, &&TARGET_JUMP_ABSOLUTE_QUICK, + &&TARGET_PUSH_EXC_INFO, &&TARGET_LOAD_ATTR_ADAPTIVE, &&TARGET_LOAD_ATTR_INSTANCE_VALUE, - &&TARGET_LOAD_ATTR_WITH_HINT, - &&TARGET_LOAD_ATTR_SLOT, &&TARGET_LOAD_ATTR_MODULE, + &&TARGET_LOAD_ATTR_SLOT, + &&TARGET_LOAD_ATTR_WITH_HINT, + &&TARGET_LOAD_CONST__LOAD_FAST, + &&TARGET_LOAD_FAST__LOAD_CONST, + &&TARGET_LOAD_FAST__LOAD_FAST, &&TARGET_LOAD_GLOBAL_ADAPTIVE, - &&TARGET_LOAD_GLOBAL_MODULE, &&TARGET_LOAD_GLOBAL_BUILTIN, + &&TARGET_LOAD_GLOBAL_MODULE, &&TARGET_LOAD_METHOD_ADAPTIVE, &&TARGET_LOAD_METHOD_CLASS, &&TARGET_WITH_EXCEPT_START, @@ -61,26 +61,26 @@ static void *opcode_targets[256] = { &&TARGET_PRECALL_ADAPTIVE, &&TARGET_STORE_SUBSCR, &&TARGET_DELETE_SUBSCR, + &&TARGET_PRECALL_BOUND_METHOD, &&TARGET_PRECALL_BUILTIN_CLASS, - &&TARGET_PRECALL_NO_KW_BUILTIN_O, - &&TARGET_PRECALL_NO_KW_BUILTIN_FAST, &&TARGET_PRECALL_BUILTIN_FAST_WITH_KEYWORDS, - &&TARGET_PRECALL_NO_KW_LEN, + &&TARGET_PRECALL_NO_KW_BUILTIN_FAST, + &&TARGET_PRECALL_NO_KW_BUILTIN_O, &&TARGET_PRECALL_NO_KW_ISINSTANCE, &&TARGET_GET_ITER, &&TARGET_GET_YIELD_FROM_ITER, &&TARGET_PRINT_EXPR, &&TARGET_LOAD_BUILD_CLASS, + &&TARGET_PRECALL_NO_KW_LEN, &&TARGET_PRECALL_NO_KW_LIST_APPEND, - &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_O, &&TARGET_LOAD_ASSERTION_ERROR, &&TARGET_RETURN_GENERATOR, + &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST, &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS, + &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_O, &&TARGET_PRECALL_NO_KW_STR_1, &&TARGET_PRECALL_NO_KW_TUPLE_1, &&TARGET_PRECALL_NO_KW_TYPE_1, - &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST, - &&TARGET_PRECALL_BOUND_METHOD, &&TARGET_LIST_TO_TUPLE, &&TARGET_RETURN_VALUE, &&TARGET_IMPORT_STAR, @@ -157,23 +157,23 @@ static void *opcode_targets[256] = { &&TARGET_FORMAT_VALUE, &&TARGET_BUILD_CONST_KEY_MAP, &&TARGET_BUILD_STRING, - &&TARGET_UNPACK_SEQUENCE_ADAPTIVE, - &&TARGET_UNPACK_SEQUENCE_LIST, + &&TARGET_STORE_FAST__LOAD_FAST, + &&TARGET_STORE_FAST__STORE_FAST, &&TARGET_LOAD_METHOD, - &&TARGET_UNPACK_SEQUENCE_TUPLE, + &&TARGET_STORE_SUBSCR_ADAPTIVE, &&TARGET_LIST_EXTEND, &&TARGET_SET_UPDATE, &&TARGET_DICT_MERGE, &&TARGET_DICT_UPDATE, &&TARGET_PRECALL, - &&TARGET_UNPACK_SEQUENCE_TWO_TUPLE, - &&TARGET_LOAD_FAST__LOAD_FAST, - &&TARGET_STORE_FAST__LOAD_FAST, - &&TARGET_LOAD_FAST__LOAD_CONST, + &&TARGET_STORE_SUBSCR_DICT, + &&TARGET_STORE_SUBSCR_LIST_INT, + &&TARGET_UNPACK_SEQUENCE_ADAPTIVE, + &&TARGET_UNPACK_SEQUENCE_LIST, &&TARGET_CALL, &&TARGET_KW_NAMES, - &&TARGET_LOAD_CONST__LOAD_FAST, - &&TARGET_STORE_FAST__STORE_FAST, + &&TARGET_UNPACK_SEQUENCE_TUPLE, + &&TARGET_UNPACK_SEQUENCE_TWO_TUPLE, &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, diff --git a/Python/specialize.c b/Python/specialize.c index d84adac352078..ce091a2c5f078 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -15,31 +15,6 @@ * ./adaptive.md */ - -/* We layout the quickened data as a bi-directional array: - * Instructions upwards, cache entries downwards. - * first_instr is aligned to a SpecializedCacheEntry. - * The nth instruction is located at first_instr[n] - * The nth cache is located at ((SpecializedCacheEntry *)first_instr)[-1-n] - * The first (index 0) cache entry is reserved for the count, to enable finding - * the first instruction from the base pointer. - * The cache_count argument must include space for the count. - * We use the SpecializedCacheOrInstruction union to refer to the data - * to avoid type punning. - - Layout of quickened data, each line 8 bytes for M cache entries and N instructions: - - <---- co->co_quickened - - - ... - - <--- co->co_first_instr - - ... - -*/ - /* Map from opcode to adaptive opcode. Values of zero are ignored. */ static uint8_t adaptive_opcodes[256] = { @@ -275,26 +250,14 @@ _Py_PrintSpecializationStats(int to_file) #define SPECIALIZATION_FAIL(opcode, kind) ((void)0) #endif -static _Py_CODEUNIT * -allocate(int instruction_count) +// Insert adaptive instructions and superinstructions. This cannot fail. +void +_PyCode_Quicken(PyCodeObject *code) { - assert(instruction_count > 0); - void *array = PyMem_Malloc(sizeof(_Py_CODEUNIT) * instruction_count); - if (array == NULL) { - PyErr_NoMemory(); - return NULL; - } _Py_QuickenedCount++; - return (_Py_CODEUNIT *)array; -} - - -// Insert adaptive instructions and superinstructions. -static void -optimize(_Py_CODEUNIT *instructions, int len) -{ int previous_opcode = -1; - for(int i = 0; i < len; i++) { + _Py_CODEUNIT *instructions = _PyCode_CODE(code); + for (int i = 0; i < Py_SIZE(code); i++) { int opcode = _Py_OPCODE(instructions[i]); uint8_t adaptive_opcode = adaptive_opcodes[opcode]; if (adaptive_opcode) { @@ -302,10 +265,10 @@ optimize(_Py_CODEUNIT *instructions, int len) // Make sure the adaptive counter is zero: assert(instructions[i + 1] == 0); previous_opcode = -1; - i += _PyOpcode_InlineCacheEntries[opcode]; + i += _PyOpcode_Caches[opcode]; } else { - assert(!_PyOpcode_InlineCacheEntries[opcode]); + assert(!_PyOpcode_Caches[opcode]); switch (opcode) { case JUMP_ABSOLUTE: _Py_SET_OPCODE(instructions[i], JUMP_ABSOLUTE_QUICK); @@ -347,28 +310,6 @@ optimize(_Py_CODEUNIT *instructions, int len) } } -int -_Py_Quicken(PyCodeObject *code) { - if (code->co_quickened) { - return 0; - } - Py_ssize_t size = PyBytes_GET_SIZE(code->co_code); - int instr_count = (int)(size/sizeof(_Py_CODEUNIT)); - if (instr_count > MAX_SIZE_TO_QUICKEN) { - code->co_warmup = QUICKENING_WARMUP_COLDEST; - return 0; - } - _Py_CODEUNIT *quickened = allocate(instr_count); - if (quickened == NULL) { - return -1; - } - memcpy(quickened, code->co_firstinstr, size); - optimize(quickened, instr_count); - code->co_quickened = quickened; - code->co_firstinstr = quickened; - return 0; -} - static inline int initial_counter_value(void) { /* Starting value for the counter. @@ -705,8 +646,7 @@ specialize_dict_access( int _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) { - assert(_PyOpcode_InlineCacheEntries[LOAD_ATTR] == - INLINE_CACHE_ENTRIES_LOAD_ATTR); + assert(_PyOpcode_Caches[LOAD_ATTR] == INLINE_CACHE_ENTRIES_LOAD_ATTR); _PyAttrCache *cache = (_PyAttrCache *)(instr + 1); if (PyModule_CheckExact(owner)) { int err = specialize_module_load_attr(owner, instr, name, LOAD_ATTR, @@ -804,8 +744,7 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) int _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) { - assert(_PyOpcode_InlineCacheEntries[STORE_ATTR] == - INLINE_CACHE_ENTRIES_STORE_ATTR); + assert(_PyOpcode_Caches[STORE_ATTR] == INLINE_CACHE_ENTRIES_STORE_ATTR); _PyAttrCache *cache = (_PyAttrCache *)(instr + 1); PyTypeObject *type = Py_TYPE(owner); if (PyModule_CheckExact(owner)) { @@ -965,8 +904,7 @@ typedef enum { int _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) { - assert(_PyOpcode_InlineCacheEntries[LOAD_METHOD] == - INLINE_CACHE_ENTRIES_LOAD_METHOD); + assert(_PyOpcode_Caches[LOAD_METHOD] == INLINE_CACHE_ENTRIES_LOAD_METHOD); _PyLoadMethodCache *cache = (_PyLoadMethodCache *)(instr + 1); PyTypeObject *owner_cls = Py_TYPE(owner); @@ -1098,8 +1036,7 @@ _Py_Specialize_LoadGlobal( PyObject *globals, PyObject *builtins, _Py_CODEUNIT *instr, PyObject *name) { - assert(_PyOpcode_InlineCacheEntries[LOAD_GLOBAL] == - INLINE_CACHE_ENTRIES_LOAD_GLOBAL); + assert(_PyOpcode_Caches[LOAD_GLOBAL] == INLINE_CACHE_ENTRIES_LOAD_GLOBAL); /* Use inline cache */ _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)(instr + 1); assert(PyUnicode_CheckExact(name)); @@ -1235,7 +1172,7 @@ int _Py_Specialize_BinarySubscr( PyObject *container, PyObject *sub, _Py_CODEUNIT *instr) { - assert(_PyOpcode_InlineCacheEntries[BINARY_SUBSCR] == + assert(_PyOpcode_Caches[BINARY_SUBSCR] == INLINE_CACHE_ENTRIES_BINARY_SUBSCR); _PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)(instr + 1); PyTypeObject *container_type = Py_TYPE(container); @@ -1663,8 +1600,7 @@ int _Py_Specialize_Precall(PyObject *callable, _Py_CODEUNIT *instr, int nargs, PyObject *kwnames, int oparg) { - assert(_PyOpcode_InlineCacheEntries[PRECALL] == - INLINE_CACHE_ENTRIES_PRECALL); + assert(_PyOpcode_Caches[PRECALL] == INLINE_CACHE_ENTRIES_PRECALL); _PyPrecallCache *cache = (_PyPrecallCache *)(instr + 1); int fail; if (PyCFunction_CheckExact(callable)) { @@ -1710,7 +1646,7 @@ int _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, PyObject *kwnames) { - assert(_PyOpcode_InlineCacheEntries[CALL] == INLINE_CACHE_ENTRIES_CALL); + assert(_PyOpcode_Caches[CALL] == INLINE_CACHE_ENTRIES_CALL); _PyCallCache *cache = (_PyCallCache *)(instr + 1); int fail; if (PyFunction_Check(callable)) { @@ -1808,8 +1744,7 @@ void _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, int oparg) { - assert(_PyOpcode_InlineCacheEntries[BINARY_OP] == - INLINE_CACHE_ENTRIES_BINARY_OP); + assert(_PyOpcode_Caches[BINARY_OP] == INLINE_CACHE_ENTRIES_BINARY_OP); _PyBinaryOpCache *cache = (_PyBinaryOpCache *)(instr + 1); switch (oparg) { case NB_ADD: @@ -1936,8 +1871,7 @@ void _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, int oparg) { - assert(_PyOpcode_InlineCacheEntries[COMPARE_OP] == - INLINE_CACHE_ENTRIES_COMPARE_OP); + assert(_PyOpcode_Caches[COMPARE_OP] == INLINE_CACHE_ENTRIES_COMPARE_OP); _PyCompareOpCache *cache = (_PyCompareOpCache *)(instr + 1); int next_opcode = _Py_OPCODE(instr[INLINE_CACHE_ENTRIES_COMPARE_OP + 1]); if (next_opcode != POP_JUMP_IF_FALSE && next_opcode != POP_JUMP_IF_TRUE) { @@ -2019,7 +1953,7 @@ unpack_sequence_fail_kind(PyObject *seq) void _Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr, int oparg) { - assert(_PyOpcode_InlineCacheEntries[UNPACK_SEQUENCE] == + assert(_PyOpcode_Caches[UNPACK_SEQUENCE] == INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE); _PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)(instr + 1); if (PyTuple_CheckExact(seq)) { diff --git a/Tools/scripts/deepfreeze.py b/Tools/scripts/deepfreeze.py index 954fca81b51e9..d208258dbc54c 100644 --- a/Tools/scripts/deepfreeze.py +++ b/Tools/scripts/deepfreeze.py @@ -229,12 +229,8 @@ def generate_unicode(self, name: str, s: str) -> str: def generate_code(self, name: str, code: types.CodeType) -> str: # The ordering here matches PyCode_NewWithPosOnlyArgs() # (but see below). - co_code = self.generate(name + "_code", code.co_code) co_consts = self.generate(name + "_consts", code.co_consts) co_names = self.generate(name + "_names", code.co_names) - co_varnames = self.generate(name + "_varnames", code.co_varnames) - co_freevars = self.generate(name + "_freevars", code.co_freevars) - co_cellvars = self.generate(name + "_cellvars", code.co_cellvars) co_filename = self.generate(name + "_filename", code.co_filename) co_name = self.generate(name + "_name", code.co_name) co_qualname = self.generate(name + "_qualname", code.co_qualname) @@ -249,14 +245,17 @@ def generate_code(self, name: str, code: types.CodeType) -> str: # Derived values nlocals, nplaincellvars, ncellvars, nfreevars = \ get_localsplus_counts(code, localsplusnames, localspluskinds) - with self.block(f"static struct PyCodeObject {name} =", ";"): - self.object_head("PyCode_Type") + co_code_adaptive = make_string_literal(code.co_code) + self.write("static") + with self.indent(): + self.write(f"struct _PyCode_DEF({len(code.co_code)})") + with self.block(f"{name} =", ";"): + self.object_var_head("PyCode_Type", len(code.co_code) // 2) # But the ordering here must match that in cpython/code.h # (which is a pain because we tend to reorder those for perf) # otherwise MSVC doesn't like it. self.write(f".co_consts = {co_consts},") self.write(f".co_names = {co_names},") - self.write(f".co_firstinstr = (_Py_CODEUNIT *) {removesuffix(co_code, '.ob_base.ob_base')}.ob_sval,") self.write(f".co_exceptiontable = {co_exceptiontable},") self.field(code, "co_flags") self.write(".co_warmup = QUICKENING_INITIAL_WARMUP_VALUE,") @@ -265,7 +264,11 @@ def generate_code(self, name: str, code: types.CodeType) -> str: self.field(code, "co_kwonlyargcount") self.field(code, "co_stacksize") self.field(code, "co_firstlineno") - self.write(f".co_code = {co_code},") + self.write(f".co_nlocalsplus = {len(localsplusnames)},") + self.field(code, "co_nlocals") + self.write(f".co_nplaincellvars = {nplaincellvars},") + self.write(f".co_ncellvars = {ncellvars},") + self.write(f".co_nfreevars = {nfreevars},") self.write(f".co_localsplusnames = {co_localsplusnames},") self.write(f".co_localspluskinds = {co_localspluskinds},") self.write(f".co_filename = {co_filename},") @@ -274,17 +277,11 @@ def generate_code(self, name: str, code: types.CodeType) -> str: self.write(f".co_linetable = {co_linetable},") self.write(f".co_endlinetable = {co_endlinetable},") self.write(f".co_columntable = {co_columntable},") - self.write(f".co_nlocalsplus = {len(localsplusnames)},") - self.field(code, "co_nlocals") - self.write(f".co_nplaincellvars = {nplaincellvars},") - self.write(f".co_ncellvars = {ncellvars},") - self.write(f".co_nfreevars = {nfreevars},") - self.write(f".co_varnames = {co_varnames},") - self.write(f".co_cellvars = {co_cellvars},") - self.write(f".co_freevars = {co_freevars},") - self.deallocs.append(f"_PyStaticCode_Dealloc(&{name});") - self.interns.append(f"_PyStaticCode_InternStrings(&{name})") - return f"& {name}.ob_base" + self.write(f".co_code_adaptive = {co_code_adaptive},") + name_as_code = f"(PyCodeObject *)&{name}" + self.deallocs.append(f"_PyStaticCode_Dealloc({name_as_code});") + self.interns.append(f"_PyStaticCode_InternStrings({name_as_code})") + return f"& {name}.ob_base.ob_base" def generate_tuple(self, name: str, t: Tuple[object, ...]) -> str: if len(t) == 0: @@ -450,13 +447,13 @@ def generate(args: list[str], output: TextIO) -> None: code = compile(fd.read(), f"", "exec") printer.generate_file(modname, code) with printer.block(f"void\n_Py_Deepfreeze_Fini(void)"): - for p in printer.deallocs: - printer.write(p) + for p in printer.deallocs: + printer.write(p) with printer.block(f"int\n_Py_Deepfreeze_Init(void)"): - for p in printer.interns: - with printer.block(f"if ({p} < 0)"): - printer.write("return -1;") - printer.write("return 0;") + for p in printer.interns: + with printer.block(f"if ({p} < 0)"): + printer.write("return -1;") + printer.write("return 0;") if verbose: print(f"Cache hits: {printer.hits}, misses: {printer.misses}") diff --git a/Tools/scripts/generate_opcode_h.py b/Tools/scripts/generate_opcode_h.py index 75a9c3f3bfadb..3b79dc6b7359f 100644 --- a/Tools/scripts/generate_opcode_h.py +++ b/Tools/scripts/generate_opcode_h.py @@ -28,7 +28,7 @@ #endif /* !Py_OPCODE_H */ """ -DEFINE = "#define {:<31} {:>3}\n" +DEFINE = "#define {:<38} {:>3}\n" UINT32_MASK = (1<<32)-1 @@ -75,16 +75,27 @@ def main(opcode_py, outfile='Include/opcode.h'): fobj.write(DEFINE.format(name, next_op)) used[next_op] = True fobj.write(DEFINE.format('DO_TRACING', 255)) - fobj.write("\nextern const uint8_t _PyOpcode_InlineCacheEntries[256];\n") + fobj.write("\nextern const uint8_t _PyOpcode_Caches[256];\n") + fobj.write("\nextern const uint8_t _PyOpcode_Deopt[256];\n") fobj.write("\n#ifdef NEED_OPCODE_TABLES\n") write_int_array_from_ops("_PyOpcode_RelativeJump", opcode['hasjrel'], fobj) write_int_array_from_ops("_PyOpcode_Jump", opcode['hasjrel'] + opcode['hasjabs'], fobj) - fobj.write("\nconst uint8_t _PyOpcode_InlineCacheEntries[256] = {\n") + fobj.write("\nconst uint8_t _PyOpcode_Caches[256] = {\n") for i, entries in enumerate(opcode["_inline_cache_entries"]): if entries: fobj.write(f" [{opname[i]}] = {entries},\n") fobj.write("};\n") + deoptcodes = {} + for basic in opmap: + deoptcodes[basic] = basic + for basic, family in opcode["_specializations"].items(): + for specialized in family: + deoptcodes[specialized] = basic + fobj.write("\nconst uint8_t _PyOpcode_Deopt[256] = {\n") + for opt, deopt in sorted(deoptcodes.items()): + fobj.write(f" [{opt}] = {deopt},\n") + fobj.write("};\n") fobj.write("#endif /* OPCODE_TABLES */\n") fobj.write("\n") From webhook-mailer at python.org Mon Mar 21 07:28:50 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 21 Mar 2022 11:28:50 -0000 Subject: [Python-checkins] bpo-23691: Protect the re.finditer() iterator from re-entering (GH-32012) Message-ID: https://github.com/python/cpython/commit/f89949ec6741bd02841bece61f5b703e738dd13c commit: f89949ec6741bd02841bece61f5b703e738dd13c branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-21T04:28:31-07:00 summary: bpo-23691: Protect the re.finditer() iterator from re-entering (GH-32012) (cherry picked from commit 08eb754d840696914928355014c2d424131f8835) Co-authored-by: Serhiy Storchaka files: A Misc/NEWS.d/next/Library/2022-03-20-22-13-24.bpo-23691.Nc2TrW.rst M Modules/_sre.c M Modules/sre.h diff --git a/Misc/NEWS.d/next/Library/2022-03-20-22-13-24.bpo-23691.Nc2TrW.rst b/Misc/NEWS.d/next/Library/2022-03-20-22-13-24.bpo-23691.Nc2TrW.rst new file mode 100644 index 0000000000000..053a2b2709ee8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-20-22-13-24.bpo-23691.Nc2TrW.rst @@ -0,0 +1 @@ +Protect the :func:`re.finditer` iterator from re-entering. diff --git a/Modules/_sre.c b/Modules/_sre.c index 8225c36da1a38..338530e2dc993 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -2391,6 +2391,25 @@ scanner_dealloc(ScannerObject* self) PyObject_DEL(self); } +static int +scanner_begin(ScannerObject* self) +{ + if (self->executing) { + PyErr_SetString(PyExc_ValueError, + "regular expression scanner already executing"); + return 0; + } + self->executing = 1; + return 1; +} + +static void +scanner_end(ScannerObject* self) +{ + assert(self->executing); + self->executing = 0; +} + /*[clinic input] _sre.SRE_Scanner.match @@ -2404,16 +2423,23 @@ _sre_SRE_Scanner_match_impl(ScannerObject *self) PyObject* match; Py_ssize_t status; - if (state->start == NULL) + if (!scanner_begin(self)) { + return NULL; + } + if (state->start == NULL) { + scanner_end(self); Py_RETURN_NONE; + } state_reset(state); state->ptr = state->start; status = sre_match(state, PatternObject_GetCode(self->pattern)); - if (PyErr_Occurred()) + if (PyErr_Occurred()) { + scanner_end(self); return NULL; + } match = pattern_new_match((PatternObject*) self->pattern, state, status); @@ -2425,6 +2451,7 @@ _sre_SRE_Scanner_match_impl(ScannerObject *self) state->start = state->ptr; } + scanner_end(self); return match; } @@ -2442,16 +2469,23 @@ _sre_SRE_Scanner_search_impl(ScannerObject *self) PyObject* match; Py_ssize_t status; - if (state->start == NULL) + if (!scanner_begin(self)) { + return NULL; + } + if (state->start == NULL) { + scanner_end(self); Py_RETURN_NONE; + } state_reset(state); state->ptr = state->start; status = sre_search(state, PatternObject_GetCode(self->pattern)); - if (PyErr_Occurred()) + if (PyErr_Occurred()) { + scanner_end(self); return NULL; + } match = pattern_new_match((PatternObject*) self->pattern, state, status); @@ -2463,6 +2497,7 @@ _sre_SRE_Scanner_search_impl(ScannerObject *self) state->start = state->ptr; } + scanner_end(self); return match; } @@ -2476,6 +2511,7 @@ pattern_scanner(PatternObject *self, PyObject *string, Py_ssize_t pos, Py_ssize_ if (!scanner) return NULL; scanner->pattern = NULL; + scanner->executing = 0; /* create search state object */ if (!state_init(&scanner->state, self, string, pos, endpos)) { diff --git a/Modules/sre.h b/Modules/sre.h index 9b0d8b190426a..785adbd003e7f 100644 --- a/Modules/sre.h +++ b/Modules/sre.h @@ -89,6 +89,7 @@ typedef struct { PyObject_HEAD PyObject* pattern; SRE_STATE state; + int executing; } ScannerObject; #endif From webhook-mailer at python.org Mon Mar 21 07:31:08 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 21 Mar 2022 11:31:08 -0000 Subject: [Python-checkins] bpo-23691: Protect the re.finditer() iterator from re-entering (GH-32012) Message-ID: https://github.com/python/cpython/commit/1b21b55ee0ea57226c52dc9f3ee3c034a5d1dc7b commit: 1b21b55ee0ea57226c52dc9f3ee3c034a5d1dc7b branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-21T04:30:58-07:00 summary: bpo-23691: Protect the re.finditer() iterator from re-entering (GH-32012) (cherry picked from commit 08eb754d840696914928355014c2d424131f8835) Co-authored-by: Serhiy Storchaka files: A Misc/NEWS.d/next/Library/2022-03-20-22-13-24.bpo-23691.Nc2TrW.rst M Modules/_sre.c M Modules/sre.h diff --git a/Misc/NEWS.d/next/Library/2022-03-20-22-13-24.bpo-23691.Nc2TrW.rst b/Misc/NEWS.d/next/Library/2022-03-20-22-13-24.bpo-23691.Nc2TrW.rst new file mode 100644 index 0000000000000..053a2b2709ee8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-20-22-13-24.bpo-23691.Nc2TrW.rst @@ -0,0 +1 @@ +Protect the :func:`re.finditer` iterator from re-entering. diff --git a/Modules/_sre.c b/Modules/_sre.c index d21b533530187..911626dafc977 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -2510,6 +2510,25 @@ scanner_dealloc(ScannerObject* self) Py_DECREF(tp); } +static int +scanner_begin(ScannerObject* self) +{ + if (self->executing) { + PyErr_SetString(PyExc_ValueError, + "regular expression scanner already executing"); + return 0; + } + self->executing = 1; + return 1; +} + +static void +scanner_end(ScannerObject* self) +{ + assert(self->executing); + self->executing = 0; +} + /*[clinic input] _sre.SRE_Scanner.match @@ -2527,16 +2546,23 @@ _sre_SRE_Scanner_match_impl(ScannerObject *self, PyTypeObject *cls) PyObject* match; Py_ssize_t status; - if (state->start == NULL) + if (!scanner_begin(self)) { + return NULL; + } + if (state->start == NULL) { + scanner_end(self); Py_RETURN_NONE; + } state_reset(state); state->ptr = state->start; status = sre_match(state, PatternObject_GetCode(self->pattern)); - if (PyErr_Occurred()) + if (PyErr_Occurred()) { + scanner_end(self); return NULL; + } match = pattern_new_match(module_state, (PatternObject*) self->pattern, state, status); @@ -2548,6 +2574,7 @@ _sre_SRE_Scanner_match_impl(ScannerObject *self, PyTypeObject *cls) state->start = state->ptr; } + scanner_end(self); return match; } @@ -2569,16 +2596,23 @@ _sre_SRE_Scanner_search_impl(ScannerObject *self, PyTypeObject *cls) PyObject* match; Py_ssize_t status; - if (state->start == NULL) + if (!scanner_begin(self)) { + return NULL; + } + if (state->start == NULL) { + scanner_end(self); Py_RETURN_NONE; + } state_reset(state); state->ptr = state->start; status = sre_search(state, PatternObject_GetCode(self->pattern)); - if (PyErr_Occurred()) + if (PyErr_Occurred()) { + scanner_end(self); return NULL; + } match = pattern_new_match(module_state, (PatternObject*) self->pattern, state, status); @@ -2590,6 +2624,7 @@ _sre_SRE_Scanner_search_impl(ScannerObject *self, PyTypeObject *cls) state->start = state->ptr; } + scanner_end(self); return match; } @@ -2607,6 +2642,7 @@ pattern_scanner(_sremodulestate *module_state, if (!scanner) return NULL; scanner->pattern = NULL; + scanner->executing = 0; /* create search state object */ if (!state_init(&scanner->state, self, string, pos, endpos)) { diff --git a/Modules/sre.h b/Modules/sre.h index 9b0d8b190426a..785adbd003e7f 100644 --- a/Modules/sre.h +++ b/Modules/sre.h @@ -89,6 +89,7 @@ typedef struct { PyObject_HEAD PyObject* pattern; SRE_STATE state; + int executing; } ScannerObject; #endif From webhook-mailer at python.org Mon Mar 21 12:28:38 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Mon, 21 Mar 2022 16:28:38 -0000 Subject: [Python-checkins] bpo-433030: Add support of atomic grouping in regular expressions (GH-31982) Message-ID: https://github.com/python/cpython/commit/345b390ed69f36681dbc41187bc8f49cd9135b54 commit: 345b390ed69f36681dbc41187bc8f49cd9135b54 branch: main author: Serhiy Storchaka committer: serhiy-storchaka date: 2022-03-21T18:28:22+02:00 summary: bpo-433030: Add support of atomic grouping in regular expressions (GH-31982) * Atomic grouping: (?>...). * Possessive quantifiers: x++, x*+, x?+, x{m,n}+. Equivalent to (?>x+), (?>x*), (?>x?), (?>x{m,n}). Co-authored-by: Jeffrey C. Jacobs files: A Misc/NEWS.d/next/Library/2022-03-19-08-42-57.bpo-433030.UTwRX7.rst M Doc/library/re.rst M Doc/whatsnew/3.11.rst M Lib/sre_compile.py M Lib/sre_constants.py M Lib/sre_parse.py M Lib/test/test_re.py M Misc/ACKS M Modules/_sre.c M Modules/sre_constants.h M Modules/sre_lib.h diff --git a/Doc/library/re.rst b/Doc/library/re.rst index 950a5b1fdc240..02c0a849610b0 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -154,6 +154,30 @@ The special characters are: characters as possible will be matched. Using the RE ``<.*?>`` will match only ``''``. +.. index:: + single: *+; in regular expressions + single: ++; in regular expressions + single: ?+; in regular expressions + +``*+``, ``++``, ``?+`` + Like the ``'*'``, ``'+'``, and ``'?'`` qualifiers, those where ``'+'`` is + appended also match as many times as possible. + However, unlike the true greedy qualifiers, these do not allow + back-tracking when the expression following it fails to match. + These are known as :dfn:`possessive` qualifiers. + For example, ``a*a`` will match ``'aaaa'`` because the ``a*`` will match + all 4 ``'a'``s, but, when the final ``'a'`` is encountered, the + expression is backtracked so that in the end the ``a*`` ends up matching + 3 ``'a'``s total, and the fourth ``'a'`` is matched by the final ``'a'``. + However, when ``a*+a`` is used to match ``'aaaa'``, the ``a*+`` will + match all 4 ``'a'``, but when the final ``'a'`` fails to find any more + characters to match, the expression cannot be backtracked and will thus + fail to match. + ``x*+``, ``x++`` and ``x?+`` are equivalent to ``(?>x*)``, ``(?>x+)`` + and ``(?>x?)`` correspondigly. + + .. versionadded:: 3.11 + .. index:: single: {} (curly brackets); in regular expressions @@ -178,6 +202,21 @@ The special characters are: 6-character string ``'aaaaaa'``, ``a{3,5}`` will match 5 ``'a'`` characters, while ``a{3,5}?`` will only match 3 characters. +``{m,n}+`` + Causes the resulting RE to match from *m* to *n* repetitions of the + preceding RE, attempting to match as many repetitions as possible + *without* establishing any backtracking points. + This is the possessive version of the qualifier above. + For example, on the 6-character string ``'aaaaaa'``, ``a{3,5}+aa`` + attempt to match 5 ``'a'`` characters, then, requiring 2 more ``'a'``s, + will need more characters than available and thus fail, while + ``a{3,5}aa`` will match with ``a{3,5}`` capturing 5, then 4 ``'a'``s + by backtracking and then the final 2 ``'a'``s are matched by the final + ``aa`` in the pattern. + ``x{m,n}+`` is equivalent to ``(?>x{m,n})``. + + .. versionadded:: 3.11 + .. index:: single: \ (backslash); in regular expressions ``\`` @@ -336,6 +375,21 @@ The special characters are: .. versionchanged:: 3.7 The letters ``'a'``, ``'L'`` and ``'u'`` also can be used in a group. +``(?>...)`` + Attempts to match ``...`` as if it was a separate regular expression, and + if successful, continues to match the rest of the pattern following it. + If the subsequent pattern fails to match, the stack can only be unwound + to a point *before* the ``(?>...)`` because once exited, the expression, + known as an :dfn:`atomic group`, has thrown away all stack points within + itself. + Thus, ``(?>.*).`` would never match anything because first the ``.*`` + would match all characters possible, then, having nothing left to match, + the final ``.`` would fail to match. + Since there are no stack points saved in the Atomic Group, and there is + no stack point before it, the entire expression would thus fail to match. + + .. versionadded:: 3.11 + .. index:: single: (?P<; in regular expressions ``(?P...)`` diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index b7e9dc6e9e37f..ca7699daa9854 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -295,6 +295,12 @@ os instead of ``CryptGenRandom()`` which is deprecated. (Contributed by Dong-hee Na in :issue:`44611`.) +re +-- + +* Atomic grouping (``(?>...)``) and possessive qualifiers (``*+``, ``++``, + ``?+``, ``{m,n}+``) are now supported in regular expressions. + (Contributed by Jeffrey C. Jacobs and Serhiy Storchaka in :issue:`433030`.) shutil ------ diff --git a/Lib/sre_compile.py b/Lib/sre_compile.py index c6398bfb83a57..0867200a59a23 100644 --- a/Lib/sre_compile.py +++ b/Lib/sre_compile.py @@ -17,11 +17,16 @@ assert _sre.MAGIC == MAGIC, "SRE module mismatch" _LITERAL_CODES = {LITERAL, NOT_LITERAL} -_REPEATING_CODES = {REPEAT, MIN_REPEAT, MAX_REPEAT} _SUCCESS_CODES = {SUCCESS, FAILURE} _ASSERT_CODES = {ASSERT, ASSERT_NOT} _UNIT_CODES = _LITERAL_CODES | {ANY, IN} +_REPEATING_CODES = { + MIN_REPEAT: (REPEAT, MIN_UNTIL, MIN_REPEAT_ONE), + MAX_REPEAT: (REPEAT, MAX_UNTIL, REPEAT_ONE), + POSSESSIVE_REPEAT: (POSSESSIVE_REPEAT, SUCCESS, POSSESSIVE_REPEAT_ONE), +} + # Sets of lowercase characters which have the same uppercase. _equivalences = ( # LATIN SMALL LETTER I, LATIN SMALL LETTER DOTLESS I @@ -138,10 +143,7 @@ def _compile(code, pattern, flags): if flags & SRE_FLAG_TEMPLATE: raise error("internal: unsupported template operator %r" % (op,)) if _simple(av[2]): - if op is MAX_REPEAT: - emit(REPEAT_ONE) - else: - emit(MIN_REPEAT_ONE) + emit(REPEATING_CODES[op][2]) skip = _len(code); emit(0) emit(av[0]) emit(av[1]) @@ -149,16 +151,13 @@ def _compile(code, pattern, flags): emit(SUCCESS) code[skip] = _len(code) - skip else: - emit(REPEAT) + emit(REPEATING_CODES[op][0]) skip = _len(code); emit(0) emit(av[0]) emit(av[1]) _compile(code, av[2], flags) code[skip] = _len(code) - skip - if op is MAX_REPEAT: - emit(MAX_UNTIL) - else: - emit(MIN_UNTIL) + emit(REPEATING_CODES[op][1]) elif op is SUBPATTERN: group, add_flags, del_flags, p = av if group: @@ -169,6 +168,17 @@ def _compile(code, pattern, flags): if group: emit(MARK) emit((group-1)*2+1) + elif op is ATOMIC_GROUP: + # Atomic Groups are handled by starting with an Atomic + # Group op code, then putting in the atomic group pattern + # and finally a success op code to tell any repeat + # operations within the Atomic Group to stop eating and + # pop their stack if they reach it + emit(ATOMIC_GROUP) + skip = _len(code); emit(0) + _compile(code, av, flags) + emit(SUCCESS) + code[skip] = _len(code) - skip elif op in SUCCESS_CODES: emit(op) elif op in ASSERT_CODES: @@ -709,7 +719,8 @@ def print_2(*args): else: print_(FAILURE) i += 1 - elif op in (REPEAT, REPEAT_ONE, MIN_REPEAT_ONE): + elif op in (REPEAT, REPEAT_ONE, MIN_REPEAT_ONE, + POSSESSIVE_REPEAT, POSSESSIVE_REPEAT_ONE): skip, min, max = code[i: i+3] if max == MAXREPEAT: max = 'MAXREPEAT' @@ -725,6 +736,11 @@ def print_2(*args): print_(op, skip, arg, to=i+skip) dis_(i+2, i+skip) i += skip + elif op is ATOMIC_GROUP: + skip = code[i] + print_(op, skip, to=i+skip) + dis_(i+1, i+skip) + i += skip elif op is INFO: skip, flags, min, max = code[i: i+4] if max == MAXREPEAT: diff --git a/Lib/sre_constants.py b/Lib/sre_constants.py index 8e613cb3fa5dc..a00b0170607b5 100644 --- a/Lib/sre_constants.py +++ b/Lib/sre_constants.py @@ -13,7 +13,7 @@ # update when constants are added or removed -MAGIC = 20171005 +MAGIC = 20220318 from _sre import MAXREPEAT, MAXGROUPS @@ -97,6 +97,9 @@ def _makecodes(names): REPEAT_ONE SUBPATTERN MIN_REPEAT_ONE + ATOMIC_GROUP + POSSESSIVE_REPEAT + POSSESSIVE_REPEAT_ONE GROUPREF_IGNORE IN_IGNORE diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py index bb95107393870..b91082e48fafe 100644 --- a/Lib/sre_parse.py +++ b/Lib/sre_parse.py @@ -25,7 +25,7 @@ WHITESPACE = frozenset(" \t\n\r\v\f") -_REPEATCODES = frozenset({MIN_REPEAT, MAX_REPEAT}) +_REPEATCODES = frozenset({MIN_REPEAT, MAX_REPEAT, POSSESSIVE_REPEAT}) _UNITCODES = frozenset({ANY, RANGE, IN, LITERAL, NOT_LITERAL, CATEGORY}) ESCAPES = { @@ -190,6 +190,10 @@ def getwidth(self): i, j = av.getwidth() lo = lo + i hi = hi + j + elif op is ATOMIC_GROUP: + i, j = av.getwidth() + lo = lo + i + hi = hi + j elif op is SUBPATTERN: i, j = av[-1].getwidth() lo = lo + i @@ -675,8 +679,13 @@ def _parse(source, state, verbose, nested, first=False): if group is None and not add_flags and not del_flags: item = p if sourcematch("?"): + # Non-Greedy Match subpattern[-1] = (MIN_REPEAT, (min, max, item)) + elif sourcematch("+"): + # Possessive Match (Always Greedy) + subpattern[-1] = (POSSESSIVE_REPEAT, (min, max, item)) else: + # Greedy Match subpattern[-1] = (MAX_REPEAT, (min, max, item)) elif this == ".": @@ -684,7 +693,8 @@ def _parse(source, state, verbose, nested, first=False): elif this == "(": start = source.tell() - 1 - group = True + capture = True + atomic = False name = None add_flags = 0 del_flags = 0 @@ -726,7 +736,7 @@ def _parse(source, state, verbose, nested, first=False): len(char) + 2) elif char == ":": # non-capturing group - group = None + capture = False elif char == "#": # comment while True: @@ -800,6 +810,10 @@ def _parse(source, state, verbose, nested, first=False): subpatternappend((GROUPREF_EXISTS, (condgroup, item_yes, item_no))) continue + elif char == ">": + # non-capturing, atomic group + capture = False + atomic = True elif char in FLAGS or char == "-": # flags flags = _parse_flags(source, state, char) @@ -813,17 +827,19 @@ def _parse(source, state, verbose, nested, first=False): continue add_flags, del_flags = flags - group = None + capture = False else: raise source.error("unknown extension ?" + char, len(char) + 1) # parse group contents - if group is not None: + if capture: try: group = state.opengroup(name) except error as err: raise source.error(err.msg, len(name) + 1) from None + else: + group = None sub_verbose = ((verbose or (add_flags & SRE_FLAG_VERBOSE)) and not (del_flags & SRE_FLAG_VERBOSE)) p = _parse_sub(source, state, sub_verbose, nested + 1) @@ -832,7 +848,11 @@ def _parse(source, state, verbose, nested, first=False): source.tell() - start) if group is not None: state.closegroup(group, p) - subpatternappend((SUBPATTERN, (group, add_flags, del_flags, p))) + if atomic: + assert group is None + subpatternappend((ATOMIC_GROUP, p)) + else: + subpatternappend((SUBPATTERN, (group, add_flags, del_flags, p))) elif this == "^": subpatternappend((AT, AT_BEGINNING)) diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index f8bbe5178219a..bde7509f09729 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -83,6 +83,23 @@ def test_search_star_plus(self): self.assertEqual(re.match('x*', 'xxxa').span(), (0, 3)) self.assertIsNone(re.match('a+', 'xxx')) + def test_branching(self): + """Test Branching + Test expressions using the OR ('|') operator.""" + self.assertEqual(re.match('(ab|ba)', 'ab').span(), (0, 2)) + self.assertEqual(re.match('(ab|ba)', 'ba').span(), (0, 2)) + self.assertEqual(re.match('(abc|bac|ca|cb)', 'abc').span(), + (0, 3)) + self.assertEqual(re.match('(abc|bac|ca|cb)', 'bac').span(), + (0, 3)) + self.assertEqual(re.match('(abc|bac|ca|cb)', 'ca').span(), + (0, 2)) + self.assertEqual(re.match('(abc|bac|ca|cb)', 'cb').span(), + (0, 2)) + self.assertEqual(re.match('((a)|(b)|(c))', 'a').span(), (0, 1)) + self.assertEqual(re.match('((a)|(b)|(c))', 'b').span(), (0, 1)) + self.assertEqual(re.match('((a)|(b)|(c))', 'c').span(), (0, 1)) + def bump_num(self, matchobj): int_value = int(matchobj.group(0)) return str(int_value + 1) @@ -1239,11 +1256,13 @@ def test_nothing_to_repeat(self): 'nothing to repeat', 3) def test_multiple_repeat(self): - for outer_reps in '*', '+', '{1,2}': - for outer_mod in '', '?': + for outer_reps in '*', '+', '?', '{1,2}': + for outer_mod in '', '?', '+': outer_op = outer_reps + outer_mod for inner_reps in '*', '+', '?', '{1,2}': - for inner_mod in '', '?': + for inner_mod in '', '?', '+': + if inner_mod + outer_reps in ('?', '+'): + continue inner_op = inner_reps + inner_mod self.checkPatternError(r'x%s%s' % (inner_op, outer_op), 'multiple repeat', 1 + len(inner_op)) @@ -1458,7 +1477,8 @@ def test_inline_flags(self): def test_dollar_matches_twice(self): - "$ matches the end of string, and just before the terminating \n" + r"""Test that $ does not include \n + $ matches the end of string, and just before the terminating \n""" pattern = re.compile('$') self.assertEqual(pattern.sub('#', 'a\nb\n'), 'a\nb#\n#') self.assertEqual(pattern.sub('#', 'a\nb\nc'), 'a\nb\nc#') @@ -1774,60 +1794,6 @@ def test_bug_2537(self): self.assertEqual(m.group(1), "") self.assertEqual(m.group(2), "y") - @cpython_only - def test_debug_flag(self): - pat = r'(\.)(?:[ch]|py)(?(1)$|: )' - with captured_stdout() as out: - re.compile(pat, re.DEBUG) - self.maxDiff = None - dump = '''\ -SUBPATTERN 1 0 0 - LITERAL 46 -BRANCH - IN - LITERAL 99 - LITERAL 104 -OR - LITERAL 112 - LITERAL 121 -GROUPREF_EXISTS 1 - AT AT_END -ELSE - LITERAL 58 - LITERAL 32 - - 0. INFO 8 0b1 2 5 (to 9) - prefix_skip 0 - prefix [0x2e] ('.') - overlap [0] - 9: MARK 0 -11. LITERAL 0x2e ('.') -13. MARK 1 -15. BRANCH 10 (to 26) -17. IN 6 (to 24) -19. LITERAL 0x63 ('c') -21. LITERAL 0x68 ('h') -23. FAILURE -24: JUMP 9 (to 34) -26: branch 7 (to 33) -27. LITERAL 0x70 ('p') -29. LITERAL 0x79 ('y') -31. JUMP 2 (to 34) -33: FAILURE -34: GROUPREF_EXISTS 0 6 (to 41) -37. AT END -39. JUMP 5 (to 45) -41: LITERAL 0x3a (':') -43. LITERAL 0x20 (' ') -45: SUCCESS -''' - self.assertEqual(out.getvalue(), dump) - # Debug output is output again even a second time (bypassing - # the cache -- issue #20426). - with captured_stdout() as out: - re.compile(pat, re.DEBUG) - self.assertEqual(out.getvalue(), dump) - def test_keyword_parameters(self): # Issue #20283: Accepting the string keyword parameter. pat = re.compile(r'(ab)') @@ -2072,6 +2038,218 @@ def test_bug_40736(self): with self.assertRaisesRegex(TypeError, "got 'type'"): re.search("x*", type) + def test_possessive_qualifiers(self): + """Test Possessive Qualifiers + Test qualifiers of the form @+ for some repetition operator @, + e.g. x{3,5}+ meaning match from 3 to 5 greadily and proceed + without creating a stack frame for rolling the stack back and + trying 1 or more fewer matches.""" + self.assertIsNone(re.match('e*+e', 'eeee')) + self.assertEqual(re.match('e++a', 'eeea').group(0), 'eeea') + self.assertEqual(re.match('e?+a', 'ea').group(0), 'ea') + self.assertEqual(re.match('e{2,4}+a', 'eeea').group(0), 'eeea') + self.assertIsNone(re.match('(.)++.', 'ee')) + self.assertEqual(re.match('(ae)*+a', 'aea').groups(), ('ae',)) + self.assertEqual(re.match('([ae][ae])?+a', 'aea').groups(), + ('ae',)) + self.assertEqual(re.match('(e?){2,4}+a', 'eeea').groups(), + ('',)) + self.assertEqual(re.match('()*+a', 'a').groups(), ('',)) + self.assertEqual(re.search('x*+', 'axx').span(), (0, 0)) + self.assertEqual(re.search('x++', 'axx').span(), (1, 3)) + self.assertEqual(re.match('a*+', 'xxx').span(), (0, 0)) + self.assertEqual(re.match('x*+', 'xxxa').span(), (0, 3)) + self.assertIsNone(re.match('a++', 'xxx')) + self.assertIsNone(re.match(r"^(\w){1}+$", "abc")) + self.assertIsNone(re.match(r"^(\w){1,2}+$", "abc")) + + self.assertEqual(re.match(r"^(\w){3}+$", "abc").group(1), "c") + self.assertEqual(re.match(r"^(\w){1,3}+$", "abc").group(1), "c") + self.assertEqual(re.match(r"^(\w){1,4}+$", "abc").group(1), "c") + + self.assertIsNone(re.match("^x{1}+$", "xxx")) + self.assertIsNone(re.match("^x{1,2}+$", "xxx")) + + self.assertTrue(re.match("^x{3}+$", "xxx")) + self.assertTrue(re.match("^x{1,3}+$", "xxx")) + self.assertTrue(re.match("^x{1,4}+$", "xxx")) + + self.assertIsNone(re.match("^x{}+$", "xxx")) + self.assertTrue(re.match("^x{}+$", "x{}")) + + def test_fullmatch_possessive_qualifiers(self): + self.assertTrue(re.fullmatch(r'a++', 'a')) + self.assertTrue(re.fullmatch(r'a*+', 'a')) + self.assertTrue(re.fullmatch(r'a?+', 'a')) + self.assertTrue(re.fullmatch(r'a{1,3}+', 'a')) + self.assertIsNone(re.fullmatch(r'a++', 'ab')) + self.assertIsNone(re.fullmatch(r'a*+', 'ab')) + self.assertIsNone(re.fullmatch(r'a?+', 'ab')) + self.assertIsNone(re.fullmatch(r'a{1,3}+', 'ab')) + + self.assertTrue(re.fullmatch(r'(?:ab)++', 'ab')) + self.assertTrue(re.fullmatch(r'(?:ab)*+', 'ab')) + self.assertTrue(re.fullmatch(r'(?:ab)?+', 'ab')) + self.assertTrue(re.fullmatch(r'(?:ab){1,3}+', 'ab')) + self.assertIsNone(re.fullmatch(r'(?:ab)++', 'abc')) + self.assertIsNone(re.fullmatch(r'(?:ab)*+', 'abc')) + self.assertIsNone(re.fullmatch(r'(?:ab)?+', 'abc')) + self.assertIsNone(re.fullmatch(r'(?:ab){1,3}+', 'abc')) + + def test_findall_possessive_qualifiers(self): + self.assertEqual(re.findall(r'a++', 'aab'), ['aa']) + self.assertEqual(re.findall(r'a*+', 'aab'), ['aa', '', '']) + self.assertEqual(re.findall(r'a?+', 'aab'), ['a', 'a', '', '']) + self.assertEqual(re.findall(r'a{1,3}+', 'aab'), ['aa']) + + self.assertEqual(re.findall(r'(?:ab)++', 'ababc'), ['abab']) + self.assertEqual(re.findall(r'(?:ab)*+', 'ababc'), ['abab', '', '']) + self.assertEqual(re.findall(r'(?:ab)?+', 'ababc'), ['ab', 'ab', '', '']) + self.assertEqual(re.findall(r'(?:ab){1,3}+', 'ababc'), ['abab']) + + def test_atomic_grouping(self): + """Test Atomic Grouping + Test non-capturing groups of the form (?>...), which does + not maintain any stack point created within the group once the + group is finished being evaluated.""" + pattern1 = re.compile(r'a(?>bc|b)c') + self.assertIsNone(pattern1.match('abc')) + self.assertTrue(pattern1.match('abcc')) + self.assertIsNone(re.match(r'(?>.*).', 'abc')) + self.assertTrue(re.match(r'(?>x)++', 'xxx')) + self.assertTrue(re.match(r'(?>x++)', 'xxx')) + self.assertIsNone(re.match(r'(?>x)++x', 'xxx')) + self.assertIsNone(re.match(r'(?>x++)x', 'xxx')) + + def test_fullmatch_atomic_grouping(self): + self.assertTrue(re.fullmatch(r'(?>a+)', 'a')) + self.assertTrue(re.fullmatch(r'(?>a*)', 'a')) + self.assertTrue(re.fullmatch(r'(?>a?)', 'a')) + self.assertTrue(re.fullmatch(r'(?>a{1,3})', 'a')) + self.assertIsNone(re.fullmatch(r'(?>a+)', 'ab')) + self.assertIsNone(re.fullmatch(r'(?>a*)', 'ab')) + self.assertIsNone(re.fullmatch(r'(?>a?)', 'ab')) + self.assertIsNone(re.fullmatch(r'(?>a{1,3})', 'ab')) + + self.assertTrue(re.fullmatch(r'(?>(?:ab)+)', 'ab')) + self.assertTrue(re.fullmatch(r'(?>(?:ab)*)', 'ab')) + self.assertTrue(re.fullmatch(r'(?>(?:ab)?)', 'ab')) + self.assertTrue(re.fullmatch(r'(?>(?:ab){1,3})', 'ab')) + self.assertIsNone(re.fullmatch(r'(?>(?:ab)+)', 'abc')) + self.assertIsNone(re.fullmatch(r'(?>(?:ab)*)', 'abc')) + self.assertIsNone(re.fullmatch(r'(?>(?:ab)?)', 'abc')) + self.assertIsNone(re.fullmatch(r'(?>(?:ab){1,3})', 'abc')) + + def test_findall_atomic_grouping(self): + self.assertEqual(re.findall(r'(?>a+)', 'aab'), ['aa']) + self.assertEqual(re.findall(r'(?>a*)', 'aab'), ['aa', '', '']) + self.assertEqual(re.findall(r'(?>a?)', 'aab'), ['a', 'a', '', '']) + self.assertEqual(re.findall(r'(?>a{1,3})', 'aab'), ['aa']) + + self.assertEqual(re.findall(r'(?>(?:ab)+)', 'ababc'), ['abab']) + self.assertEqual(re.findall(r'(?>(?:ab)*)', 'ababc'), ['abab', '', '']) + self.assertEqual(re.findall(r'(?>(?:ab)?)', 'ababc'), ['ab', 'ab', '', '']) + self.assertEqual(re.findall(r'(?>(?:ab){1,3})', 'ababc'), ['abab']) + + +def get_debug_out(pat): + with captured_stdout() as out: + re.compile(pat, re.DEBUG) + return out.getvalue() + + + at cpython_only +class DebugTests(unittest.TestCase): + maxDiff = None + + def test_debug_flag(self): + pat = r'(\.)(?:[ch]|py)(?(1)$|: )' + dump = '''\ +SUBPATTERN 1 0 0 + LITERAL 46 +BRANCH + IN + LITERAL 99 + LITERAL 104 +OR + LITERAL 112 + LITERAL 121 +GROUPREF_EXISTS 1 + AT AT_END +ELSE + LITERAL 58 + LITERAL 32 + + 0. INFO 8 0b1 2 5 (to 9) + prefix_skip 0 + prefix [0x2e] ('.') + overlap [0] + 9: MARK 0 +11. LITERAL 0x2e ('.') +13. MARK 1 +15. BRANCH 10 (to 26) +17. IN 6 (to 24) +19. LITERAL 0x63 ('c') +21. LITERAL 0x68 ('h') +23. FAILURE +24: JUMP 9 (to 34) +26: branch 7 (to 33) +27. LITERAL 0x70 ('p') +29. LITERAL 0x79 ('y') +31. JUMP 2 (to 34) +33: FAILURE +34: GROUPREF_EXISTS 0 6 (to 41) +37. AT END +39. JUMP 5 (to 45) +41: LITERAL 0x3a (':') +43. LITERAL 0x20 (' ') +45: SUCCESS +''' + self.assertEqual(get_debug_out(pat), dump) + # Debug output is output again even a second time (bypassing + # the cache -- issue #20426). + self.assertEqual(get_debug_out(pat), dump) + + def test_atomic_group(self): + self.assertEqual(get_debug_out(r'(?>ab?)'), '''\ +ATOMIC_GROUP [(LITERAL, 97), (MAX_REPEAT, (0, 1, [(LITERAL, 98)]))] + + 0. INFO 4 0b0 1 2 (to 5) + 5: ATOMIC_GROUP 11 (to 17) + 7. LITERAL 0x61 ('a') + 9. REPEAT_ONE 6 0 1 (to 16) +13. LITERAL 0x62 ('b') +15. SUCCESS +16: SUCCESS +17: SUCCESS +''') + + def test_possesive_repeat_one(self): + self.assertEqual(get_debug_out(r'a?+'), '''\ +POSSESSIVE_REPEAT 0 1 + LITERAL 97 + + 0. INFO 4 0b0 0 1 (to 5) + 5: POSSESSIVE_REPEAT_ONE 6 0 1 (to 12) + 9. LITERAL 0x61 ('a') +11. SUCCESS +12: SUCCESS +''') + + def test_possesive_repeat(self): + self.assertEqual(get_debug_out(r'(?:ab)?+'), '''\ +POSSESSIVE_REPEAT 0 1 + LITERAL 97 + LITERAL 98 + + 0. INFO 4 0b0 0 2 (to 5) + 5: POSSESSIVE_REPEAT 7 0 1 (to 13) + 9. LITERAL 0x61 ('a') +11. LITERAL 0x62 ('b') +13: SUCCESS +14. SUCCESS +''') + class PatternReprTests(unittest.TestCase): def check(self, pattern, expected): diff --git a/Misc/ACKS b/Misc/ACKS index 895813e8fc208..cfc15be2c9748 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -824,6 +824,7 @@ Ben Jackson Paul Jackson Manuel Jacob David Jacobs +Jeffrey C. Jacobs Kevin Jacobs Kjetil Jacobsen Shantanu Jain diff --git a/Misc/NEWS.d/next/Library/2022-03-19-08-42-57.bpo-433030.UTwRX7.rst b/Misc/NEWS.d/next/Library/2022-03-19-08-42-57.bpo-433030.UTwRX7.rst new file mode 100644 index 0000000000000..1afed73ffeab2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-19-08-42-57.bpo-433030.UTwRX7.rst @@ -0,0 +1,2 @@ +Add support of atomic grouping (``(?>...)``) and possessive qualifiers +(``*+``, ``++``, ``?+``, ``{m,n}+``) in :mod:`regular expressions `. diff --git a/Modules/_sre.c b/Modules/_sre.c index ab321eafb6d79..35bdb4f3d2202 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -1807,6 +1807,7 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) case SRE_OP_REPEAT_ONE: case SRE_OP_MIN_REPEAT_ONE: + case SRE_OP_POSSESSIVE_REPEAT_ONE: { SRE_CODE min, max; GET_SKIP; @@ -1826,8 +1827,9 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) break; case SRE_OP_REPEAT: + case SRE_OP_POSSESSIVE_REPEAT: { - SRE_CODE min, max; + SRE_CODE op1 = op, min, max; GET_SKIP; GET_ARG; min = arg; GET_ARG; max = arg; @@ -1839,7 +1841,25 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) FAIL; code += skip-3; GET_OP; - if (op != SRE_OP_MAX_UNTIL && op != SRE_OP_MIN_UNTIL) + if (op1 == SRE_OP_POSSESSIVE_REPEAT) { + if (op != SRE_OP_SUCCESS) + FAIL; + } + else { + if (op != SRE_OP_MAX_UNTIL && op != SRE_OP_MIN_UNTIL) + FAIL; + } + } + break; + + case SRE_OP_ATOMIC_GROUP: + { + GET_SKIP; + if (!_validate_inner(code, code+skip-2, groups)) + FAIL; + code += skip-2; + GET_OP; + if (op != SRE_OP_SUCCESS) FAIL; } break; diff --git a/Modules/sre_constants.h b/Modules/sre_constants.h index c8ccb32d21de6..8b9125b75b456 100644 --- a/Modules/sre_constants.h +++ b/Modules/sre_constants.h @@ -11,7 +11,7 @@ * See the _sre.c file for information on usage and redistribution. */ -#define SRE_MAGIC 20171005 +#define SRE_MAGIC 20220318 #define SRE_OP_FAILURE 0 #define SRE_OP_SUCCESS 1 #define SRE_OP_ANY 2 @@ -40,19 +40,22 @@ #define SRE_OP_REPEAT_ONE 25 #define SRE_OP_SUBPATTERN 26 #define SRE_OP_MIN_REPEAT_ONE 27 -#define SRE_OP_GROUPREF_IGNORE 28 -#define SRE_OP_IN_IGNORE 29 -#define SRE_OP_LITERAL_IGNORE 30 -#define SRE_OP_NOT_LITERAL_IGNORE 31 -#define SRE_OP_GROUPREF_LOC_IGNORE 32 -#define SRE_OP_IN_LOC_IGNORE 33 -#define SRE_OP_LITERAL_LOC_IGNORE 34 -#define SRE_OP_NOT_LITERAL_LOC_IGNORE 35 -#define SRE_OP_GROUPREF_UNI_IGNORE 36 -#define SRE_OP_IN_UNI_IGNORE 37 -#define SRE_OP_LITERAL_UNI_IGNORE 38 -#define SRE_OP_NOT_LITERAL_UNI_IGNORE 39 -#define SRE_OP_RANGE_UNI_IGNORE 40 +#define SRE_OP_ATOMIC_GROUP 28 +#define SRE_OP_POSSESSIVE_REPEAT 29 +#define SRE_OP_POSSESSIVE_REPEAT_ONE 30 +#define SRE_OP_GROUPREF_IGNORE 31 +#define SRE_OP_IN_IGNORE 32 +#define SRE_OP_LITERAL_IGNORE 33 +#define SRE_OP_NOT_LITERAL_IGNORE 34 +#define SRE_OP_GROUPREF_LOC_IGNORE 35 +#define SRE_OP_IN_LOC_IGNORE 36 +#define SRE_OP_LITERAL_LOC_IGNORE 37 +#define SRE_OP_NOT_LITERAL_LOC_IGNORE 38 +#define SRE_OP_GROUPREF_UNI_IGNORE 39 +#define SRE_OP_IN_UNI_IGNORE 40 +#define SRE_OP_LITERAL_UNI_IGNORE 41 +#define SRE_OP_NOT_LITERAL_UNI_IGNORE 42 +#define SRE_OP_RANGE_UNI_IGNORE 43 #define SRE_AT_BEGINNING 0 #define SRE_AT_BEGINNING_LINE 1 #define SRE_AT_BEGINNING_STRING 2 diff --git a/Modules/sre_lib.h b/Modules/sre_lib.h index 32469cd161cf3..956fd3fad9164 100644 --- a/Modules/sre_lib.h +++ b/Modules/sre_lib.h @@ -480,6 +480,9 @@ do { \ #define JUMP_BRANCH 11 #define JUMP_ASSERT 12 #define JUMP_ASSERT_NOT 13 +#define JUMP_POSS_REPEAT_1 14 +#define JUMP_POSS_REPEAT_2 15 +#define JUMP_ATOMIC_GROUP 16 #define DO_JUMPX(jumpvalue, jumplabel, nextpattern, toplevel_) \ DATA_ALLOC(SRE(match_context), nextctx); \ @@ -950,6 +953,60 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) } RETURN_FAILURE; + case SRE_OP_POSSESSIVE_REPEAT_ONE: + /* match repeated sequence (maximizing regexp) without + backtracking */ + + /* this operator only works if the repeated item is + exactly one character wide, and we're not already + collecting backtracking points. for other cases, + use the MAX_REPEAT operator */ + + /* <1=min> <2=max> item + tail */ + + TRACE(("|%p|%p|POSSESSIVE_REPEAT_ONE %d %d\n", ctx->pattern, + ctx->ptr, ctx->pattern[1], ctx->pattern[2])); + + if (ctx->ptr + ctx->pattern[1] > end) { + RETURN_FAILURE; /* cannot match */ + } + + state->ptr = ctx->ptr; + + ret = SRE(count)(state, ctx->pattern + 3, ctx->pattern[2]); + RETURN_ON_ERROR(ret); + DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos); + ctx->count = ret; + ctx->ptr += ctx->count; + + /* when we arrive here, count contains the number of + matches, and ctx->ptr points to the tail of the target + string. check if the rest of the pattern matches, + and fail if not. */ + + /* Test for not enough repetitions in match */ + if (ctx->count < (Py_ssize_t) ctx->pattern[1]) { + RETURN_FAILURE; + } + + /* Update the pattern to point to the next op code */ + ctx->pattern += ctx->pattern[0]; + + /* Let the tail be evaluated separately and consider this + match successful. */ + if (*ctx->pattern == SRE_OP_SUCCESS && + ctx->ptr == state->end && + !(ctx->toplevel && state->must_advance && ctx->ptr == state->start)) + { + /* tail is empty. we're finished */ + state->ptr = ctx->ptr; + RETURN_SUCCESS; + } + + /* Attempt to match the rest of the string */ + break; + case SRE_OP_REPEAT: /* create repeat context. all the hard work is done by the UNTIL operator (MAX_UNTIL, MIN_UNTIL) */ @@ -1110,6 +1167,138 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) state->ptr = ctx->ptr; RETURN_FAILURE; + case SRE_OP_POSSESSIVE_REPEAT: + /* create possessive repeat contexts. */ + /* <1=min> <2=max> pattern + tail */ + TRACE(("|%p|%p|POSSESSIVE_REPEAT %d %d\n", ctx->pattern, + ctx->ptr, ctx->pattern[1], ctx->pattern[2])); + + /* Set the global Input pointer to this context's Input + pointer */ + state->ptr = ctx->ptr; + + /* Initialize Count to 0 */ + ctx->count = 0; + + /* Check for minimum required matches. */ + while (ctx->count < (Py_ssize_t)ctx->pattern[1]) { + /* not enough matches */ + DO_JUMP(JUMP_POSS_REPEAT_1, jump_poss_repeat_1, + &ctx->pattern[3]); + if (ret) { + RETURN_ON_ERROR(ret); + ctx->count++; + } + else { + state->ptr = ctx->ptr; + RETURN_FAILURE; + } + } + + /* Clear the context's Input stream pointer so that it + doesn't match the global state so that the while loop can + be entered. */ + ctx->ptr = NULL; + + /* Keep trying to parse the sub-pattern until the + end is reached, creating a new context each time. */ + while ((ctx->count < (Py_ssize_t)ctx->pattern[2] || + (Py_ssize_t)ctx->pattern[2] == SRE_MAXREPEAT) && + state->ptr != ctx->ptr) { + /* Save the Capture Group Marker state into the current + Context and back up the current highest number + Capture Group marker. */ + LASTMARK_SAVE(); + MARK_PUSH(ctx->lastmark); + + /* zero-width match protection */ + /* Set the context's Input Stream pointer to be the + current Input Stream pointer from the global + state. When the loop reaches the next iteration, + the context will then store the last known good + position with the global state holding the Input + Input Stream position that has been updated with + the most recent match. Thus, if state's Input + stream remains the same as the one stored in the + current Context, we know we have successfully + matched an empty string and that all subsequent + matches will also be the empty string until the + maximum number of matches are counted, and because + of this, we could immediately stop at that point and + consider this match successful. */ + ctx->ptr = state->ptr; + + /* We have not reached the maximin matches, so try to + match once more. */ + DO_JUMP(JUMP_POSS_REPEAT_2, jump_poss_repeat_2, + &ctx->pattern[3]); + + /* Check to see if the last attempted match + succeeded. */ + if (ret) { + /* Drop the saved highest number Capture Group + marker saved above and use the newly updated + value. */ + MARK_POP_DISCARD(ctx->lastmark); + RETURN_ON_ERROR(ret); + + /* Success, increment the count. */ + ctx->count++; + } + /* Last attempted match failed. */ + else { + /* Restore the previously saved highest number + Capture Group marker since the last iteration + did not match, then restore that to the global + state. */ + MARK_POP(ctx->lastmark); + LASTMARK_RESTORE(); + + /* We have sufficient matches, so exit loop. */ + break; + } + } + + /* Evaluate Tail */ + /* Jump to end of pattern indicated by skip, and then skip + the SUCCESS op code that follows it. */ + ctx->pattern += ctx->pattern[0] + 1; + ctx->ptr = state->ptr; + break; + + case SRE_OP_ATOMIC_GROUP: + /* Atomic Group Sub Pattern */ + /* pattern tail */ + TRACE(("|%p|%p|ATOMIC_GROUP\n", ctx->pattern, ctx->ptr)); + + /* Set the global Input pointer to this context's Input + pointer */ + state->ptr = ctx->ptr; + + /* Evaluate the Atomic Group in a new context, terminating + when the end of the group, represented by a SUCCESS op + code, is reached. */ + /* Group Pattern begins at an offset of 1 code. */ + DO_JUMP(JUMP_ATOMIC_GROUP, jump_atomic_group, + &ctx->pattern[1]); + + /* Test Exit Condition */ + RETURN_ON_ERROR(ret); + + if (ret == 0) { + /* Atomic Group failed to Match. */ + state->ptr = ctx->ptr; + RETURN_FAILURE; + } + + /* Evaluate Tail */ + /* Jump to end of pattern indicated by skip, and then skip + the SUCCESS op code that follows it. */ + ctx->pattern += ctx->pattern[0]; + ctx->ptr = state->ptr; + break; + case SRE_OP_GROUPREF: /* match backreference */ TRACE(("|%p|%p|GROUPREF %d\n", ctx->pattern, @@ -1306,6 +1495,12 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) case JUMP_MIN_UNTIL_1: TRACE(("|%p|%p|JUMP_MIN_UNTIL_1\n", ctx->pattern, ctx->ptr)); goto jump_min_until_1; + case JUMP_POSS_REPEAT_1: + TRACE(("|%p|%p|JUMP_POSS_REPEAT_1\n", ctx->pattern, ctx->ptr)); + goto jump_poss_repeat_1; + case JUMP_POSS_REPEAT_2: + TRACE(("|%p|%p|JUMP_POSS_REPEAT_2\n", ctx->pattern, ctx->ptr)); + goto jump_poss_repeat_2; case JUMP_REPEAT: TRACE(("|%p|%p|JUMP_REPEAT\n", ctx->pattern, ctx->ptr)); goto jump_repeat; @@ -1318,6 +1513,9 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) case JUMP_MIN_REPEAT_ONE: TRACE(("|%p|%p|JUMP_MIN_REPEAT_ONE\n", ctx->pattern, ctx->ptr)); goto jump_min_repeat_one; + case JUMP_ATOMIC_GROUP: + TRACE(("|%p|%p|JUMP_ATOMIC_GROUP\n", ctx->pattern, ctx->ptr)); + goto jump_atomic_group; case JUMP_ASSERT: TRACE(("|%p|%p|JUMP_ASSERT\n", ctx->pattern, ctx->ptr)); goto jump_assert; From webhook-mailer at python.org Mon Mar 21 13:49:53 2022 From: webhook-mailer at python.org (tim-one) Date: Mon, 21 Mar 2022 17:49:53 -0000 Subject: [Python-checkins] bpo-47080: Use atomic groups to simplify fnmatch (GH-32029) Message-ID: https://github.com/python/cpython/commit/5c3201e146b251017cd77202015f47912ddcb980 commit: 5c3201e146b251017cd77202015f47912ddcb980 branch: main author: Tim Peters committer: tim-one date: 2022-03-21T12:49:43-05:00 summary: bpo-47080: Use atomic groups to simplify fnmatch (GH-32029) Use re's new atomic groups to greatly simplify the construction of worst-case linear-time patterns. files: M Lib/fnmatch.py M Lib/test/test_fnmatch.py diff --git a/Lib/fnmatch.py b/Lib/fnmatch.py index 239c7490d49ee..0f5a41ac06f3e 100644 --- a/Lib/fnmatch.py +++ b/Lib/fnmatch.py @@ -16,12 +16,6 @@ __all__ = ["filter", "fnmatch", "fnmatchcase", "translate"] -# Build a thread-safe incrementing counter to help create unique regexp group -# names across calls. -from itertools import count -_nextgroupnum = count().__next__ -del count - def fnmatch(name, pat): """Test whether FILENAME matches PATTERN. @@ -149,17 +143,10 @@ def translate(pat): # Now deal with STAR fixed STAR fixed ... # For an interior `STAR fixed` pairing, we want to do a minimal # .*? match followed by `fixed`, with no possibility of backtracking. - # We can't spell that directly, but can trick it into working by matching - # .*?fixed - # in a lookahead assertion, save the matched part in a group, then - # consume that group via a backreference. If the overall match fails, - # the lookahead assertion won't try alternatives. So the translation is: - # (?=(?P.*?fixed))(?P=name) - # Group names are created as needed: g0, g1, g2, ... - # The numbers are obtained from _nextgroupnum() to ensure they're unique - # across calls and across threads. This is because people rely on the - # undocumented ability to join multiple translate() results together via - # "|" to build large regexps matching "one of many" shell patterns. + # Atomic groups ("(?>...)") allow us to spell that directly. + # Note: people rely on the undocumented ability to join multiple + # translate() results together via "|" to build large regexps matching + # "one of many" shell patterns. while i < n: assert inp[i] is STAR i += 1 @@ -176,8 +163,7 @@ def translate(pat): add(".*") add(fixed) else: - groupnum = _nextgroupnum() - add(f"(?=(?P.*?{fixed}))(?P=g{groupnum})") + add(f"(?>.*?{fixed})") assert i == n res = "".join(res) return fr'(?s:{res})\Z' diff --git a/Lib/test/test_fnmatch.py b/Lib/test/test_fnmatch.py index 10668e4f6103a..ca695d6f3f019 100644 --- a/Lib/test/test_fnmatch.py +++ b/Lib/test/test_fnmatch.py @@ -124,17 +124,9 @@ def test_translate(self): self.assertEqual(translate('A*********?[?]?'), r'(?s:A.*.[?].)\Z') # fancy translation to prevent exponential-time match failure t = translate('**a*a****a') - digits = re.findall(r'\d+', t) - self.assertEqual(len(digits), 4) - self.assertEqual(digits[0], digits[1]) - self.assertEqual(digits[2], digits[3]) - g1 = f"g{digits[0]}" # e.g., group name "g4" - g2 = f"g{digits[2]}" # e.g., group name "g5" - self.assertEqual(t, - fr'(?s:(?=(?P<{g1}>.*?a))(?P={g1})(?=(?P<{g2}>.*?a))(?P={g2}).*a)\Z') + self.assertEqual(t, r'(?s:(?>.*?a)(?>.*?a).*a)\Z') # and try pasting multiple translate results - it's an undocumented - # feature that this works; all the pain of generating unique group - # names across calls exists to support this + # feature that this works r1 = translate('**a**a**a*') r2 = translate('**b**b**b*') r3 = translate('*c*c*c*') From webhook-mailer at python.org Mon Mar 21 16:33:25 2022 From: webhook-mailer at python.org (sweeneyde) Date: Mon, 21 Mar 2022 20:33:25 -0000 Subject: [Python-checkins] bpo-47067: Optimize calling GenericAlias objects (GH-31996) Message-ID: https://github.com/python/cpython/commit/1ea055bd53ccf976e88018983a3c13447c4502be commit: 1ea055bd53ccf976e88018983a3c13447c4502be branch: main author: penguin_wwy <940375606 at qq.com> committer: sweeneyde <36520290+sweeneyde at users.noreply.github.com> date: 2022-03-21T16:33:02-04:00 summary: bpo-47067: Optimize calling GenericAlias objects (GH-31996) Use vectorcall, and replace `PyObject_SetAttrString` with `PyObject_SetAttr` and a global string. files: A Misc/NEWS.d/next/Library/2022-03-20-17-15-56.bpo-47067.XXLnje.rst M Include/internal/pycore_global_strings.h M Include/internal/pycore_runtime_init.h M Objects/genericaliasobject.c diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h index 35bffa7aff949..1d83bf2cfad4c 100644 --- a/Include/internal/pycore_global_strings.h +++ b/Include/internal/pycore_global_strings.h @@ -156,6 +156,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(__next__) STRUCT_FOR_ID(__note__) STRUCT_FOR_ID(__or__) + STRUCT_FOR_ID(__orig_class__) STRUCT_FOR_ID(__origin__) STRUCT_FOR_ID(__package__) STRUCT_FOR_ID(__parameters__) diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h index 20d543a8cbc56..d5690d83a0482 100644 --- a/Include/internal/pycore_runtime_init.h +++ b/Include/internal/pycore_runtime_init.h @@ -779,6 +779,7 @@ extern "C" { INIT_ID(__next__), \ INIT_ID(__note__), \ INIT_ID(__or__), \ + INIT_ID(__orig_class__), \ INIT_ID(__origin__), \ INIT_ID(__package__), \ INIT_ID(__parameters__), \ diff --git a/Misc/NEWS.d/next/Library/2022-03-20-17-15-56.bpo-47067.XXLnje.rst b/Misc/NEWS.d/next/Library/2022-03-20-17-15-56.bpo-47067.XXLnje.rst new file mode 100644 index 0000000000000..28c0895681c40 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-20-17-15-56.bpo-47067.XXLnje.rst @@ -0,0 +1 @@ +Optimize calling ``GenericAlias`` objects by using :pep:`590` ``vectorcall`` and by replacing ``PyObject_SetAttrString`` with ``PyObject_SetAttr``. diff --git a/Objects/genericaliasobject.c b/Objects/genericaliasobject.c index 224a2e9acb748..3f03630005bc5 100644 --- a/Objects/genericaliasobject.c +++ b/Objects/genericaliasobject.c @@ -12,9 +12,10 @@ typedef struct { PyObject *origin; PyObject *args; PyObject *parameters; - PyObject* weakreflist; + PyObject *weakreflist; // Whether we're a starred type, e.g. *tuple[int]. bool starred; + vectorcallfunc vectorcall; } gaobject; typedef struct { @@ -383,13 +384,11 @@ ga_hash(PyObject *self) return h0 ^ h1; } -static PyObject * -ga_call(PyObject *self, PyObject *args, PyObject *kwds) +static inline PyObject * +set_orig_class(PyObject *obj, PyObject *self) { - gaobject *alias = (gaobject *)self; - PyObject *obj = PyObject_Call(alias->origin, args, kwds); if (obj != NULL) { - if (PyObject_SetAttrString(obj, "__orig_class__", self) < 0) { + if (PyObject_SetAttr(obj, &_Py_ID(__orig_class__), self) < 0) { if (!PyErr_ExceptionMatches(PyExc_AttributeError) && !PyErr_ExceptionMatches(PyExc_TypeError)) { @@ -402,6 +401,23 @@ ga_call(PyObject *self, PyObject *args, PyObject *kwds) return obj; } +static PyObject * +ga_call(PyObject *self, PyObject *args, PyObject *kwds) +{ + gaobject *alias = (gaobject *)self; + PyObject *obj = PyObject_Call(alias->origin, args, kwds); + return set_orig_class(obj, self); +} + +static PyObject * +ga_vectorcall(PyObject *self, PyObject *const *args, + size_t nargsf, PyObject *kwnames) +{ + gaobject *alias = (gaobject *) self; + PyObject *obj = PyVectorcall_Function(alias->origin)(alias->origin, args, nargsf, kwnames); + return set_orig_class(obj, self); +} + static const char* const attr_exceptions[] = { "__origin__", "__args__", @@ -588,6 +604,14 @@ setup_ga(gaobject *alias, PyObject *origin, PyObject *args) { alias->args = args; alias->parameters = NULL; alias->weakreflist = NULL; + + if (PyVectorcall_Function(origin) != NULL) { + alias->vectorcall = ga_vectorcall; + } + else { + alias->vectorcall = NULL; + } + return 1; } @@ -695,7 +719,7 @@ PyTypeObject Py_GenericAliasType = { .tp_hash = ga_hash, .tp_call = ga_call, .tp_getattro = ga_getattro, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_VECTORCALL, .tp_traverse = ga_traverse, .tp_richcompare = ga_richcompare, .tp_weaklistoffset = offsetof(gaobject, weakreflist), @@ -706,6 +730,7 @@ PyTypeObject Py_GenericAliasType = { .tp_free = PyObject_GC_Del, .tp_getset = ga_properties, .tp_iter = (getiterfunc)ga_iter, + .tp_vectorcall_offset = offsetof(gaobject, vectorcall), }; PyObject * From webhook-mailer at python.org Mon Mar 21 16:41:45 2022 From: webhook-mailer at python.org (iritkatriel) Date: Mon, 21 Mar 2022 20:41:45 -0000 Subject: [Python-checkins] bpo-12029: [doc] clarify that except does not match virtual subclasses of the specified exception type (GH-32027) Message-ID: https://github.com/python/cpython/commit/45833b50f0ccf2abb01304c900afee05b6d01b9e commit: 45833b50f0ccf2abb01304c900afee05b6d01b9e branch: main author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-03-21T20:41:35Z summary: bpo-12029: [doc] clarify that except does not match virtual subclasses of the specified exception type (GH-32027) files: M Doc/reference/compound_stmts.rst M Doc/reference/executionmodel.rst diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index 15a51e7fc7bea..92024e51ef4fc 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -243,9 +243,10 @@ is found that matches the exception. An expression-less except clause, if present, must be last; it matches any exception. For an except clause with an expression, that expression is evaluated, and the clause matches the exception if the resulting object is "compatible" with the exception. An object is -compatible with an exception if the object is the class or a base class of the exception -object, or a tuple containing an item that is the class or a base class of -the exception object. +compatible with an exception if the object is the class or a +:term:`non-virtual base class ` of the exception object, +or a tuple containing an item that is the class or a non-virtual base class +of the exception object. If no except clause matches the exception, the search for an exception handler continues in the surrounding code and on the invocation stack. [#]_ diff --git a/Doc/reference/executionmodel.rst b/Doc/reference/executionmodel.rst index e652915bd271c..d9183561820b2 100644 --- a/Doc/reference/executionmodel.rst +++ b/Doc/reference/executionmodel.rst @@ -259,8 +259,9 @@ a stack traceback, except when the exception is :exc:`SystemExit`. Exceptions are identified by class instances. The :keyword:`except` clause is selected depending on the class of the instance: it must reference the class of -the instance or a base class thereof. The instance can be received by the -handler and can carry additional information about the exceptional condition. +the instance or a :term:`non-virtual base class ` thereof. +The instance can be received by the handler and can carry additional information +about the exceptional condition. .. note:: From webhook-mailer at python.org Mon Mar 21 17:22:54 2022 From: webhook-mailer at python.org (iritkatriel) Date: Mon, 21 Mar 2022 21:22:54 -0000 Subject: [Python-checkins] bpo-12029: [doc] clarify that except does not match virtual subclasses of the specified exception type (GH-32027) (GH-32034) Message-ID: https://github.com/python/cpython/commit/7fc12540e3e873d8ff49711e70fd691185f977b9 commit: 7fc12540e3e873d8ff49711e70fd691185f977b9 branch: 3.10 author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-03-21T21:22:39Z summary: bpo-12029: [doc] clarify that except does not match virtual subclasses of the specified exception type (GH-32027) (GH-32034) (cherry picked from commit 45833b50f0ccf2abb01304c900afee05b6d01b9e) files: M Doc/reference/compound_stmts.rst M Doc/reference/executionmodel.rst diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index 7f37bb4fdf9c9..871c101996b15 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -233,9 +233,10 @@ is found that matches the exception. An expression-less except clause, if present, must be last; it matches any exception. For an except clause with an expression, that expression is evaluated, and the clause matches the exception if the resulting object is "compatible" with the exception. An object is -compatible with an exception if it is the class or a base class of the exception -object, or a tuple containing an item that is the class or a base class of -the exception object. +compatible with an exception if the object is the class or a +:term:`non-virtual base class ` of the exception object, +or a tuple containing an item that is the class or a non-virtual base class +of the exception object. If no except clause matches the exception, the search for an exception handler continues in the surrounding code and on the invocation stack. [#]_ diff --git a/Doc/reference/executionmodel.rst b/Doc/reference/executionmodel.rst index e652915bd271c..d9183561820b2 100644 --- a/Doc/reference/executionmodel.rst +++ b/Doc/reference/executionmodel.rst @@ -259,8 +259,9 @@ a stack traceback, except when the exception is :exc:`SystemExit`. Exceptions are identified by class instances. The :keyword:`except` clause is selected depending on the class of the instance: it must reference the class of -the instance or a base class thereof. The instance can be received by the -handler and can carry additional information about the exceptional condition. +the instance or a :term:`non-virtual base class ` thereof. +The instance can be received by the handler and can carry additional information +about the exceptional condition. .. note:: From webhook-mailer at python.org Mon Mar 21 17:28:17 2022 From: webhook-mailer at python.org (iritkatriel) Date: Mon, 21 Mar 2022 21:28:17 -0000 Subject: [Python-checkins] bpo-12029: [doc] clarify that except does not match virtual subclasses of the specified exception type (GH-32027) (GH-32035) Message-ID: https://github.com/python/cpython/commit/2d5e9f8d6296cc52da9823bb57e7f03d60b34d27 commit: 2d5e9f8d6296cc52da9823bb57e7f03d60b34d27 branch: 3.9 author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-03-21T21:27:53Z summary: bpo-12029: [doc] clarify that except does not match virtual subclasses of the specified exception type (GH-32027) (GH-32035) (cherry picked from commit 45833b50f0ccf2abb01304c900afee05b6d01b9e) files: M Doc/reference/compound_stmts.rst M Doc/reference/executionmodel.rst diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index 0bc1e24437100..493fd707164bd 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -253,9 +253,10 @@ is found that matches the exception. An expression-less except clause, if present, must be last; it matches any exception. For an except clause with an expression, that expression is evaluated, and the clause matches the exception if the resulting object is "compatible" with the exception. An object is -compatible with an exception if it is the class or a base class of the exception -object, or a tuple containing an item that is the class or a base class of -the exception object. +compatible with an exception if the object is the class or a +:term:`non-virtual base class ` of the exception object, +or a tuple containing an item that is the class or a non-virtual base class +of the exception object. If no except clause matches the exception, the search for an exception handler continues in the surrounding code and on the invocation stack. [#]_ diff --git a/Doc/reference/executionmodel.rst b/Doc/reference/executionmodel.rst index 5c85dd7052d67..5eed24e6ee4a5 100644 --- a/Doc/reference/executionmodel.rst +++ b/Doc/reference/executionmodel.rst @@ -249,8 +249,9 @@ a stack traceback, except when the exception is :exc:`SystemExit`. Exceptions are identified by class instances. The :keyword:`except` clause is selected depending on the class of the instance: it must reference the class of -the instance or a base class thereof. The instance can be received by the -handler and can carry additional information about the exceptional condition. +the instance or a :term:`non-virtual base class ` thereof. +The instance can be received by the handler and can carry additional information +about the exceptional condition. .. note:: From webhook-mailer at python.org Mon Mar 21 19:12:06 2022 From: webhook-mailer at python.org (sweeneyde) Date: Mon, 21 Mar 2022 23:12:06 -0000 Subject: [Python-checkins] Fix typo in pycore_bytesobject.h (GH-31914) Message-ID: https://github.com/python/cpython/commit/d5d625199e41580bb9372c16add4f13b9af2c223 commit: d5d625199e41580bb9372c16add4f13b9af2c223 branch: main author: jonasdlindner <42033762+jonasdlindner at users.noreply.github.com> committer: sweeneyde <36520290+sweeneyde at users.noreply.github.com> date: 2022-03-21T19:11:50-04:00 summary: Fix typo in pycore_bytesobject.h (GH-31914) files: M Include/internal/pycore_bytesobject.h diff --git a/Include/internal/pycore_bytesobject.h b/Include/internal/pycore_bytesobject.h index 8739a759ec36b..b8061607a518d 100644 --- a/Include/internal/pycore_bytesobject.h +++ b/Include/internal/pycore_bytesobject.h @@ -16,7 +16,7 @@ extern PyStatus _PyBytes_InitTypes(PyInterpreterState *); /* Substring Search. - Returns the index of the first occurence of + Returns the index of the first occurrence of a substring ("needle") in a larger text ("haystack"). If the needle is not found, return -1. If the needle is found, add offset to the index. From webhook-mailer at python.org Mon Mar 21 19:16:45 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 21 Mar 2022 23:16:45 -0000 Subject: [Python-checkins] bpo-47061: document module deprecations due to PEP 594 (GH-31984) Message-ID: https://github.com/python/cpython/commit/9ac2de922a0f783bd43b8e026e4fb70fd1888572 commit: 9ac2de922a0f783bd43b8e026e4fb70fd1888572 branch: main author: Brett Cannon committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-21T16:16:37-07:00 summary: bpo-47061: document module deprecations due to PEP 594 (GH-31984) Also removed asynchat, asyncore, and smtpd from their respective toctree entries so they are only in the superceded subtree. files: A Misc/NEWS.d/next/Library/2022-03-18-13-30-40.bpo-47061.etLHK5.rst M Doc/library/aifc.rst M Doc/library/audioop.rst M Doc/library/cgi.rst M Doc/library/cgitb.rst M Doc/library/chunk.rst M Doc/library/crypt.rst M Doc/library/fileformats.rst M Doc/library/imghdr.rst M Doc/library/internet.rst M Doc/library/ipc.rst M Doc/library/mm.rst M Doc/library/msilib.rst M Doc/library/netdata.rst M Doc/library/nis.rst M Doc/library/nntplib.rst M Doc/library/ossaudiodev.rst M Doc/library/pipes.rst M Doc/library/sndhdr.rst M Doc/library/spwd.rst M Doc/library/sunau.rst M Doc/library/superseded.rst M Doc/library/telnetlib.rst M Doc/library/unix.rst M Doc/library/uu.rst M Doc/library/windows.rst M Doc/library/xdrlib.rst diff --git a/Doc/library/aifc.rst b/Doc/library/aifc.rst index 2e917cf7321b8..edb4bf86e5a0a 100644 --- a/Doc/library/aifc.rst +++ b/Doc/library/aifc.rst @@ -3,6 +3,7 @@ .. module:: aifc :synopsis: Read and write audio files in AIFF or AIFC format. + :deprecated: **Source code:** :source:`Lib/aifc.py` @@ -11,6 +12,10 @@ single: AIFF single: AIFF-C + +.. deprecated:: 3.11 + The :mod:`aifc` module is deprecated (see :pep:`594` for details). + -------------- This module provides support for reading and writing AIFF and AIFF-C files. diff --git a/Doc/library/audioop.rst b/Doc/library/audioop.rst index bad9da2ec62e5..eae206084f090 100644 --- a/Doc/library/audioop.rst +++ b/Doc/library/audioop.rst @@ -3,6 +3,10 @@ .. module:: audioop :synopsis: Manipulate raw audio data. + :deprecated: + +.. deprecated:: 3.11 + The :mod:`audioop` module is deprecated (see :pep:`594` for details). -------------- diff --git a/Doc/library/cgi.rst b/Doc/library/cgi.rst index a2957ba5a68ad..7e697408af07b 100644 --- a/Doc/library/cgi.rst +++ b/Doc/library/cgi.rst @@ -3,6 +3,7 @@ .. module:: cgi :synopsis: Helpers for running Python scripts via the Common Gateway Interface. + :deprecated: **Source code:** :source:`Lib/cgi.py` @@ -14,6 +15,9 @@ single: URL single: Common Gateway Interface +.. deprecated:: 3.11 + The :mod:`cgi` module is deprecated (see :pep:`594` for details). + -------------- Support module for Common Gateway Interface (CGI) scripts. diff --git a/Doc/library/cgitb.rst b/Doc/library/cgitb.rst index 5f3a6476dd8cd..349414610bd40 100644 --- a/Doc/library/cgitb.rst +++ b/Doc/library/cgitb.rst @@ -3,6 +3,7 @@ .. module:: cgitb :synopsis: Configurable traceback handler for CGI scripts. + :deprecated: .. moduleauthor:: Ka-Ping Yee .. sectionauthor:: Fred L. Drake, Jr. @@ -15,6 +16,9 @@ single: exceptions; in CGI scripts single: tracebacks; in CGI scripts +.. deprecated:: 3.11 + The :mod:`cgitb` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`cgitb` module provides a special exception handler for Python scripts. diff --git a/Doc/library/chunk.rst b/Doc/library/chunk.rst index 5e24df923ed21..7999420f536d7 100644 --- a/Doc/library/chunk.rst +++ b/Doc/library/chunk.rst @@ -3,6 +3,7 @@ .. module:: chunk :synopsis: Module to read IFF chunks. + :deprecated: .. moduleauthor:: Sjoerd Mullender .. sectionauthor:: Sjoerd Mullender @@ -16,6 +17,9 @@ single: Real Media File Format single: RMFF +.. deprecated:: 3.11 + The :mod:`chunk` module is deprecated (see :pep:`594` for details). + -------------- This module provides an interface for reading files that use EA IFF 85 chunks. diff --git a/Doc/library/crypt.rst b/Doc/library/crypt.rst index d25c626a17585..73df87ca0db8d 100644 --- a/Doc/library/crypt.rst +++ b/Doc/library/crypt.rst @@ -4,6 +4,7 @@ .. module:: crypt :platform: Unix :synopsis: The crypt() function used to check Unix passwords. + :deprecated: .. moduleauthor:: Steven D. Majewski .. sectionauthor:: Steven D. Majewski @@ -15,6 +16,9 @@ single: crypt(3) pair: cipher; DES +.. deprecated:: 3.11 + The :mod:`crypt` module is deprecated (see :pep:`594` for details). + -------------- This module implements an interface to the :manpage:`crypt(3)` routine, which is diff --git a/Doc/library/fileformats.rst b/Doc/library/fileformats.rst index bb099fe2d3d6e..cab82b30ef42d 100644 --- a/Doc/library/fileformats.rst +++ b/Doc/library/fileformats.rst @@ -14,5 +14,4 @@ that aren't markup languages and are not related to e-mail. configparser.rst tomllib.rst netrc.rst - xdrlib.rst plistlib.rst diff --git a/Doc/library/imghdr.rst b/Doc/library/imghdr.rst index 3d7f6de7a1bec..084fef73daf28 100644 --- a/Doc/library/imghdr.rst +++ b/Doc/library/imghdr.rst @@ -3,9 +3,13 @@ .. module:: imghdr :synopsis: Determine the type of image contained in a file or byte stream. + :deprecated: **Source code:** :source:`Lib/imghdr.py` +.. deprecated:: 3.11 + The :mod:`imghdr` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`imghdr` module determines the type of image contained in a file or diff --git a/Doc/library/internet.rst b/Doc/library/internet.rst index e745dd1243512..ff58dcf4d89c3 100644 --- a/Doc/library/internet.rst +++ b/Doc/library/internet.rst @@ -20,8 +20,6 @@ is currently supported on most popular platforms. Here is an overview: .. toctree:: webbrowser.rst - cgi.rst - cgitb.rst wsgiref.rst urllib.rst urllib.request.rst @@ -33,10 +31,7 @@ is currently supported on most popular platforms. Here is an overview: ftplib.rst poplib.rst imaplib.rst - nntplib.rst smtplib.rst - smtpd.rst - telnetlib.rst uuid.rst socketserver.rst http.server.rst diff --git a/Doc/library/ipc.rst b/Doc/library/ipc.rst index b88a174eb97f1..4849c82f317d9 100644 --- a/Doc/library/ipc.rst +++ b/Doc/library/ipc.rst @@ -22,7 +22,5 @@ The list of modules described in this chapter is: ssl.rst select.rst selectors.rst - asyncore.rst - asynchat.rst signal.rst mmap.rst diff --git a/Doc/library/mm.rst b/Doc/library/mm.rst index c8f79c4de1cdf..cd06e9385a261 100644 --- a/Doc/library/mm.rst +++ b/Doc/library/mm.rst @@ -11,12 +11,5 @@ discretion of the installation. Here's an overview: .. toctree:: - audioop.rst - aifc.rst - sunau.rst wave.rst - chunk.rst colorsys.rst - imghdr.rst - sndhdr.rst - ossaudiodev.rst diff --git a/Doc/library/msilib.rst b/Doc/library/msilib.rst index 22638852e31ea..b2fa20873fbbf 100644 --- a/Doc/library/msilib.rst +++ b/Doc/library/msilib.rst @@ -4,6 +4,7 @@ .. module:: msilib :platform: Windows :synopsis: Creation of Microsoft Installer files, and CAB files. + :deprecated: .. moduleauthor:: Martin v. L?wis .. sectionauthor:: Martin v. L?wis @@ -12,6 +13,9 @@ .. index:: single: msi +.. deprecated:: 3.11 + The :mod:`msilib` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`msilib` supports the creation of Microsoft Installer (``.msi``) files. diff --git a/Doc/library/netdata.rst b/Doc/library/netdata.rst index 16f43a69d68b2..8955e859ab634 100644 --- a/Doc/library/netdata.rst +++ b/Doc/library/netdata.rst @@ -19,4 +19,3 @@ on the internet. base64.rst binascii.rst quopri.rst - uu.rst diff --git a/Doc/library/nis.rst b/Doc/library/nis.rst index 10c67cbb81b2f..f6b6ea83946b0 100644 --- a/Doc/library/nis.rst +++ b/Doc/library/nis.rst @@ -5,10 +5,14 @@ .. module:: nis :platform: Unix :synopsis: Interface to Sun's NIS (Yellow Pages) library. + :deprecated: .. moduleauthor:: Fred Gansevles .. sectionauthor:: Moshe Zadka +.. deprecated:: 3.11 + The :mod:`nis` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`nis` module gives a thin wrapper around the NIS library, useful for diff --git a/Doc/library/nntplib.rst b/Doc/library/nntplib.rst index e7ec9047e015e..2a996e451bf7c 100644 --- a/Doc/library/nntplib.rst +++ b/Doc/library/nntplib.rst @@ -3,6 +3,7 @@ .. module:: nntplib :synopsis: NNTP protocol client (requires sockets). + :deprecated: **Source code:** :source:`Lib/nntplib.py` @@ -10,6 +11,9 @@ pair: NNTP; protocol single: Network News Transfer Protocol +.. deprecated:: 3.11 + The :mod:`nntplib` module is deprecated (see :pep:`594` for details). + -------------- This module defines the class :class:`NNTP` which implements the client side of diff --git a/Doc/library/ossaudiodev.rst b/Doc/library/ossaudiodev.rst index a7d3dac363cdf..e0f0a6b8259e4 100644 --- a/Doc/library/ossaudiodev.rst +++ b/Doc/library/ossaudiodev.rst @@ -4,6 +4,10 @@ .. module:: ossaudiodev :platform: Linux, FreeBSD :synopsis: Access to OSS-compatible audio devices. + :deprecated: + +.. deprecated:: 3.11 + The :mod:`ossaudiodev` module is deprecated (see :pep:`594` for details). -------------- diff --git a/Doc/library/pipes.rst b/Doc/library/pipes.rst index 57e27a6acf4b6..4de8c51bcae04 100644 --- a/Doc/library/pipes.rst +++ b/Doc/library/pipes.rst @@ -4,11 +4,15 @@ .. module:: pipes :platform: Unix :synopsis: A Python interface to Unix shell pipelines. + :deprecated: .. sectionauthor:: Moshe Zadka **Source code:** :source:`Lib/pipes.py` +.. deprecated:: 3.11 + The :mod:`pipes` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`pipes` module defines a class to abstract the concept of a *pipeline* diff --git a/Doc/library/sndhdr.rst b/Doc/library/sndhdr.rst index 6bfa9a9fd210b..41bce18b9cd84 100644 --- a/Doc/library/sndhdr.rst +++ b/Doc/library/sndhdr.rst @@ -3,6 +3,7 @@ .. module:: sndhdr :synopsis: Determine type of a sound file. + :deprecated: .. sectionauthor:: Fred L. Drake, Jr. .. Based on comments in the module source file. @@ -13,6 +14,9 @@ single: A-LAW single: u-LAW +.. deprecated:: 3.11 + The :mod:`sndhdr` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`sndhdr` provides utility functions which attempt to determine the type diff --git a/Doc/library/spwd.rst b/Doc/library/spwd.rst index c6cad2a3c3284..cb31a10a52e00 100644 --- a/Doc/library/spwd.rst +++ b/Doc/library/spwd.rst @@ -4,6 +4,10 @@ .. module:: spwd :platform: Unix :synopsis: The shadow password database (getspnam() and friends). + :deprecated: + +.. deprecated:: 3.11 + The :mod:`spwd` module is deprecated (see :pep:`594` for details). -------------- diff --git a/Doc/library/sunau.rst b/Doc/library/sunau.rst index aad6f93b6bff1..cfb1257f58548 100644 --- a/Doc/library/sunau.rst +++ b/Doc/library/sunau.rst @@ -3,11 +3,15 @@ .. module:: sunau :synopsis: Provide an interface to the Sun AU sound format. + :deprecated: .. sectionauthor:: Moshe Zadka **Source code:** :source:`Lib/sunau.py` +.. deprecated:: 3.11 + The :mod:`sunau` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`sunau` module provides a convenient interface to the Sun AU sound diff --git a/Doc/library/superseded.rst b/Doc/library/superseded.rst index fd23e4d1536d3..e3f9b0d37fe10 100644 --- a/Doc/library/superseded.rst +++ b/Doc/library/superseded.rst @@ -10,8 +10,26 @@ backwards compatibility. They have been superseded by other modules. .. toctree:: + aifc.rst asynchat.rst asyncore.rst - smtpd.rst + audioop.rst + cgi.rst + cgitb.rst + chunk.rst + crypt.rst + imghdr.rst imp.rst + msilib.rst + nntplib.rst + nis.rst optparse.rst + ossaudiodev.rst + pipes.rst + smtpd.rst + sndhdr.rst + spwd.rst + sunau.rst + telnetlib.rst + uu.rst + xdrlib.rst diff --git a/Doc/library/telnetlib.rst b/Doc/library/telnetlib.rst index 48a9aea50dddd..97b0a713e4422 100644 --- a/Doc/library/telnetlib.rst +++ b/Doc/library/telnetlib.rst @@ -3,6 +3,7 @@ .. module:: telnetlib :synopsis: Telnet client class. + :deprecated: .. sectionauthor:: Skip Montanaro @@ -10,6 +11,9 @@ .. index:: single: protocol; Telnet +.. deprecated:: 3.11 + The :mod:`telnetlib` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`telnetlib` module provides a :class:`Telnet` class that implements the diff --git a/Doc/library/unix.rst b/Doc/library/unix.rst index 04d4081f4a073..4553a104d15a2 100644 --- a/Doc/library/unix.rst +++ b/Doc/library/unix.rst @@ -13,14 +13,10 @@ of it. Here's an overview: posix.rst pwd.rst - spwd.rst grp.rst - crypt.rst termios.rst tty.rst pty.rst fcntl.rst - pipes.rst resource.rst - nis.rst syslog.rst diff --git a/Doc/library/uu.rst b/Doc/library/uu.rst index 0bc8021e1bdfc..c341bc83dcfed 100644 --- a/Doc/library/uu.rst +++ b/Doc/library/uu.rst @@ -3,11 +3,15 @@ .. module:: uu :synopsis: Encode and decode files in uuencode format. + :deprecated: .. moduleauthor:: Lance Ellinghouse **Source code:** :source:`Lib/uu.py` +.. deprecated:: 3.11 + The :mod:`uu` module is deprecated (see :pep:`594` for details). + -------------- This module encodes and decodes files in uuencode format, allowing arbitrary diff --git a/Doc/library/windows.rst b/Doc/library/windows.rst index b60d4e4ccf51d..4d72ead12aadc 100644 --- a/Doc/library/windows.rst +++ b/Doc/library/windows.rst @@ -9,7 +9,6 @@ This chapter describes modules that are only available on MS Windows platforms. .. toctree:: - msilib.rst msvcrt.rst winreg.rst winsound.rst diff --git a/Doc/library/xdrlib.rst b/Doc/library/xdrlib.rst index 42a03a46754d0..060b2e2c60df6 100644 --- a/Doc/library/xdrlib.rst +++ b/Doc/library/xdrlib.rst @@ -3,6 +3,7 @@ .. module:: xdrlib :synopsis: Encoders and decoders for the External Data Representation (XDR). + :deprecated: **Source code:** :source:`Lib/xdrlib.py` @@ -10,6 +11,9 @@ single: XDR single: External Data Representation +.. deprecated:: 3.11 + The :mod:`xdrlib` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`xdrlib` module supports the External Data Representation Standard as diff --git a/Misc/NEWS.d/next/Library/2022-03-18-13-30-40.bpo-47061.etLHK5.rst b/Misc/NEWS.d/next/Library/2022-03-18-13-30-40.bpo-47061.etLHK5.rst new file mode 100644 index 0000000000000..5445089e53c39 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-18-13-30-40.bpo-47061.etLHK5.rst @@ -0,0 +1,5 @@ +Deprecate the various modules listed by :pep:`594`: + +aifc, asynchat, asyncore, audioop, cgi, cgitb, chunk, crypt, +imghdr, msilib, nntplib, nis, ossaudiodev, pipes, smtpd, +sndhdr, spwd, sunau, telnetlib, uu, xdrlib From webhook-mailer at python.org Mon Mar 21 20:07:04 2022 From: webhook-mailer at python.org (zooba) Date: Tue, 22 Mar 2022 00:07:04 -0000 Subject: [Python-checkins] bpo-44336: Prevent tests hanging on child process handles on Windows (GH-26578) Message-ID: https://github.com/python/cpython/commit/19058b9f6271338bcc46b7d30fe79a83990cc35c commit: 19058b9f6271338bcc46b7d30fe79a83990cc35c branch: main author: Jeremy Kloth committer: zooba date: 2022-03-22T00:06:55Z summary: bpo-44336: Prevent tests hanging on child process handles on Windows (GH-26578) Replace the child process `typeperf.exe` with a daemon thread that reads the performance counters directly. This prevents the issues that arise from inherited handles in grandchild processes (see issue37531 for discussion). We only use the load tracker when running tests in multiprocess mode. This prevents inadvertent interactions with tests expecting a single threaded environment. Displaying load is really only helpful for buildbots running in multiprocess mode anyway. files: M Lib/test/libregrtest/main.py M Lib/test/libregrtest/win_utils.py diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py index fc3c2b9692055..af58114ed925c 100644 --- a/Lib/test/libregrtest/main.py +++ b/Lib/test/libregrtest/main.py @@ -533,7 +533,24 @@ def run_tests(self): if self.ns.use_mp: from test.libregrtest.runtest_mp import run_tests_multiprocess - run_tests_multiprocess(self) + # If we're on windows and this is the parent runner (not a worker), + # track the load average. + if sys.platform == 'win32' and self.worker_test_name is None: + from test.libregrtest.win_utils import WindowsLoadTracker + + try: + self.win_load_tracker = WindowsLoadTracker() + except PermissionError as error: + # Standard accounts may not have access to the performance + # counters. + print(f'Failed to create WindowsLoadTracker: {error}') + + try: + run_tests_multiprocess(self) + finally: + if self.win_load_tracker is not None: + self.win_load_tracker.close() + self.win_load_tracker = None else: self.run_tests_sequential() @@ -695,28 +712,11 @@ def _main(self, tests, kwargs): self.list_cases() sys.exit(0) - # If we're on windows and this is the parent runner (not a worker), - # track the load average. - if sys.platform == 'win32' and self.worker_test_name is None: - from test.libregrtest.win_utils import WindowsLoadTracker - - try: - self.win_load_tracker = WindowsLoadTracker() - except FileNotFoundError as error: - # Windows IoT Core and Windows Nano Server do not provide - # typeperf.exe for x64, x86 or ARM - print(f'Failed to create WindowsLoadTracker: {error}') + self.run_tests() + self.display_result() - try: - self.run_tests() - self.display_result() - - if self.ns.verbose2 and self.bad: - self.rerun_failed_tests() - finally: - if self.win_load_tracker is not None: - self.win_load_tracker.close() - self.win_load_tracker = None + if self.ns.verbose2 and self.bad: + self.rerun_failed_tests() self.finalize() diff --git a/Lib/test/libregrtest/win_utils.py b/Lib/test/libregrtest/win_utils.py index a1cc2201147db..5736cdfd3c729 100644 --- a/Lib/test/libregrtest/win_utils.py +++ b/Lib/test/libregrtest/win_utils.py @@ -1,16 +1,11 @@ +import _overlapped +import _thread import _winapi import math -import msvcrt -import os -import subprocess -import uuid +import struct import winreg -from test.support import os_helper -from test.libregrtest.utils import print_warning -# Max size of asynchronous reads -BUFSIZE = 8192 # Seconds per measurement SAMPLING_INTERVAL = 1 # Exponential damping factor to compute exponentially weighted moving average @@ -19,174 +14,111 @@ # Initialize the load using the arithmetic mean of the first NVALUE values # of the Processor Queue Length NVALUE = 5 -# Windows registry subkey of HKEY_LOCAL_MACHINE where the counter names -# of typeperf are registered -COUNTER_REGISTRY_KEY = (r"SOFTWARE\Microsoft\Windows NT\CurrentVersion" - r"\Perflib\CurrentLanguage") class WindowsLoadTracker(): """ - This class asynchronously interacts with the `typeperf` command to read - the system load on Windows. Multiprocessing and threads can't be used - here because they interfere with the test suite's cases for those - modules. + This class asynchronously reads the performance counters to calculate + the system load on Windows. A "raw" thread is used here to prevent + interference with the test suite's cases for the threading module. """ def __init__(self): + # Pre-flight test for access to the performance data; + # `PermissionError` will be raised if not allowed + winreg.QueryInfoKey(winreg.HKEY_PERFORMANCE_DATA) + self._values = [] self._load = None - self._buffer = '' - self._popen = None - self.start() - - def start(self): - # Create a named pipe which allows for asynchronous IO in Windows - pipe_name = r'\\.\pipe\typeperf_output_' + str(uuid.uuid4()) - - open_mode = _winapi.PIPE_ACCESS_INBOUND - open_mode |= _winapi.FILE_FLAG_FIRST_PIPE_INSTANCE - open_mode |= _winapi.FILE_FLAG_OVERLAPPED - - # This is the read end of the pipe, where we will be grabbing output - self.pipe = _winapi.CreateNamedPipe( - pipe_name, open_mode, _winapi.PIPE_WAIT, - 1, BUFSIZE, BUFSIZE, _winapi.NMPWAIT_WAIT_FOREVER, _winapi.NULL - ) - # The write end of the pipe which is passed to the created process - pipe_write_end = _winapi.CreateFile( - pipe_name, _winapi.GENERIC_WRITE, 0, _winapi.NULL, - _winapi.OPEN_EXISTING, 0, _winapi.NULL - ) - # Open up the handle as a python file object so we can pass it to - # subprocess - command_stdout = msvcrt.open_osfhandle(pipe_write_end, 0) - - # Connect to the read end of the pipe in overlap/async mode - overlap = _winapi.ConnectNamedPipe(self.pipe, overlapped=True) - overlap.GetOverlappedResult(True) - - # Spawn off the load monitor - counter_name = self._get_counter_name() - command = ['typeperf', counter_name, '-si', str(SAMPLING_INTERVAL)] - self._popen = subprocess.Popen(' '.join(command), - stdout=command_stdout, - cwd=os_helper.SAVEDCWD) - - # Close our copy of the write end of the pipe - os.close(command_stdout) - - def _get_counter_name(self): - # accessing the registry to get the counter localization name - with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, COUNTER_REGISTRY_KEY) as perfkey: - counters = winreg.QueryValueEx(perfkey, 'Counter')[0] - - # Convert [key1, value1, key2, value2, ...] list - # to {key1: value1, key2: value2, ...} dict - counters = iter(counters) - counters_dict = dict(zip(counters, counters)) - - # System counter has key '2' and Processor Queue Length has key '44' - system = counters_dict['2'] - process_queue_length = counters_dict['44'] - return f'"\\{system}\\{process_queue_length}"' - - def close(self, kill=True): - if self._popen is None: + self._running = _overlapped.CreateEvent(None, True, False, None) + self._stopped = _overlapped.CreateEvent(None, True, False, None) + + _thread.start_new_thread(self._update_load, (), {}) + + def _update_load(self, + # localize module access to prevent shutdown errors + _wait=_winapi.WaitForSingleObject, + _signal=_overlapped.SetEvent): + # run until signaled to stop + while _wait(self._running, 1000): + self._calculate_load() + # notify stopped + _signal(self._stopped) + + def _calculate_load(self, + # localize module access to prevent shutdown errors + _query=winreg.QueryValueEx, + _hkey=winreg.HKEY_PERFORMANCE_DATA, + _unpack=struct.unpack_from): + # get the 'System' object + data, _ = _query(_hkey, '2') + # PERF_DATA_BLOCK { + # WCHAR Signature[4] 8 + + # DWOWD LittleEndian 4 + + # DWORD Version 4 + + # DWORD Revision 4 + + # DWORD TotalByteLength 4 + + # DWORD HeaderLength = 24 byte offset + # ... + # } + obj_start, = _unpack('L', data, 24) + # PERF_OBJECT_TYPE { + # DWORD TotalByteLength + # DWORD DefinitionLength + # DWORD HeaderLength + # ... + # } + data_start, defn_start = _unpack('4xLL', data, obj_start) + data_base = obj_start + data_start + defn_base = obj_start + defn_start + # find the 'Processor Queue Length' counter (index=44) + while defn_base < data_base: + # PERF_COUNTER_DEFINITION { + # DWORD ByteLength + # DWORD CounterNameTitleIndex + # ... [7 DWORDs/28 bytes] + # DWORD CounterOffset + # } + size, idx, offset = _unpack('LL28xL', data, defn_base) + defn_base += size + if idx == 44: + counter_offset = data_base + offset + # the counter is known to be PERF_COUNTER_RAWCOUNT (DWORD) + processor_queue_length, = _unpack('L', data, counter_offset) + break + else: return - self._load = None - - if kill: - self._popen.kill() - self._popen.wait() - self._popen = None - - def __del__(self): - self.close() - - def _parse_line(self, line): - # typeperf outputs in a CSV format like this: - # "07/19/2018 01:32:26.605","3.000000" - # (date, process queue length) - tokens = line.split(',') - if len(tokens) != 2: - raise ValueError - - value = tokens[1] - if not value.startswith('"') or not value.endswith('"'): - raise ValueError - value = value[1:-1] - return float(value) - - def _read_lines(self): - overlapped, _ = _winapi.ReadFile(self.pipe, BUFSIZE, True) - bytes_read, res = overlapped.GetOverlappedResult(False) - if res != 0: - return () - - output = overlapped.getbuffer() - output = output.decode('oem', 'replace') - output = self._buffer + output - lines = output.splitlines(True) - - # bpo-36670: typeperf only writes a newline *before* writing a value, - # not after. Sometimes, the written line in incomplete (ex: only - # timestamp, without the process queue length). Only pass the last line - # to the parser if it's a valid value, otherwise store it in - # self._buffer. - try: - self._parse_line(lines[-1]) - except ValueError: - self._buffer = lines.pop(-1) + # We use an exponentially weighted moving average, imitating the + # load calculation on Unix systems. + # https://en.wikipedia.org/wiki/Load_(computing)#Unix-style_load_calculation + # https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average + if self._load is not None: + self._load = (self._load * LOAD_FACTOR_1 + + processor_queue_length * (1.0 - LOAD_FACTOR_1)) + elif len(self._values) < NVALUE: + self._values.append(processor_queue_length) else: - self._buffer = '' + self._load = sum(self._values) / len(self._values) - return lines + def close(self, kill=True): + self.__del__() + return + + def __del__(self, + # localize module access to prevent shutdown errors + _wait=_winapi.WaitForSingleObject, + _close=_winapi.CloseHandle, + _signal=_overlapped.SetEvent): + if self._running is not None: + # tell the update thread to quit + _signal(self._running) + # wait for the update thread to signal done + _wait(self._stopped, -1) + # cleanup events + _close(self._running) + _close(self._stopped) + self._running = self._stopped = None def getloadavg(self): - if self._popen is None: - return None - - returncode = self._popen.poll() - if returncode is not None: - self.close(kill=False) - return None - - try: - lines = self._read_lines() - except BrokenPipeError: - self.close() - return None - - for line in lines: - line = line.rstrip() - - # Ignore the initial header: - # "(PDH-CSV 4.0)","\\\\WIN\\System\\Processor Queue Length" - if 'PDH-CSV' in line: - continue - - # Ignore blank lines - if not line: - continue - - try: - processor_queue_length = self._parse_line(line) - except ValueError: - print_warning("Failed to parse typeperf output: %a" % line) - continue - - # We use an exponentially weighted moving average, imitating the - # load calculation on Unix systems. - # https://en.wikipedia.org/wiki/Load_(computing)#Unix-style_load_calculation - # https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average - if self._load is not None: - self._load = (self._load * LOAD_FACTOR_1 - + processor_queue_length * (1.0 - LOAD_FACTOR_1)) - elif len(self._values) < NVALUE: - self._values.append(processor_queue_length) - else: - self._load = sum(self._values) / len(self._values) - return self._load From webhook-mailer at python.org Mon Mar 21 20:30:35 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 22 Mar 2022 00:30:35 -0000 Subject: [Python-checkins] [3.10] bpo-47061: document module deprecations due to PEP 594 (GH-31984) (GH-32039) Message-ID: https://github.com/python/cpython/commit/c3538355f49f9394140428a848f2acf08175ff1a commit: c3538355f49f9394140428a848f2acf08175ff1a branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-21T17:30:21-07:00 summary: [3.10] bpo-47061: document module deprecations due to PEP 594 (GH-31984) (GH-32039) Also removed asynchat, asyncore, and smtpd from their respective toctree entries so they are only in the superceded subtree. (cherry picked from commit 9ac2de922a0f783bd43b8e026e4fb70fd1888572) Co-authored-by: Brett Cannon Automerge-Triggered-By: GH:brettcannon files: A Misc/NEWS.d/next/Library/2022-03-18-13-30-40.bpo-47061.etLHK5.rst M Doc/library/aifc.rst M Doc/library/audioop.rst M Doc/library/cgi.rst M Doc/library/cgitb.rst M Doc/library/chunk.rst M Doc/library/crypt.rst M Doc/library/fileformats.rst M Doc/library/imghdr.rst M Doc/library/internet.rst M Doc/library/ipc.rst M Doc/library/mm.rst M Doc/library/msilib.rst M Doc/library/netdata.rst M Doc/library/nis.rst M Doc/library/nntplib.rst M Doc/library/ossaudiodev.rst M Doc/library/pipes.rst M Doc/library/sndhdr.rst M Doc/library/spwd.rst M Doc/library/sunau.rst M Doc/library/superseded.rst M Doc/library/telnetlib.rst M Doc/library/unix.rst M Doc/library/uu.rst M Doc/library/windows.rst M Doc/library/xdrlib.rst diff --git a/Doc/library/aifc.rst b/Doc/library/aifc.rst index 2e917cf7321b8..edb4bf86e5a0a 100644 --- a/Doc/library/aifc.rst +++ b/Doc/library/aifc.rst @@ -3,6 +3,7 @@ .. module:: aifc :synopsis: Read and write audio files in AIFF or AIFC format. + :deprecated: **Source code:** :source:`Lib/aifc.py` @@ -11,6 +12,10 @@ single: AIFF single: AIFF-C + +.. deprecated:: 3.11 + The :mod:`aifc` module is deprecated (see :pep:`594` for details). + -------------- This module provides support for reading and writing AIFF and AIFF-C files. diff --git a/Doc/library/audioop.rst b/Doc/library/audioop.rst index bad9da2ec62e5..eae206084f090 100644 --- a/Doc/library/audioop.rst +++ b/Doc/library/audioop.rst @@ -3,6 +3,10 @@ .. module:: audioop :synopsis: Manipulate raw audio data. + :deprecated: + +.. deprecated:: 3.11 + The :mod:`audioop` module is deprecated (see :pep:`594` for details). -------------- diff --git a/Doc/library/cgi.rst b/Doc/library/cgi.rst index c151f04dfb8d0..306aa8d19ad72 100644 --- a/Doc/library/cgi.rst +++ b/Doc/library/cgi.rst @@ -3,6 +3,7 @@ .. module:: cgi :synopsis: Helpers for running Python scripts via the Common Gateway Interface. + :deprecated: **Source code:** :source:`Lib/cgi.py` @@ -14,6 +15,9 @@ single: URL single: Common Gateway Interface +.. deprecated:: 3.11 + The :mod:`cgi` module is deprecated (see :pep:`594` for details). + -------------- Support module for Common Gateway Interface (CGI) scripts. diff --git a/Doc/library/cgitb.rst b/Doc/library/cgitb.rst index 5f3a6476dd8cd..349414610bd40 100644 --- a/Doc/library/cgitb.rst +++ b/Doc/library/cgitb.rst @@ -3,6 +3,7 @@ .. module:: cgitb :synopsis: Configurable traceback handler for CGI scripts. + :deprecated: .. moduleauthor:: Ka-Ping Yee .. sectionauthor:: Fred L. Drake, Jr. @@ -15,6 +16,9 @@ single: exceptions; in CGI scripts single: tracebacks; in CGI scripts +.. deprecated:: 3.11 + The :mod:`cgitb` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`cgitb` module provides a special exception handler for Python scripts. diff --git a/Doc/library/chunk.rst b/Doc/library/chunk.rst index 5e24df923ed21..7999420f536d7 100644 --- a/Doc/library/chunk.rst +++ b/Doc/library/chunk.rst @@ -3,6 +3,7 @@ .. module:: chunk :synopsis: Module to read IFF chunks. + :deprecated: .. moduleauthor:: Sjoerd Mullender .. sectionauthor:: Sjoerd Mullender @@ -16,6 +17,9 @@ single: Real Media File Format single: RMFF +.. deprecated:: 3.11 + The :mod:`chunk` module is deprecated (see :pep:`594` for details). + -------------- This module provides an interface for reading files that use EA IFF 85 chunks. diff --git a/Doc/library/crypt.rst b/Doc/library/crypt.rst index d25c626a17585..73df87ca0db8d 100644 --- a/Doc/library/crypt.rst +++ b/Doc/library/crypt.rst @@ -4,6 +4,7 @@ .. module:: crypt :platform: Unix :synopsis: The crypt() function used to check Unix passwords. + :deprecated: .. moduleauthor:: Steven D. Majewski .. sectionauthor:: Steven D. Majewski @@ -15,6 +16,9 @@ single: crypt(3) pair: cipher; DES +.. deprecated:: 3.11 + The :mod:`crypt` module is deprecated (see :pep:`594` for details). + -------------- This module implements an interface to the :manpage:`crypt(3)` routine, which is diff --git a/Doc/library/fileformats.rst b/Doc/library/fileformats.rst index e9c2e1fbbdf3e..7b33b3364572d 100644 --- a/Doc/library/fileformats.rst +++ b/Doc/library/fileformats.rst @@ -13,5 +13,4 @@ that aren't markup languages and are not related to e-mail. csv.rst configparser.rst netrc.rst - xdrlib.rst plistlib.rst diff --git a/Doc/library/imghdr.rst b/Doc/library/imghdr.rst index 3d7f6de7a1bec..084fef73daf28 100644 --- a/Doc/library/imghdr.rst +++ b/Doc/library/imghdr.rst @@ -3,9 +3,13 @@ .. module:: imghdr :synopsis: Determine the type of image contained in a file or byte stream. + :deprecated: **Source code:** :source:`Lib/imghdr.py` +.. deprecated:: 3.11 + The :mod:`imghdr` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`imghdr` module determines the type of image contained in a file or diff --git a/Doc/library/internet.rst b/Doc/library/internet.rst index e745dd1243512..ff58dcf4d89c3 100644 --- a/Doc/library/internet.rst +++ b/Doc/library/internet.rst @@ -20,8 +20,6 @@ is currently supported on most popular platforms. Here is an overview: .. toctree:: webbrowser.rst - cgi.rst - cgitb.rst wsgiref.rst urllib.rst urllib.request.rst @@ -33,10 +31,7 @@ is currently supported on most popular platforms. Here is an overview: ftplib.rst poplib.rst imaplib.rst - nntplib.rst smtplib.rst - smtpd.rst - telnetlib.rst uuid.rst socketserver.rst http.server.rst diff --git a/Doc/library/ipc.rst b/Doc/library/ipc.rst index b88a174eb97f1..4849c82f317d9 100644 --- a/Doc/library/ipc.rst +++ b/Doc/library/ipc.rst @@ -22,7 +22,5 @@ The list of modules described in this chapter is: ssl.rst select.rst selectors.rst - asyncore.rst - asynchat.rst signal.rst mmap.rst diff --git a/Doc/library/mm.rst b/Doc/library/mm.rst index c8f79c4de1cdf..cd06e9385a261 100644 --- a/Doc/library/mm.rst +++ b/Doc/library/mm.rst @@ -11,12 +11,5 @@ discretion of the installation. Here's an overview: .. toctree:: - audioop.rst - aifc.rst - sunau.rst wave.rst - chunk.rst colorsys.rst - imghdr.rst - sndhdr.rst - ossaudiodev.rst diff --git a/Doc/library/msilib.rst b/Doc/library/msilib.rst index 83b3d4973bf0d..5ce18a1f75fc2 100644 --- a/Doc/library/msilib.rst +++ b/Doc/library/msilib.rst @@ -4,6 +4,7 @@ .. module:: msilib :platform: Windows :synopsis: Creation of Microsoft Installer files, and CAB files. + :deprecated: .. moduleauthor:: Martin v. L?wis .. sectionauthor:: Martin v. L?wis @@ -12,6 +13,9 @@ .. index:: single: msi +.. deprecated:: 3.11 + The :mod:`msilib` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`msilib` supports the creation of Microsoft Installer (``.msi``) files. diff --git a/Doc/library/netdata.rst b/Doc/library/netdata.rst index e76280f2fe3f4..0e6ebd3b02ddd 100644 --- a/Doc/library/netdata.rst +++ b/Doc/library/netdata.rst @@ -20,4 +20,3 @@ on the internet. binhex.rst binascii.rst quopri.rst - uu.rst diff --git a/Doc/library/nis.rst b/Doc/library/nis.rst index 10c67cbb81b2f..f6b6ea83946b0 100644 --- a/Doc/library/nis.rst +++ b/Doc/library/nis.rst @@ -5,10 +5,14 @@ .. module:: nis :platform: Unix :synopsis: Interface to Sun's NIS (Yellow Pages) library. + :deprecated: .. moduleauthor:: Fred Gansevles .. sectionauthor:: Moshe Zadka +.. deprecated:: 3.11 + The :mod:`nis` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`nis` module gives a thin wrapper around the NIS library, useful for diff --git a/Doc/library/nntplib.rst b/Doc/library/nntplib.rst index e7ec9047e015e..2a996e451bf7c 100644 --- a/Doc/library/nntplib.rst +++ b/Doc/library/nntplib.rst @@ -3,6 +3,7 @@ .. module:: nntplib :synopsis: NNTP protocol client (requires sockets). + :deprecated: **Source code:** :source:`Lib/nntplib.py` @@ -10,6 +11,9 @@ pair: NNTP; protocol single: Network News Transfer Protocol +.. deprecated:: 3.11 + The :mod:`nntplib` module is deprecated (see :pep:`594` for details). + -------------- This module defines the class :class:`NNTP` which implements the client side of diff --git a/Doc/library/ossaudiodev.rst b/Doc/library/ossaudiodev.rst index a7d3dac363cdf..e0f0a6b8259e4 100644 --- a/Doc/library/ossaudiodev.rst +++ b/Doc/library/ossaudiodev.rst @@ -4,6 +4,10 @@ .. module:: ossaudiodev :platform: Linux, FreeBSD :synopsis: Access to OSS-compatible audio devices. + :deprecated: + +.. deprecated:: 3.11 + The :mod:`ossaudiodev` module is deprecated (see :pep:`594` for details). -------------- diff --git a/Doc/library/pipes.rst b/Doc/library/pipes.rst index 57e27a6acf4b6..4de8c51bcae04 100644 --- a/Doc/library/pipes.rst +++ b/Doc/library/pipes.rst @@ -4,11 +4,15 @@ .. module:: pipes :platform: Unix :synopsis: A Python interface to Unix shell pipelines. + :deprecated: .. sectionauthor:: Moshe Zadka **Source code:** :source:`Lib/pipes.py` +.. deprecated:: 3.11 + The :mod:`pipes` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`pipes` module defines a class to abstract the concept of a *pipeline* diff --git a/Doc/library/sndhdr.rst b/Doc/library/sndhdr.rst index 6bfa9a9fd210b..41bce18b9cd84 100644 --- a/Doc/library/sndhdr.rst +++ b/Doc/library/sndhdr.rst @@ -3,6 +3,7 @@ .. module:: sndhdr :synopsis: Determine type of a sound file. + :deprecated: .. sectionauthor:: Fred L. Drake, Jr. .. Based on comments in the module source file. @@ -13,6 +14,9 @@ single: A-LAW single: u-LAW +.. deprecated:: 3.11 + The :mod:`sndhdr` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`sndhdr` provides utility functions which attempt to determine the type diff --git a/Doc/library/spwd.rst b/Doc/library/spwd.rst index c6cad2a3c3284..cb31a10a52e00 100644 --- a/Doc/library/spwd.rst +++ b/Doc/library/spwd.rst @@ -4,6 +4,10 @@ .. module:: spwd :platform: Unix :synopsis: The shadow password database (getspnam() and friends). + :deprecated: + +.. deprecated:: 3.11 + The :mod:`spwd` module is deprecated (see :pep:`594` for details). -------------- diff --git a/Doc/library/sunau.rst b/Doc/library/sunau.rst index aad6f93b6bff1..cfb1257f58548 100644 --- a/Doc/library/sunau.rst +++ b/Doc/library/sunau.rst @@ -3,11 +3,15 @@ .. module:: sunau :synopsis: Provide an interface to the Sun AU sound format. + :deprecated: .. sectionauthor:: Moshe Zadka **Source code:** :source:`Lib/sunau.py` +.. deprecated:: 3.11 + The :mod:`sunau` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`sunau` module provides a convenient interface to the Sun AU sound diff --git a/Doc/library/superseded.rst b/Doc/library/superseded.rst index fd23e4d1536d3..e3f9b0d37fe10 100644 --- a/Doc/library/superseded.rst +++ b/Doc/library/superseded.rst @@ -10,8 +10,26 @@ backwards compatibility. They have been superseded by other modules. .. toctree:: + aifc.rst asynchat.rst asyncore.rst - smtpd.rst + audioop.rst + cgi.rst + cgitb.rst + chunk.rst + crypt.rst + imghdr.rst imp.rst + msilib.rst + nntplib.rst + nis.rst optparse.rst + ossaudiodev.rst + pipes.rst + smtpd.rst + sndhdr.rst + spwd.rst + sunau.rst + telnetlib.rst + uu.rst + xdrlib.rst diff --git a/Doc/library/telnetlib.rst b/Doc/library/telnetlib.rst index 48a9aea50dddd..97b0a713e4422 100644 --- a/Doc/library/telnetlib.rst +++ b/Doc/library/telnetlib.rst @@ -3,6 +3,7 @@ .. module:: telnetlib :synopsis: Telnet client class. + :deprecated: .. sectionauthor:: Skip Montanaro @@ -10,6 +11,9 @@ .. index:: single: protocol; Telnet +.. deprecated:: 3.11 + The :mod:`telnetlib` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`telnetlib` module provides a :class:`Telnet` class that implements the diff --git a/Doc/library/unix.rst b/Doc/library/unix.rst index 04d4081f4a073..4553a104d15a2 100644 --- a/Doc/library/unix.rst +++ b/Doc/library/unix.rst @@ -13,14 +13,10 @@ of it. Here's an overview: posix.rst pwd.rst - spwd.rst grp.rst - crypt.rst termios.rst tty.rst pty.rst fcntl.rst - pipes.rst resource.rst - nis.rst syslog.rst diff --git a/Doc/library/uu.rst b/Doc/library/uu.rst index 0bc8021e1bdfc..c341bc83dcfed 100644 --- a/Doc/library/uu.rst +++ b/Doc/library/uu.rst @@ -3,11 +3,15 @@ .. module:: uu :synopsis: Encode and decode files in uuencode format. + :deprecated: .. moduleauthor:: Lance Ellinghouse **Source code:** :source:`Lib/uu.py` +.. deprecated:: 3.11 + The :mod:`uu` module is deprecated (see :pep:`594` for details). + -------------- This module encodes and decodes files in uuencode format, allowing arbitrary diff --git a/Doc/library/windows.rst b/Doc/library/windows.rst index b60d4e4ccf51d..4d72ead12aadc 100644 --- a/Doc/library/windows.rst +++ b/Doc/library/windows.rst @@ -9,7 +9,6 @@ This chapter describes modules that are only available on MS Windows platforms. .. toctree:: - msilib.rst msvcrt.rst winreg.rst winsound.rst diff --git a/Doc/library/xdrlib.rst b/Doc/library/xdrlib.rst index 42a03a46754d0..060b2e2c60df6 100644 --- a/Doc/library/xdrlib.rst +++ b/Doc/library/xdrlib.rst @@ -3,6 +3,7 @@ .. module:: xdrlib :synopsis: Encoders and decoders for the External Data Representation (XDR). + :deprecated: **Source code:** :source:`Lib/xdrlib.py` @@ -10,6 +11,9 @@ single: XDR single: External Data Representation +.. deprecated:: 3.11 + The :mod:`xdrlib` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`xdrlib` module supports the External Data Representation Standard as diff --git a/Misc/NEWS.d/next/Library/2022-03-18-13-30-40.bpo-47061.etLHK5.rst b/Misc/NEWS.d/next/Library/2022-03-18-13-30-40.bpo-47061.etLHK5.rst new file mode 100644 index 0000000000000..5445089e53c39 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-18-13-30-40.bpo-47061.etLHK5.rst @@ -0,0 +1,5 @@ +Deprecate the various modules listed by :pep:`594`: + +aifc, asynchat, asyncore, audioop, cgi, cgitb, chunk, crypt, +imghdr, msilib, nntplib, nis, ossaudiodev, pipes, smtpd, +sndhdr, spwd, sunau, telnetlib, uu, xdrlib From webhook-mailer at python.org Mon Mar 21 21:09:03 2022 From: webhook-mailer at python.org (zooba) Date: Tue, 22 Mar 2022 01:09:03 -0000 Subject: [Python-checkins] bpo-47086: Remove .chm from Windows installer and add HTML docs (GH-32038) Message-ID: https://github.com/python/cpython/commit/3751b6b030b4a3b88959b4f3c4ef2e58d325e497 commit: 3751b6b030b4a3b88959b4f3c4ef2e58d325e497 branch: main author: Steve Dower committer: zooba date: 2022-03-22T01:08:37Z summary: bpo-47086: Remove .chm from Windows installer and add HTML docs (GH-32038) files: A Misc/NEWS.d/next/Windows/2022-03-21-20-45-01.bpo-47086.bIuKlF.rst D Tools/msi/doc/doc_files.wxs D Tools/msi/doc/doc_no_files.wxs M .azure-pipelines/windows-release.yml M .azure-pipelines/windows-release/gpg-sign.yml M .azure-pipelines/windows-release/msi-steps.yml M .azure-pipelines/windows-release/stage-build.yml M .azure-pipelines/windows-release/stage-publish-pythonorg.yml M PC/layout/support/filesets.py M PC/layout/support/options.py M Tools/msi/README.txt M Tools/msi/build.bat M Tools/msi/buildrelease.bat M Tools/msi/bundle/Default.wxl M Tools/msi/common.wxs M Tools/msi/doc/doc.wixproj M Tools/msi/doc/doc.wxs M Tools/msi/msi.props M Tools/msi/uploadrelease.ps1 diff --git a/.azure-pipelines/windows-release.yml b/.azure-pipelines/windows-release.yml index 096ecadc79eb7..581f48ba22882 100644 --- a/.azure-pipelines/windows-release.yml +++ b/.azure-pipelines/windows-release.yml @@ -43,13 +43,17 @@ parameters: # Eventually when we stop releasing anything that old, we can drop this # argument (and make it implicitly always 'true') - name: ARM64TclTk - displayName: "Use Tcl/Tk for ARM64" + displayName: "Use Tcl/Tk for ARM64 (3.11 and later)" type: boolean default: true - name: DoPGO displayName: "Run PGO" type: boolean default: true +- name: DoCHM + displayName: "Produce compiled help document (pre-3.11)" + type: boolean + default: false - name: DoLayout displayName: "Produce full layout artifact" type: boolean @@ -86,6 +90,7 @@ variables: ${{ if ne(parameters.SigningCertificate, 'Unsigned') }}: SigningCertificate: ${{ parameters.SigningCertificate }} SigningDescription: ${{ parameters.SigningDescription }} + DoCHM: ${{ parameters.DoCHM }} DoLayout: ${{ parameters.DoLayout }} DoMSIX: ${{ parameters.DoMSIX }} DoNuget: ${{ parameters.DoNuget }} diff --git a/.azure-pipelines/windows-release/gpg-sign.yml b/.azure-pipelines/windows-release/gpg-sign.yml index 0855af8d703df..04206d23e4996 100644 --- a/.azure-pipelines/windows-release/gpg-sign.yml +++ b/.azure-pipelines/windows-release/gpg-sign.yml @@ -3,12 +3,14 @@ parameters: GPGPassphrase: $(GPGPassphrase) Files: '*' WorkingDirectory: $(Build.BinariesDirectory) + Condition: succeeded() steps: - task: DownloadSecureFile at 1 name: gpgkey inputs: secureFile: ${{ parameters.GPGKeyFile }} + condition: ${{ parameters.Condition }} displayName: 'Download GPG key' - powershell: | @@ -18,6 +20,7 @@ steps: gpg/gpg2.exe -ba --batch --passphrase ${{ parameters.GPGPassphrase }} $_ "Made signature for $_" } + condition: ${{ parameters.Condition }} displayName: 'Generate GPG signatures' workingDirectory: ${{ parameters.WorkingDirectory }} diff --git a/.azure-pipelines/windows-release/msi-steps.yml b/.azure-pipelines/windows-release/msi-steps.yml index c3c2c43032c00..79fc6f5ed292d 100644 --- a/.azure-pipelines/windows-release/msi-steps.yml +++ b/.azure-pipelines/windows-release/msi-steps.yml @@ -21,8 +21,6 @@ steps: inputs: sourceFolder: $(Build.BinariesDirectory)\doc targetFolder: $(Build.SourcesDirectory)\Doc\build - contents: | - htmlhelp\*.chm - task: DownloadPipelineArtifact at 1 displayName: 'Download artifact: bin_win32' diff --git a/.azure-pipelines/windows-release/stage-build.yml b/.azure-pipelines/windows-release/stage-build.yml index 2745d79dd069c..26f4317750436 100644 --- a/.azure-pipelines/windows-release/stage-build.yml +++ b/.azure-pipelines/windows-release/stage-build.yml @@ -5,7 +5,6 @@ jobs: - job: Build_Docs displayName: Docs build pool: - #name: 'Windows Release' vmImage: windows-2022 workspace: @@ -21,14 +20,10 @@ jobs: - script: Doc\make.bat htmlhelp displayName: 'Build CHM docs' + condition: and(succeeded(), eq(variables['DoCHM'], 'true')) env: BUILDDIR: $(Build.BinariesDirectory)\Doc - #- powershell: | - # mkdir -Force "$(Build.BinariesDirectory)\Doc\htmlhelp" - # iwr "https://www.python.org/ftp/python/3.8.0/python380.chm" -OutFile "$(Build.BinariesDirectory)\Doc\htmlhelp\python390a0.chm" - # displayName: 'Cheat at building CHM docs' - - task: CopyFiles at 2 displayName: 'Assemble artifact: Doc' inputs: @@ -44,6 +39,7 @@ jobs: targetPath: $(Build.ArtifactStagingDirectory)\Doc artifactName: doc + - job: Build_Python displayName: Python build diff --git a/.azure-pipelines/windows-release/stage-publish-pythonorg.yml b/.azure-pipelines/windows-release/stage-publish-pythonorg.yml index 953f728ade381..ee50e4e8aa0db 100644 --- a/.azure-pipelines/windows-release/stage-publish-pythonorg.yml +++ b/.azure-pipelines/windows-release/stage-publish-pythonorg.yml @@ -87,7 +87,13 @@ jobs: - template: ./gpg-sign.yml parameters: GPGKeyFile: 'python-signing.key' - Files: 'doc\htmlhelp\*.chm, msi\*\*, embed\*.zip' + Files: 'msi\*\*, embed\*.zip' + + - template: ./gpg-sign.yml + parameters: + GPGKeyFile: 'python-signing.key' + Files: 'doc\htmlhelp\*.chm' + Condition: and(succeeded(), eq(variables['DoCHM'], 'true')) - powershell: > $(Build.SourcesDirectory)\Tools\msi\uploadrelease.ps1 diff --git a/Misc/NEWS.d/next/Windows/2022-03-21-20-45-01.bpo-47086.bIuKlF.rst b/Misc/NEWS.d/next/Windows/2022-03-21-20-45-01.bpo-47086.bIuKlF.rst new file mode 100644 index 0000000000000..b73e1870c6de2 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-03-21-20-45-01.bpo-47086.bIuKlF.rst @@ -0,0 +1,2 @@ +The installer for Windows now includes documentation as loose HTML files +rather than a single compiled :file:`.chm` file. diff --git a/PC/layout/support/filesets.py b/PC/layout/support/filesets.py index 47f727c057844..3f63f686a9fab 100644 --- a/PC/layout/support/filesets.py +++ b/PC/layout/support/filesets.py @@ -93,6 +93,8 @@ def _return_true(f): def rglob(root, patterns, condition=None): + if not os.path.isdir(root): + return if isinstance(patterns, tuple): for p in patterns: yield from _rglob(root, p, condition or _return_true) diff --git a/PC/layout/support/options.py b/PC/layout/support/options.py index 9faf20c0fdc7a..e8310293159e4 100644 --- a/PC/layout/support/options.py +++ b/PC/layout/support/options.py @@ -80,7 +80,7 @@ def public(f): "venv", "dev", "symbols", - "chm", + "html-doc", ], }, "embed": { diff --git a/Tools/msi/README.txt b/Tools/msi/README.txt index 0a4382f3e0223..8c6ec516f18e9 100644 --- a/Tools/msi/README.txt +++ b/Tools/msi/README.txt @@ -4,17 +4,16 @@ Quick Build Info For testing, the installer should be built with the Tools/msi/build.bat script: - build.bat [-x86] [-x64] [--doc] + build.bat [-x86] [-x64] [-ARM64] [--doc] For an official release, the installer should be built with the Tools/msi/buildrelease.bat script and environment variables: - set PYTHON= + set PYTHON= set SPHINXBUILD= - set PATH=; - ;%PATH% + set PATH=;%PATH% - buildrelease.bat [-x86] [-x64] [-D] [-B] + buildrelease.bat [-x86] [-x64] [-ARM64] [-D] [-B] [-o ] [-c ] See the Building the Installer section for more information. @@ -77,20 +76,17 @@ and Features | Turn Windows Features on or off) and ensure that the entry For testing, the installer should be built with the Tools/msi/build.bat script: - build.bat [-x86] [-x64] [--doc] [--test-marker] [--pack] + build.bat [-x86] [-x64] [-ARM64] [--doc] [--test-marker] [--pack] This script will build the required configurations of Python and generate an installer layout in PCbuild/(win32|amd64)/en-us. -Specify -x86 and/or -x64 to build for each platform. If neither is -specified, both platforms will be built. Currently, both the debug and +Specify -x86, -x64 and/or -ARM64 to build for each platform. If none are +specified, both x64 and x86 will be built. Currently, both the debug and release versions of Python are required for the installer. -Specify --doc to build the documentation (.chm) file. If the file is not -available, it will simply be excluded from the installer. Ensure -%PYTHON% and %SPHINXBUILD% are set when passing this option. You may -also set %HTMLHELP% to the Html Help Compiler (hhc.exe), or put HHC on -your PATH or in externals/. +Specify --doc to include the documentation files. Ensure %PYTHON% and +%SPHINXBUILD% are set when passing this option. Specify --test-marker to build an installer that works side-by-side with an official Python release. All registry keys and install locations will @@ -106,18 +102,18 @@ Tools/msi/buildrelease.bat script: set PYTHON= set SPHINXBUILD= - set PATH=; - ;%PATH% + set PATH=;%PATH% - buildrelease.bat [-x86] [-x64] [-D] [-B] + buildrelease.bat [-x86] [-x64] [-ARM64] [-D] [-B] [-o ] [-c ] -Specify -x86 and/or -x64 to build for each platform. If neither is -specified, both platforms will be built. Currently, both the debug and +Specify -x86, -x64 and/or -ARM64 to build for each platform. If none are +specified, both x64 and x86 will be built. Currently, both the debug and release versions of Python are required for the installer. Specify -D to skip rebuilding the documentation. The documentation is required for a release and the build will fail if it is not available. +Ensure %PYTHON% and %SPHINXBUILD% are set if you omit this option. Specify -B to skip rebuilding Python. This is useful to only rebuild the installer layout after a previous call to buildrelease.bat. @@ -129,10 +125,6 @@ Specify -c to choose a code-signing certificate to be used for all the signable binaries in Python as well as each file making up the installer. Official releases of Python must be signed. -Ensure %PYTHON% and %SPHINXBUILD% are set when passing this option. You -may also set %HTMLHELP% to the Html Help Compiler (hhc.exe), or put HHC -on your PATH or in externals/. You will also need Git (git.exe) on -your PATH. If WiX is not found on your system, it will be automatically downloaded and extracted to the externals/ directory. @@ -366,7 +358,7 @@ Within this install directory is the following approximate layout: .\python3x.dll The core interpreter .\python3.dll The stable ABI reference .\DLLs Stdlib extensions (*.pyd) and dependencies -.\Doc Documentation (*.chm) +.\Doc Documentation (*.html) .\include Development headers (*.h) .\Lib Standard library .\Lib\test Test suite @@ -421,7 +413,7 @@ a semicolon. When the documentation is installed, a key "Help" is created within the root key, with a subkey "Main Python Documentation" with its default -value set to the full path to the installed CHM file. +value set to the full path to the main index.html file. The py.exe launcher is installed as part of a regular Python install, diff --git a/Tools/msi/build.bat b/Tools/msi/build.bat index ded1cfb5b2d6f..425558f99d591 100644 --- a/Tools/msi/build.bat +++ b/Tools/msi/build.bat @@ -48,7 +48,7 @@ if defined BUILDARM64 ( ) if defined BUILDDOC ( - call "%PCBUILD%..\Doc\make.bat" htmlhelp + call "%PCBUILD%..\Doc\make.bat" html if errorlevel 1 exit /B %ERRORLEVEL% ) @@ -87,8 +87,8 @@ echo build.bat [-x86] [-x64] [-arm64] [--doc] [-h] [--test-marker] [--pack] [-r] echo. echo -x86 Build x86 installers echo -x64 Build x64 installers -echo -ARM64 Build ARM64 installers -echo --doc Build CHM documentation +echo -ARM64 Build ARM64 installers +echo --doc Build documentation echo --test-marker Build with test markers echo --no-test-marker Build without test markers (default) echo --pack Embed core MSIs into installer diff --git a/Tools/msi/buildrelease.bat b/Tools/msi/buildrelease.bat index d057ca675363f..0373c9f7b836a 100644 --- a/Tools/msi/buildrelease.bat +++ b/Tools/msi/buildrelease.bat @@ -81,7 +81,7 @@ if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & if "%SKIPBUILD%" EQU "1" goto skipdoc if "%SKIPDOC%" EQU "1" goto skipdoc -call "%D%..\..\doc\make.bat" htmlhelp +call "%D%..\..\doc\make.bat" html if errorlevel 1 exit /B %ERRORLEVEL% :skipdoc diff --git a/Tools/msi/bundle/Default.wxl b/Tools/msi/bundle/Default.wxl index 70fb467ec8b19..2eddd1f749ec5 100644 --- a/Tools/msi/bundle/Default.wxl +++ b/Tools/msi/bundle/Default.wxl @@ -67,7 +67,7 @@ Select Customize to review current options. &Back B&rowse &Documentation - Installs the Python documentation file. + Installs the Python documentation files. &pip Installs pip, which can download and install other Python packages. tcl/tk and &IDLE diff --git a/Tools/msi/common.wxs b/Tools/msi/common.wxs index 4554e80014a29..b819d320ee948 100644 --- a/Tools/msi/common.wxs +++ b/Tools/msi/common.wxs @@ -85,7 +85,9 @@ - + + + diff --git a/Tools/msi/doc/doc.wixproj b/Tools/msi/doc/doc.wixproj index ea9929acd05ff..83687968faebe 100644 --- a/Tools/msi/doc/doc.wixproj +++ b/Tools/msi/doc/doc.wixproj @@ -10,21 +10,28 @@ - python$(MajorVersionNumber)$(MinorVersionNumber)$(MicroVersionNumber)$(ReleaseLevelName).chm - false - true - - - $(DefineConstants);DocFilename=$(DocFilename); + $(PySourcePath)Doc\build\html\ + $(DocHtmlPath)\ + + doc_html + - - - + + + $(DocHtmlPath) + !(bindpath.doc_html) + $(DocHtmlPath)..\ + Doc_ + doc_html + + + \ No newline at end of file diff --git a/Tools/msi/doc/doc.wxs b/Tools/msi/doc/doc.wxs index 1d7706bb4d50a..e80fff43418bb 100644 --- a/Tools/msi/doc/doc.wxs +++ b/Tools/msi/doc/doc.wxs @@ -8,35 +8,31 @@ - - - - 1 - - - + + + + + + + - + - - - - diff --git a/Tools/msi/doc/doc_files.wxs b/Tools/msi/doc/doc_files.wxs deleted file mode 100644 index fe09afe4d3c76..0000000000000 --- a/Tools/msi/doc/doc_files.wxs +++ /dev/null @@ -1,15 +0,0 @@ -? - - - - - - - - - - - - - - diff --git a/Tools/msi/doc/doc_no_files.wxs b/Tools/msi/doc/doc_no_files.wxs deleted file mode 100644 index 7ab7c2690689c..0000000000000 --- a/Tools/msi/doc/doc_no_files.wxs +++ /dev/null @@ -1,17 +0,0 @@ -? - - - - - - - - - - - diff --git a/Tools/msi/msi.props b/Tools/msi/msi.props index b5fd3d3a3da74..06aa0b8bbca27 100644 --- a/Tools/msi/msi.props +++ b/Tools/msi/msi.props @@ -115,9 +115,6 @@ - - - src diff --git a/Tools/msi/uploadrelease.ps1 b/Tools/msi/uploadrelease.ps1 index 7c825c443f228..a8669e5d65ed1 100644 --- a/Tools/msi/uploadrelease.ps1 +++ b/Tools/msi/uploadrelease.ps1 @@ -80,19 +80,19 @@ if (-not $skipupload) { "" if ($doc_htmlhelp) { - pushd $doc_htmlhelp + $chm = gci -EA 0 $doc_htmlhelp\python*.chm, $doc_htmlhelp\python*.chm.asc } else { - pushd $build + $chm = gci -EA 0 $build\python*.chm, $build\python*.chm.asc } - $chm = gci python*.chm, python*.chm.asc - popd $d = "$target/$($p[0])/" & $plink -batch $user@$server mkdir $d & $plink -batch $user@$server chgrp downloads $d & $plink -batch $user@$server chmod o+rx $d - & $pscp -batch $chm.FullName "$user@${server}:$d" - if (-not $?) { throw "Failed to upload $chm" } + if ($chm) { + & $pscp -batch $chm.FullName "$user@${server}:$d" + if (-not $?) { throw "Failed to upload $chm" } + } $dirs = gci "$build" -Directory if ($embed) { From webhook-mailer at python.org Tue Mar 22 05:37:25 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 22 Mar 2022 09:37:25 -0000 Subject: [Python-checkins] bpo-45150: Add hashlib.file_digest() for efficient file hashing (GH-31930) Message-ID: https://github.com/python/cpython/commit/4f97d64c831c94660ceb01f34d51fa236ad968b0 commit: 4f97d64c831c94660ceb01f34d51fa236ad968b0 branch: main author: Christian Heimes committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-22T02:37:00-07:00 summary: bpo-45150: Add hashlib.file_digest() for efficient file hashing (GH-31930) files: A Misc/NEWS.d/next/Library/2022-03-16-11-52-52.bpo-45150.kYbIME.rst M Doc/library/hashlib.rst M Lib/hashlib.py M Lib/test/test_hashlib.py diff --git a/Doc/library/hashlib.rst b/Doc/library/hashlib.rst index aa24131f8bf44..da97b0e9a74d1 100644 --- a/Doc/library/hashlib.rst +++ b/Doc/library/hashlib.rst @@ -228,6 +228,49 @@ by the SHAKE algorithm. exchange the value safely in email or other non-binary environments. +File hashing +------------ + +The hashlib module provides a helper function for efficient hashing of +a file or file-like object. + +.. function:: file_digest(fileobj, digest, /) + + Return a digest object that has been updated with contents of file object. + + *fileobj* must be a file-like object opened for reading in binary mode. + It accepts file objects from builtin :func:`open`, :class:`~io.BytesIO` + instances, SocketIO objects from :meth:`socket.socket.makefile`, and + similar. The function may bypass Python's I/O and use the file descriptor + from :meth:`~io.IOBase.fileno` directly. *fileobj* must be assumed to be + in an unknown state after this function returns or raises. It is up to + the caller to close *fileobj*. + + *digest* must either be a hash algorithm name as a *str*, a hash + constructor, or a callable that returns a hash object. + + Example: + + >>> import io, hashlib, hmac + >>> with open(hashlib.__file__, "rb") as f: + ... digest = hashlib.file_digest(f, "sha256") + ... + >>> digest.hexdigest() # doctest: +ELLIPSIS + '...' + + >>> buf = io.BytesIO(b"somedata") + >>> mac1 = hmac.HMAC(b"key", digestmod=hashlib.sha512) + >>> digest = hashlib.file_digest(buf, lambda: mac1) + + >>> digest is mac1 + True + >>> mac2 = hmac.HMAC(b"key", b"somedata", digestmod=hashlib.sha512) + >>> mac1.digest() == mac2.digest() + True + + .. versionadded:: 3.11 + + Key derivation -------------- diff --git a/Lib/hashlib.py b/Lib/hashlib.py index 562501860a72b..b546a3fd79531 100644 --- a/Lib/hashlib.py +++ b/Lib/hashlib.py @@ -65,7 +65,7 @@ algorithms_available = set(__always_supported) __all__ = __always_supported + ('new', 'algorithms_guaranteed', - 'algorithms_available', 'pbkdf2_hmac') + 'algorithms_available', 'pbkdf2_hmac', 'file_digest') __builtin_constructor_cache = {} @@ -254,6 +254,52 @@ def prf(msg, inner=inner, outer=outer): pass +def file_digest(fileobj, digest, /, *, _bufsize=2**18): + """Hash the contents of a file-like object. Returns a digest object. + + *fileobj* must be a file-like object opened for reading in binary mode. + It accepts file objects from open(), io.BytesIO(), and SocketIO objects. + The function may bypass Python's I/O and use the file descriptor *fileno* + directly. + + *digest* must either be a hash algorithm name as a *str*, a hash + constructor, or a callable that returns a hash object. + """ + # On Linux we could use AF_ALG sockets and sendfile() to archive zero-copy + # hashing with hardware acceleration. + if isinstance(digest, str): + digestobj = new(digest) + else: + digestobj = digest() + + if hasattr(fileobj, "getbuffer"): + # io.BytesIO object, use zero-copy buffer + digestobj.update(fileobj.getbuffer()) + return digestobj + + # Only binary files implement readinto(). + if not ( + hasattr(fileobj, "readinto") + and hasattr(fileobj, "readable") + and fileobj.readable() + ): + raise ValueError( + f"'{fileobj!r}' is not a file-like object in binary reading mode." + ) + + # binary file, socket.SocketIO object + # Note: socket I/O uses different syscalls than file I/O. + buf = bytearray(_bufsize) # Reusable buffer to reduce allocations. + view = memoryview(buf) + while True: + size = fileobj.readinto(buf) + if size == 0: + break # EOF + digestobj.update(view[:size]) + + return digestobj + + for __func_name in __always_supported: # try them all, some may not work due to the OpenSSL # version not supporting that algorithm. diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py index ea31f8be2cb82..daf6e3862a24f 100644 --- a/Lib/test/test_hashlib.py +++ b/Lib/test/test_hashlib.py @@ -10,6 +10,7 @@ from binascii import unhexlify import hashlib import importlib +import io import itertools import os import sys @@ -20,6 +21,7 @@ from test import support from test.support import _4G, bigmemtest from test.support.import_helper import import_fresh_module +from test.support import os_helper from test.support import threading_helper from test.support import warnings_helper from http.client import HTTPException @@ -371,6 +373,31 @@ def check(self, name, data, hexdigest, shake=False, **kwargs): if not shake: self.assertEqual(len(digest), m.digest_size) + if not shake and kwargs.get("key") is None: + # skip shake and blake2 extended parameter tests + self.check_file_digest(name, data, hexdigest) + + def check_file_digest(self, name, data, hexdigest): + hexdigest = hexdigest.lower() + digests = [name] + digests.extend(self.constructors_to_test[name]) + + with open(os_helper.TESTFN, "wb") as f: + f.write(data) + + try: + for digest in digests: + buf = io.BytesIO(data) + buf.seek(0) + self.assertEqual( + hashlib.file_digest(buf, digest).hexdigest(), hexdigest + ) + with open(os_helper.TESTFN, "rb") as f: + digestobj = hashlib.file_digest(f, digest) + self.assertEqual(digestobj.hexdigest(), hexdigest) + finally: + os.unlink(os_helper.TESTFN) + def check_no_unicode(self, algorithm_name): # Unicode objects are not allowed as input. constructors = self.constructors_to_test[algorithm_name] @@ -1117,6 +1144,33 @@ def test_normalized_name(self): self.assertNotIn("blake2b512", hashlib.algorithms_available) self.assertNotIn("sha3-512", hashlib.algorithms_available) + def test_file_digest(self): + data = b'a' * 65536 + d1 = hashlib.sha256() + self.addCleanup(os.unlink, os_helper.TESTFN) + with open(os_helper.TESTFN, "wb") as f: + for _ in range(10): + d1.update(data) + f.write(data) + + with open(os_helper.TESTFN, "rb") as f: + d2 = hashlib.file_digest(f, hashlib.sha256) + + self.assertEqual(d1.hexdigest(), d2.hexdigest()) + self.assertEqual(d1.name, d2.name) + self.assertIs(type(d1), type(d2)) + + with self.assertRaises(ValueError): + hashlib.file_digest(None, "sha256") + + with self.assertRaises(ValueError): + with open(os_helper.TESTFN, "r") as f: + hashlib.file_digest(f, "sha256") + + with self.assertRaises(ValueError): + with open(os_helper.TESTFN, "wb") as f: + hashlib.file_digest(f, "sha256") + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2022-03-16-11-52-52.bpo-45150.kYbIME.rst b/Misc/NEWS.d/next/Library/2022-03-16-11-52-52.bpo-45150.kYbIME.rst new file mode 100644 index 0000000000000..1c6ea5a8e43bc --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-16-11-52-52.bpo-45150.kYbIME.rst @@ -0,0 +1 @@ +Add :func:`hashlib.file_digest` helper for efficient hashing of file object. From webhook-mailer at python.org Tue Mar 22 05:45:05 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Tue, 22 Mar 2022 09:45:05 -0000 Subject: [Python-checkins] bpo-47081: Replace "qualifiers" with "quantifiers" in the re module documentation (GH-32028) Message-ID: https://github.com/python/cpython/commit/c6cd3cc93c40363ce704d34a70e6fb73ea1d97a3 commit: c6cd3cc93c40363ce704d34a70e6fb73ea1d97a3 branch: main author: Serhiy Storchaka committer: serhiy-storchaka date: 2022-03-22T11:44:47+02:00 summary: bpo-47081: Replace "qualifiers" with "quantifiers" in the re module documentation (GH-32028) It is a more commonly used term. files: M Doc/howto/regex.rst M Doc/library/re.rst M Doc/whatsnew/3.11.rst M Lib/test/test_re.py M Misc/NEWS.d/next/Library/2022-03-19-08-42-57.bpo-433030.UTwRX7.rst diff --git a/Doc/howto/regex.rst b/Doc/howto/regex.rst index d574c3736b1cb..33dca2fc41f9d 100644 --- a/Doc/howto/regex.rst +++ b/Doc/howto/regex.rst @@ -230,13 +230,13 @@ while ``+`` requires at least *one* occurrence. To use a similar example, ``ca+t`` will match ``'cat'`` (1 ``'a'``), ``'caaat'`` (3 ``'a'``\ s), but won't match ``'ct'``. -There are two more repeating qualifiers. The question mark character, ``?``, +There are two more repeating operators or quantifiers. The question mark character, ``?``, matches either once or zero times; you can think of it as marking something as being optional. For example, ``home-?brew`` matches either ``'homebrew'`` or ``'home-brew'``. -The most complicated repeated qualifier is ``{m,n}``, where *m* and *n* are -decimal integers. This qualifier means there must be at least *m* repetitions, +The most complicated quantifier is ``{m,n}``, where *m* and *n* are +decimal integers. This quantifier means there must be at least *m* repetitions, and at most *n*. For example, ``a/{1,3}b`` will match ``'a/b'``, ``'a//b'``, and ``'a///b'``. It won't match ``'ab'``, which has no slashes, or ``'a////b'``, which has four. @@ -245,7 +245,7 @@ You can omit either *m* or *n*; in that case, a reasonable value is assumed for the missing value. Omitting *m* is interpreted as a lower limit of 0, while omitting *n* results in an upper bound of infinity. -Readers of a reductionist bent may notice that the three other qualifiers can +Readers of a reductionist bent may notice that the three other quantifiers can all be expressed using this notation. ``{0,}`` is the same as ``*``, ``{1,}`` is equivalent to ``+``, and ``{0,1}`` is the same as ``?``. It's better to use ``*``, ``+``, or ``?`` when you can, simply because they're shorter and easier @@ -803,7 +803,7 @@ which matches the header's value. Groups are marked by the ``'('``, ``')'`` metacharacters. ``'('`` and ``')'`` have much the same meaning as they do in mathematical expressions; they group together the expressions contained inside them, and you can repeat the contents -of a group with a repeating qualifier, such as ``*``, ``+``, ``?``, or +of a group with a quantifier, such as ``*``, ``+``, ``?``, or ``{m,n}``. For example, ``(ab)*`` will match zero or more repetitions of ``ab``. :: @@ -1326,7 +1326,7 @@ backtrack character by character until it finds a match for the ``>``. The final match extends from the ``'<'`` in ``''`` to the ``'>'`` in ``''``, which isn't what you want. -In this case, the solution is to use the non-greedy qualifiers ``*?``, ``+?``, +In this case, the solution is to use the non-greedy quantifiers ``*?``, ``+?``, ``??``, or ``{m,n}?``, which match as *little* text as possible. In the above example, the ``'>'`` is tried immediately after the first ``'<'`` matches, and when it fails, the engine advances a character at a time, retrying the ``'>'`` diff --git a/Doc/library/re.rst b/Doc/library/re.rst index 02c0a849610b0..b72d72f8355f2 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -87,7 +87,7 @@ Some characters, like ``'|'`` or ``'('``, are special. Special characters either stand for classes of ordinary characters, or affect how the regular expressions around them are interpreted. -Repetition qualifiers (``*``, ``+``, ``?``, ``{m,n}``, etc) cannot be +Repetition operators or quantifiers (``*``, ``+``, ``?``, ``{m,n}``, etc) cannot be directly nested. This avoids ambiguity with the non-greedy modifier suffix ``?``, and with other modifiers in other implementations. To apply a second repetition to an inner repetition, parentheses may be used. For example, @@ -146,10 +146,10 @@ The special characters are: single: ??; in regular expressions ``*?``, ``+?``, ``??`` - The ``'*'``, ``'+'``, and ``'?'`` qualifiers are all :dfn:`greedy`; they match + The ``'*'``, ``'+'``, and ``'?'`` quantifiers are all :dfn:`greedy`; they match as much text as possible. Sometimes this behaviour isn't desired; if the RE ``<.*>`` is matched against ``' b '``, it will match the entire - string, and not just ``''``. Adding ``?`` after the qualifier makes it + string, and not just ``''``. Adding ``?`` after the quantifier makes it perform the match in :dfn:`non-greedy` or :dfn:`minimal` fashion; as *few* characters as possible will be matched. Using the RE ``<.*?>`` will match only ``''``. @@ -160,11 +160,11 @@ The special characters are: single: ?+; in regular expressions ``*+``, ``++``, ``?+`` - Like the ``'*'``, ``'+'``, and ``'?'`` qualifiers, those where ``'+'`` is + Like the ``'*'``, ``'+'``, and ``'?'`` quantifiers, those where ``'+'`` is appended also match as many times as possible. - However, unlike the true greedy qualifiers, these do not allow + However, unlike the true greedy quantifiers, these do not allow back-tracking when the expression following it fails to match. - These are known as :dfn:`possessive` qualifiers. + These are known as :dfn:`possessive` quantifiers. For example, ``a*a`` will match ``'aaaa'`` because the ``a*`` will match all 4 ``'a'``s, but, when the final ``'a'`` is encountered, the expression is backtracked so that in the end the ``a*`` ends up matching @@ -198,7 +198,7 @@ The special characters are: ``{m,n}?`` Causes the resulting RE to match from *m* to *n* repetitions of the preceding RE, attempting to match as *few* repetitions as possible. This is the - non-greedy version of the previous qualifier. For example, on the + non-greedy version of the previous quantifier. For example, on the 6-character string ``'aaaaaa'``, ``a{3,5}`` will match 5 ``'a'`` characters, while ``a{3,5}?`` will only match 3 characters. @@ -206,7 +206,7 @@ The special characters are: Causes the resulting RE to match from *m* to *n* repetitions of the preceding RE, attempting to match as many repetitions as possible *without* establishing any backtracking points. - This is the possessive version of the qualifier above. + This is the possessive version of the quantifier above. For example, on the 6-character string ``'aaaaaa'``, ``a{3,5}+aa`` attempt to match 5 ``'a'`` characters, then, requiring 2 more ``'a'``s, will need more characters than available and thus fail, while diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index ca7699daa9854..96db3a90cfce4 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -298,7 +298,7 @@ os re -- -* Atomic grouping (``(?>...)``) and possessive qualifiers (``*+``, ``++``, +* Atomic grouping (``(?>...)``) and possessive quantifiers (``*+``, ``++``, ``?+``, ``{m,n}+``) are now supported in regular expressions. (Contributed by Jeffrey C. Jacobs and Serhiy Storchaka in :issue:`433030`.) diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index bde7509f09729..da827ca7c4e92 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -2038,9 +2038,9 @@ def test_bug_40736(self): with self.assertRaisesRegex(TypeError, "got 'type'"): re.search("x*", type) - def test_possessive_qualifiers(self): - """Test Possessive Qualifiers - Test qualifiers of the form @+ for some repetition operator @, + def test_possessive_quantifiers(self): + """Test Possessive Quantifiers + Test quantifiers of the form @+ for some repetition operator @, e.g. x{3,5}+ meaning match from 3 to 5 greadily and proceed without creating a stack frame for rolling the stack back and trying 1 or more fewer matches.""" @@ -2077,7 +2077,7 @@ def test_possessive_qualifiers(self): self.assertIsNone(re.match("^x{}+$", "xxx")) self.assertTrue(re.match("^x{}+$", "x{}")) - def test_fullmatch_possessive_qualifiers(self): + def test_fullmatch_possessive_quantifiers(self): self.assertTrue(re.fullmatch(r'a++', 'a')) self.assertTrue(re.fullmatch(r'a*+', 'a')) self.assertTrue(re.fullmatch(r'a?+', 'a')) @@ -2096,7 +2096,7 @@ def test_fullmatch_possessive_qualifiers(self): self.assertIsNone(re.fullmatch(r'(?:ab)?+', 'abc')) self.assertIsNone(re.fullmatch(r'(?:ab){1,3}+', 'abc')) - def test_findall_possessive_qualifiers(self): + def test_findall_possessive_quantifiers(self): self.assertEqual(re.findall(r'a++', 'aab'), ['aa']) self.assertEqual(re.findall(r'a*+', 'aab'), ['aa', '', '']) self.assertEqual(re.findall(r'a?+', 'aab'), ['a', 'a', '', '']) diff --git a/Misc/NEWS.d/next/Library/2022-03-19-08-42-57.bpo-433030.UTwRX7.rst b/Misc/NEWS.d/next/Library/2022-03-19-08-42-57.bpo-433030.UTwRX7.rst index 1afed73ffeab2..f449306f2fae9 100644 --- a/Misc/NEWS.d/next/Library/2022-03-19-08-42-57.bpo-433030.UTwRX7.rst +++ b/Misc/NEWS.d/next/Library/2022-03-19-08-42-57.bpo-433030.UTwRX7.rst @@ -1,2 +1,2 @@ -Add support of atomic grouping (``(?>...)``) and possessive qualifiers +Add support of atomic grouping (``(?>...)``) and possessive quantifiers (``*+``, ``++``, ``?+``, ``{m,n}+``) in :mod:`regular expressions `. From webhook-mailer at python.org Tue Mar 22 05:53:25 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Tue, 22 Mar 2022 09:53:25 -0000 Subject: [Python-checkins] bpo-28080: Add support for the fallback encoding in ZIP files (GH-32007) Message-ID: https://github.com/python/cpython/commit/a25a985535ccbb7df8caddc0017550ff4eae5855 commit: a25a985535ccbb7df8caddc0017550ff4eae5855 branch: main author: Serhiy Storchaka committer: serhiy-storchaka date: 2022-03-22T11:52:55+02:00 summary: bpo-28080: Add support for the fallback encoding in ZIP files (GH-32007) * Add the metadata_encoding parameter in the zipfile.ZipFile constructor. * Add the --metadata-encoding option in the zipfile CLI. Co-authored-by: Stephen J. Turnbull files: A Misc/NEWS.d/next/Library/2022-03-20-15-54-41.bpo-28080.kn35Vk.rst M Doc/library/zipfile.rst M Doc/whatsnew/3.11.rst M Lib/test/test_zipfile.py M Lib/zipfile.py diff --git a/Doc/library/zipfile.rst b/Doc/library/zipfile.rst index 9d0d894c05b57..bfcc883de6927 100644 --- a/Doc/library/zipfile.rst +++ b/Doc/library/zipfile.rst @@ -139,7 +139,8 @@ ZipFile Objects .. class:: ZipFile(file, mode='r', compression=ZIP_STORED, allowZip64=True, \ - compresslevel=None, *, strict_timestamps=True) + compresslevel=None, *, strict_timestamps=True, + metadata_encoding=None) Open a ZIP file, where *file* can be a path to a file (a string), a file-like object or a :term:`path-like object`. @@ -183,6 +184,10 @@ ZipFile Objects Similar behavior occurs with files newer than 2107-12-31, the timestamp is also set to the limit. + When mode is ``'r'``, *metadata_encoding* may be set to the name of a codec, + which will be used to decode metadata such as the names of members and ZIP + comments. + If the file is created with mode ``'w'``, ``'x'`` or ``'a'`` and then :meth:`closed ` without adding any files to the archive, the appropriate ZIP structures for an empty archive will be written to the file. @@ -194,6 +199,19 @@ ZipFile Objects with ZipFile('spam.zip', 'w') as myzip: myzip.write('eggs.txt') + .. note:: + + *metadata_encoding* is an instance-wide setting for the ZipFile. + It is not currently possible to set this on a per-member basis. + + This attribute is a workaround for legacy implementations which produce + archives with names in the current locale encoding or code page (mostly + on Windows). According to the .ZIP standard, the encoding of metadata + may be specified to be either IBM code page (default) or UTF-8 by a flag + in the archive header. + That flag takes precedence over *metadata_encoding*, which is + a Python-specific extension. + .. versionadded:: 3.2 Added the ability to use :class:`ZipFile` as a context manager. @@ -220,6 +238,10 @@ ZipFile Objects .. versionadded:: 3.8 The *strict_timestamps* keyword-only argument + .. versionchanged:: 3.11 + Added support for specifying member name encoding for reading + metadata in the zipfile's directory and file headers. + .. method:: ZipFile.close() @@ -395,6 +417,15 @@ ZipFile Objects given. The archive must be open with mode ``'w'``, ``'x'`` or ``'a'``. + .. note:: + + The ZIP file standard historically did not specify a metadata encoding, + but strongly recommended CP437 (the original IBM PC encoding) for + interoperability. Recent versions allow use of UTF-8 (only). In this + module, UTF-8 will automatically be used to write the member names if + they contain any non-ASCII characters. It is not possible to write + member names in any encoding other than ASCII or UTF-8. + .. note:: Archive names should be relative to the archive root, that is, they should not @@ -868,6 +899,14 @@ Command-line options Test whether the zipfile is valid or not. +.. cmdoption:: --metadata-encoding + + Specify encoding of member names for :option:`-l`, :option:`-e` and + :option:`-t`. + + .. versionadded:: 3.11 + + Decompression pitfalls ---------------------- diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 96db3a90cfce4..938a573d59574 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -432,6 +432,12 @@ venv Third party code that also creates new virtual environments should do the same. (Contributed by Miro Hron?ok in :issue:`45413`.) +zipfile +------- + +* Added support for specifying member name encoding for reading + metadata in the zipfile's directory and file headers. + (Contributed by Stephen J. Turnbull and Serhiy Storchaka in :issue:`28080`.) fcntl ----- diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index 759a4abb9d4d4..26c40457e62a0 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -21,8 +21,10 @@ from random import randint, random, randbytes from test.support import script_helper -from test.support import (findfile, requires_zlib, requires_bz2, - requires_lzma, captured_stdout, requires_subprocess) +from test.support import ( + findfile, requires_zlib, requires_bz2, requires_lzma, + captured_stdout, captured_stderr, requires_subprocess +) from test.support.os_helper import ( TESTFN, unlink, rmtree, temp_dir, temp_cwd, fd_count ) @@ -3210,5 +3212,139 @@ def test_inheritance(self, alpharep): assert isinstance(file, cls) +class EncodedMetadataTests(unittest.TestCase): + file_names = ['\u4e00', '\u4e8c', '\u4e09'] # Han 'one', 'two', 'three' + file_content = [ + "This is pure ASCII.\n".encode('ascii'), + # This is modern Japanese. (UTF-8) + "\u3053\u308c\u306f\u73fe\u4ee3\u7684\u65e5\u672c\u8a9e\u3067\u3059\u3002\n".encode('utf-8'), + # This is obsolete Japanese. (Shift JIS) + "\u3053\u308c\u306f\u53e4\u3044\u65e5\u672c\u8a9e\u3067\u3059\u3002\n".encode('shift_jis'), + ] + + def setUp(self): + self.addCleanup(unlink, TESTFN) + # Create .zip of 3 members with Han names encoded in Shift JIS. + # Each name is 1 Han character encoding to 2 bytes in Shift JIS. + # The ASCII names are arbitrary as long as they are length 2 and + # not otherwise contained in the zip file. + # Data elements are encoded bytes (ascii, utf-8, shift_jis). + placeholders = ["n1", "n2"] + self.file_names[2:] + with zipfile.ZipFile(TESTFN, mode="w") as tf: + for temp, content in zip(placeholders, self.file_content): + tf.writestr(temp, content, zipfile.ZIP_STORED) + # Hack in the Shift JIS names with flag bit 11 (UTF-8) unset. + with open(TESTFN, "rb") as tf: + data = tf.read() + for name, temp in zip(self.file_names, placeholders[:2]): + data = data.replace(temp.encode('ascii'), + name.encode('shift_jis')) + with open(TESTFN, "wb") as tf: + tf.write(data) + + def _test_read(self, zipfp, expected_names, expected_content): + # Check the namelist + names = zipfp.namelist() + self.assertEqual(sorted(names), sorted(expected_names)) + + # Check infolist + infos = zipfp.infolist() + names = [zi.filename for zi in infos] + self.assertEqual(sorted(names), sorted(expected_names)) + + # check getinfo + for name, content in zip(expected_names, expected_content): + info = zipfp.getinfo(name) + self.assertEqual(info.filename, name) + self.assertEqual(info.file_size, len(content)) + self.assertEqual(zipfp.read(name), content) + + def test_read_with_metadata_encoding(self): + # Read the ZIP archive with correct metadata_encoding + with zipfile.ZipFile(TESTFN, "r", metadata_encoding='shift_jis') as zipfp: + self._test_read(zipfp, self.file_names, self.file_content) + + def test_read_without_metadata_encoding(self): + # Read the ZIP archive without metadata_encoding + expected_names = [name.encode('shift_jis').decode('cp437') + for name in self.file_names[:2]] + self.file_names[2:] + with zipfile.ZipFile(TESTFN, "r") as zipfp: + self._test_read(zipfp, expected_names, self.file_content) + + def test_read_with_incorrect_metadata_encoding(self): + # Read the ZIP archive with incorrect metadata_encoding + expected_names = [name.encode('shift_jis').decode('koi8-u') + for name in self.file_names[:2]] + self.file_names[2:] + with zipfile.ZipFile(TESTFN, "r", metadata_encoding='koi8-u') as zipfp: + self._test_read(zipfp, expected_names, self.file_content) + + def test_read_with_unsuitable_metadata_encoding(self): + # Read the ZIP archive with metadata_encoding unsuitable for + # decoding metadata + with self.assertRaises(UnicodeDecodeError): + zipfile.ZipFile(TESTFN, "r", metadata_encoding='ascii') + with self.assertRaises(UnicodeDecodeError): + zipfile.ZipFile(TESTFN, "r", metadata_encoding='utf-8') + + def test_read_after_append(self): + newname = '\u56db' # Han 'four' + expected_names = [name.encode('shift_jis').decode('cp437') + for name in self.file_names[:2]] + self.file_names[2:] + expected_names.append(newname) + expected_content = (*self.file_content, b"newcontent") + + with zipfile.ZipFile(TESTFN, "a") as zipfp: + zipfp.writestr(newname, "newcontent") + self.assertEqual(sorted(zipfp.namelist()), sorted(expected_names)) + + with zipfile.ZipFile(TESTFN, "r") as zipfp: + self._test_read(zipfp, expected_names, expected_content) + + with zipfile.ZipFile(TESTFN, "r", metadata_encoding='shift_jis') as zipfp: + self.assertEqual(sorted(zipfp.namelist()), sorted(expected_names)) + for i, (name, content) in enumerate(zip(expected_names, expected_content)): + info = zipfp.getinfo(name) + self.assertEqual(info.filename, name) + self.assertEqual(info.file_size, len(content)) + if i < 2: + with self.assertRaises(zipfile.BadZipFile): + zipfp.read(name) + else: + self.assertEqual(zipfp.read(name), content) + + def test_write_with_metadata_encoding(self): + ZF = zipfile.ZipFile + for mode in ("w", "x", "a"): + with self.assertRaisesRegex(ValueError, + "^metadata_encoding is only"): + ZF("nonesuch.zip", mode, metadata_encoding="shift_jis") + + def test_cli_with_metadata_encoding(self): + errmsg = "Non-conforming encodings not supported with -c." + args = ["--metadata-encoding=shift_jis", "-c", "nonesuch", "nonesuch"] + with captured_stdout() as stdout: + with captured_stderr() as stderr: + self.assertRaises(SystemExit, zipfile.main, args) + self.assertEqual(stdout.getvalue(), "") + self.assertIn(errmsg, stderr.getvalue()) + + with captured_stdout() as stdout: + zipfile.main(["--metadata-encoding=shift_jis", "-t", TESTFN]) + listing = stdout.getvalue() + + with captured_stdout() as stdout: + zipfile.main(["--metadata-encoding=shift_jis", "-l", TESTFN]) + listing = stdout.getvalue() + for name in self.file_names: + self.assertIn(name, listing) + + os.mkdir(TESTFN2) + self.addCleanup(rmtree, TESTFN2) + zipfile.main(["--metadata-encoding=shift_jis", "-e", TESTFN, TESTFN2]) + listing = os.listdir(TESTFN2) + for name in self.file_names: + self.assertIn(name, listing) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/zipfile.py b/Lib/zipfile.py index 385adc897317f..721834aff13a7 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -480,7 +480,7 @@ def FileHeader(self, zip64=None): def _encodeFilenameFlags(self): try: - return self.filename.encode('ascii'), self.flag_bits + return self.filename.encode('ascii'), self.flag_bits & ~_MASK_UTF_FILENAME except UnicodeEncodeError: return self.filename.encode('utf-8'), self.flag_bits | _MASK_UTF_FILENAME @@ -1240,7 +1240,7 @@ class ZipFile: _windows_illegal_name_trans_table = None def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=True, - compresslevel=None, *, strict_timestamps=True): + compresslevel=None, *, strict_timestamps=True, metadata_encoding=None): """Open the ZIP file with mode read 'r', write 'w', exclusive create 'x', or append 'a'.""" if mode not in ('r', 'w', 'x', 'a'): @@ -1259,6 +1259,12 @@ def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=True, self.pwd = None self._comment = b'' self._strict_timestamps = strict_timestamps + self.metadata_encoding = metadata_encoding + + # Check that we don't try to write with nonconforming codecs + if self.metadata_encoding and mode != 'r': + raise ValueError( + "metadata_encoding is only supported for reading files") # Check if we were passed a file-like object if isinstance(file, os.PathLike): @@ -1389,13 +1395,13 @@ def _RealGetContents(self): if self.debug > 2: print(centdir) filename = fp.read(centdir[_CD_FILENAME_LENGTH]) - flags = centdir[5] + flags = centdir[_CD_FLAG_BITS] if flags & _MASK_UTF_FILENAME: # UTF-8 file names extension filename = filename.decode('utf-8') else: # Historical ZIP filename encoding - filename = filename.decode('cp437') + filename = filename.decode(self.metadata_encoding or 'cp437') # Create ZipInfo instance to store file information x = ZipInfo(filename) x.extra = fp.read(centdir[_CD_EXTRA_FIELD_LENGTH]) @@ -1572,7 +1578,7 @@ def open(self, name, mode="r", pwd=None, *, force_zip64=False): # UTF-8 filename fname_str = fname.decode("utf-8") else: - fname_str = fname.decode("cp437") + fname_str = fname.decode(self.metadata_encoding or "cp437") if fname_str != zinfo.orig_filename: raise BadZipFile( @@ -2461,11 +2467,15 @@ def main(args=None): help='Create zipfile from sources') group.add_argument('-t', '--test', metavar='', help='Test if a zipfile is valid') + parser.add_argument('--metadata-encoding', metavar='', + help='Specify encoding of member names for -l, -e and -t') args = parser.parse_args(args) + encoding = args.metadata_encoding + if args.test is not None: src = args.test - with ZipFile(src, 'r') as zf: + with ZipFile(src, 'r', metadata_encoding=encoding) as zf: badfile = zf.testzip() if badfile: print("The following enclosed file is corrupted: {!r}".format(badfile)) @@ -2473,15 +2483,20 @@ def main(args=None): elif args.list is not None: src = args.list - with ZipFile(src, 'r') as zf: + with ZipFile(src, 'r', metadata_encoding=encoding) as zf: zf.printdir() elif args.extract is not None: src, curdir = args.extract - with ZipFile(src, 'r') as zf: + with ZipFile(src, 'r', metadata_encoding=encoding) as zf: zf.extractall(curdir) elif args.create is not None: + if encoding: + print("Non-conforming encodings not supported with -c.", + file=sys.stderr) + sys.exit(1) + zip_name = args.create.pop(0) files = args.create diff --git a/Misc/NEWS.d/next/Library/2022-03-20-15-54-41.bpo-28080.kn35Vk.rst b/Misc/NEWS.d/next/Library/2022-03-20-15-54-41.bpo-28080.kn35Vk.rst new file mode 100644 index 0000000000000..08428e63be3d4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-20-15-54-41.bpo-28080.kn35Vk.rst @@ -0,0 +1,4 @@ +Add the *metadata_encoding* parameter in the :class:`zipfile.ZipFile` +constructor and the ``--metadata-encoding`` option in the :mod:`zipfile` +CLI to allow reading zipfiles using non-standard codecs to encode the +filenames within the archive. From webhook-mailer at python.org Tue Mar 22 06:04:51 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 22 Mar 2022 10:04:51 -0000 Subject: [Python-checkins] bpo-40280: Skip socket, fork, subprocess tests on Emscripten (GH-31986) Message-ID: https://github.com/python/cpython/commit/deeaac49e267285158264643799624623f4a7b29 commit: deeaac49e267285158264643799624623f4a7b29 branch: main author: Christian Heimes committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-22T03:04:36-07:00 summary: bpo-40280: Skip socket, fork, subprocess tests on Emscripten (GH-31986) - Add requires_fork and requires_subprocess to more tests - Skip extension import tests if dlopen is not available - Don't assume that _testcapi is a shared extension - Skip a lot of socket tests that don't work on Emscripten - Skip mmap tests, mmap emulation is incomplete - venv does not work yet - Cannot get libc from executable The "entire" test suite is now passing on Emscripten with EMSDK from git head (91 suites are skipped). files: A Misc/NEWS.d/next/Tests/2022-03-19-10-25-04.bpo-40280.wBRSel.rst M Lib/test/lock_tests.py M Lib/test/pythoninfo.py M Lib/test/support/__init__.py M Lib/test/test_asyncgen.py M Lib/test/test_asynchat.py M Lib/test/test_asyncio/__init__.py M Lib/test/test_asyncore.py M Lib/test/test_contextlib_async.py M Lib/test/test_doctest.py M Lib/test/test_docxmlrpc.py M Lib/test/test_ftplib.py M Lib/test/test_httplib.py M Lib/test/test_httpservers.py M Lib/test/test_imaplib.py M Lib/test/test_import/__init__.py M Lib/test/test_importlib/extension/test_finder.py M Lib/test/test_importlib/extension/test_loader.py M Lib/test/test_json/test_tool.py M Lib/test/test_logging.py M Lib/test/test_mailbox.py M Lib/test/test_mmap.py M Lib/test/test_pdb.py M Lib/test/test_peg_generator/test_c_parser.py M Lib/test/test_platform.py M Lib/test/test_poll.py M Lib/test/test_poplib.py M Lib/test/test_pydoc.py M Lib/test/test_robotparser.py M Lib/test/test_select.py M Lib/test/test_selectors.py M Lib/test/test_smtplib.py M Lib/test/test_socket.py M Lib/test/test_socketserver.py M Lib/test/test_sys_settrace.py M Lib/test/test_telnetlib.py M Lib/test/test_tools/__init__.py M Lib/test/test_urllib2.py M Lib/test/test_urllib2_localnet.py M Lib/test/test_venv.py M Lib/test/test_wait3.py M Lib/test/test_wait4.py M Lib/test/test_xmlrpc.py M Lib/unittest/test/__init__.py M Lib/unittest/test/test_async_case.py M Lib/unittest/test/test_program.py M Lib/unittest/test/test_runner.py M Lib/unittest/test/testmock/testasync.py M Makefile.pre.in M configure M configure.ac M setup.py diff --git a/Lib/test/lock_tests.py b/Lib/test/lock_tests.py index d82629368dff8..f16c7ed952cf5 100644 --- a/Lib/test/lock_tests.py +++ b/Lib/test/lock_tests.py @@ -15,7 +15,7 @@ from test.support import threading_helper -requires_fork = unittest.skipUnless(hasattr(os, 'fork'), +requires_fork = unittest.skipUnless(support.has_fork_support, "platform doesn't support fork " "(no _at_fork_reinit method)") diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index d15a11c80b649..b00830c279e87 100644 --- a/Lib/test/pythoninfo.py +++ b/Lib/test/pythoninfo.py @@ -6,6 +6,7 @@ import re import sys import traceback +import unittest import warnings @@ -615,7 +616,7 @@ def collect_resource(info_add): def collect_test_socket(info_add): try: from test import test_socket - except ImportError: + except (ImportError, unittest.SkipTest): return # all check attributes like HAVE_SOCKET_CAN diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index fc1b86bebcd1a..c5666d66f4782 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -42,6 +42,7 @@ "requires_IEEE_754", "requires_zlib", "has_fork_support", "requires_fork", "has_subprocess_support", "requires_subprocess", + "has_socket_support", "requires_working_socket", "anticipate_failure", "load_package_tests", "detect_api_mismatch", "check__all__", "skip_if_buggy_ucrt_strfptime", "check_disallow_instantiation", "check_sanitizer", "skip_if_sanitizer", @@ -520,6 +521,21 @@ def requires_subprocess(): """Used for subprocess, os.spawn calls, fd inheritance""" return unittest.skipUnless(has_subprocess_support, "requires subprocess support") +# Emscripten's socket emulation has limitation. WASI doesn't have sockets yet. +has_socket_support = not is_emscripten and not is_wasi + +def requires_working_socket(*, module=False): + """Skip tests or modules that require working sockets + + Can be used as a function/class decorator or to skip an entire module. + """ + msg = "requires socket support" + if module: + if not has_socket_support: + raise unittest.SkipTest(msg) + else: + return unittest.skipUnless(has_socket_support, msg) + # Does strftime() support glibc extension like '%4Y'? has_strftime_extensions = False if sys.platform != "win32": diff --git a/Lib/test/test_asyncgen.py b/Lib/test/test_asyncgen.py index 473bce484b47b..fb22f411c2e29 100644 --- a/Lib/test/test_asyncgen.py +++ b/Lib/test/test_asyncgen.py @@ -4,10 +4,12 @@ import contextlib from test.support.import_helper import import_module -from test.support import gc_collect +from test.support import gc_collect, requires_working_socket asyncio = import_module("asyncio") +requires_working_socket(module=True) + _no_default = object() diff --git a/Lib/test/test_asynchat.py b/Lib/test/test_asynchat.py index 973ac1f7d97c9..d28d67732e788 100644 --- a/Lib/test/test_asynchat.py +++ b/Lib/test/test_asynchat.py @@ -18,6 +18,8 @@ import asynchat import asyncore +support.requires_working_socket(module=True) + HOST = socket_helper.HOST SERVER_QUIT = b'QUIT\n' diff --git a/Lib/test/test_asyncio/__init__.py b/Lib/test/test_asyncio/__init__.py index 5d415044d7dc6..ab0b5aa948925 100644 --- a/Lib/test/test_asyncio/__init__.py +++ b/Lib/test/test_asyncio/__init__.py @@ -1,7 +1,9 @@ import os +from test import support from test.support import load_package_tests from test.support import import_helper +support.requires_working_socket(module=True) # Skip tests if we don't have concurrent.futures. import_helper.import_module('concurrent.futures') diff --git a/Lib/test/test_asyncore.py b/Lib/test/test_asyncore.py index ecd1e120ecb51..e3f31bd06d0c3 100644 --- a/Lib/test/test_asyncore.py +++ b/Lib/test/test_asyncore.py @@ -18,6 +18,8 @@ if support.PGO: raise unittest.SkipTest("test is not helpful for PGO") +support.requires_working_socket(module=True) + import warnings with warnings.catch_warnings(): warnings.simplefilter('ignore', DeprecationWarning) diff --git a/Lib/test/test_contextlib_async.py b/Lib/test/test_contextlib_async.py index c16c7ecd19a25..462e05cc79aec 100644 --- a/Lib/test/test_contextlib_async.py +++ b/Lib/test/test_contextlib_async.py @@ -8,6 +8,7 @@ from test.test_contextlib import TestBaseExitStack +support.requires_working_socket(module=True) def _async_test(func): """Decorator to turn an async function into a test case.""" diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py index 407a14c7ddf67..8616aeddc1d5d 100644 --- a/Lib/test/test_doctest.py +++ b/Lib/test/test_doctest.py @@ -18,6 +18,11 @@ import types import contextlib + +if not support.has_subprocess_support: + raise unittest.SkipTest("test_CLI requires subprocess support.") + + # NOTE: There are some additional tests relating to interaction with # zipimport in the test_zipimport_support test module. @@ -455,7 +460,7 @@ def basics(): r""" >>> tests = finder.find(sample_func) >>> print(tests) # doctest: +ELLIPSIS - [] + [] The exact name depends on how test_doctest was invoked, so allow for leading path components. diff --git a/Lib/test/test_docxmlrpc.py b/Lib/test/test_docxmlrpc.py index 9a06be4585502..89d80091850f5 100644 --- a/Lib/test/test_docxmlrpc.py +++ b/Lib/test/test_docxmlrpc.py @@ -4,6 +4,9 @@ import sys import threading import unittest +from test import support + +support.requires_working_socket(module=True) def make_request_and_skipIf(condition, reason): # If we skip the test, we have to make a request because diff --git a/Lib/test/test_ftplib.py b/Lib/test/test_ftplib.py index 2f5cc06ca4b9a..2794fccfe7c72 100644 --- a/Lib/test/test_ftplib.py +++ b/Lib/test/test_ftplib.py @@ -29,6 +29,7 @@ import asyncore import asynchat +support.requires_working_socket(module=True) TIMEOUT = support.LOOPBACK_TIMEOUT DEFAULT_ENCODING = 'utf-8' diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py index 8265b8d1d6d2d..15dab0356f5e3 100644 --- a/Lib/test/test_httplib.py +++ b/Lib/test/test_httplib.py @@ -19,6 +19,7 @@ from test.support import socket_helper from test.support import warnings_helper +support.requires_working_socket(module=True) here = os.path.dirname(__file__) # Self-signed cert file for 'localhost' diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py index 1cc020f63539d..d20b45e8e02f8 100644 --- a/Lib/test/test_httpservers.py +++ b/Lib/test/test_httpservers.py @@ -33,6 +33,7 @@ from test.support import os_helper from test.support import threading_helper +support.requires_working_socket(module=True) class NoLogRequestHandler: def log_message(self, *args): diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py index 30b553746af11..ff13edea2d1e4 100644 --- a/Lib/test/test_imaplib.py +++ b/Lib/test/test_imaplib.py @@ -11,7 +11,8 @@ import socket from test.support import (verbose, - run_with_tz, run_with_locale, cpython_only) + run_with_tz, run_with_locale, cpython_only, + requires_working_socket) from test.support import hashlib_helper from test.support import threading_helper from test.support import warnings_helper @@ -23,6 +24,8 @@ except ImportError: ssl = None +support.requires_working_socket(module=True) + CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "keycert3.pem") CAFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "pycacert.pem") diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index 8857fd5000bb1..7cca9f9d60ab6 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -20,7 +20,7 @@ from test.support import os_helper from test.support import ( - STDLIB_DIR, is_jython, swap_attr, swap_item, cpython_only) + STDLIB_DIR, is_jython, swap_attr, swap_item, cpython_only, is_emscripten) from test.support.import_helper import ( forget, make_legacy_pyc, unlink, unload, DirsOnSysPath, CleanImport) from test.support.os_helper import ( @@ -101,8 +101,17 @@ def test_from_import_missing_attr_has_name_and_so_path(self): with self.assertRaises(ImportError) as cm: from _testcapi import i_dont_exist self.assertEqual(cm.exception.name, '_testcapi') - self.assertEqual(cm.exception.path, _testcapi.__file__) - self.assertRegex(str(cm.exception), r"cannot import name 'i_dont_exist' from '_testcapi' \(.*\.(so|pyd)\)") + if hasattr(_testcapi, "__file__"): + self.assertEqual(cm.exception.path, _testcapi.__file__) + self.assertRegex( + str(cm.exception), + r"cannot import name 'i_dont_exist' from '_testcapi' \(.*\.(so|pyd)\)" + ) + else: + self.assertEqual( + str(cm.exception), + "cannot import name 'i_dont_exist' from '_testcapi' (unknown location)" + ) def test_from_import_missing_attr_has_name(self): with self.assertRaises(ImportError) as cm: @@ -525,6 +534,7 @@ class FilePermissionTests(unittest.TestCase): @unittest.skipUnless(os.name == 'posix', "test meaningful only on posix systems") + @unittest.skipIf(is_emscripten, "Emscripten's umask is a stub.") def test_creation_mode(self): mask = 0o022 with temp_umask(mask), _ready_to_import() as (name, path): diff --git a/Lib/test/test_importlib/extension/test_finder.py b/Lib/test/test_importlib/extension/test_finder.py index 140f20657f736..b6663a4484550 100644 --- a/Lib/test/test_importlib/extension/test_finder.py +++ b/Lib/test/test_importlib/extension/test_finder.py @@ -10,6 +10,10 @@ class FinderTests(abc.FinderTests): """Test the finder for extension modules.""" + def setUp(self): + if not self.machinery.EXTENSION_SUFFIXES: + raise unittest.SkipTest("Requires dynamic loading support.") + def find_spec(self, fullname): importer = self.machinery.FileFinder(util.EXTENSIONS.path, (self.machinery.ExtensionFileLoader, diff --git a/Lib/test/test_importlib/extension/test_loader.py b/Lib/test/test_importlib/extension/test_loader.py index e7a88a8f5e321..5080009bee32e 100644 --- a/Lib/test/test_importlib/extension/test_loader.py +++ b/Lib/test/test_importlib/extension/test_loader.py @@ -12,11 +12,14 @@ import importlib from test.support.script_helper import assert_python_failure + class LoaderTests(abc.LoaderTests): """Test load_module() for extension modules.""" def setUp(self): + if not self.machinery.EXTENSION_SUFFIXES: + raise unittest.SkipTest("Requires dynamic loading support.") self.loader = self.machinery.ExtensionFileLoader(util.EXTENSIONS.name, util.EXTENSIONS.file_path) @@ -91,6 +94,8 @@ class MultiPhaseExtensionModuleTests(abc.LoaderTests): # Test loading extension modules with multi-phase initialization (PEP 489). def setUp(self): + if not self.machinery.EXTENSION_SUFFIXES: + raise unittest.SkipTest("Requires dynamic loading support.") self.name = '_testmultiphase' finder = self.machinery.FileFinder(None) self.spec = importlib.util.find_spec(self.name) diff --git a/Lib/test/test_json/test_tool.py b/Lib/test/test_json/test_tool.py index 1d7fca6efb1cc..2b63810d53981 100644 --- a/Lib/test/test_json/test_tool.py +++ b/Lib/test/test_json/test_tool.py @@ -10,6 +10,7 @@ from test.support.script_helper import assert_python_ok + at support.requires_subprocess() class TestTool(unittest.TestCase): data = """ diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index be193dcdacf4f..5f72a6dd5871a 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -75,6 +75,7 @@ except ImportError: pass + class BaseTest(unittest.TestCase): """Base class for logging tests.""" @@ -626,6 +627,9 @@ def test_path_objects(self): os.unlink(fn) @unittest.skipIf(os.name == 'nt', 'WatchedFileHandler not appropriate for Windows.') + @unittest.skipIf( + support.is_emscripten, "Emscripten cannot fstat unlinked files." + ) def test_race(self): # Issue #14632 refers. def remove_loop(fname, tries): @@ -1058,6 +1062,7 @@ class TestUnixDatagramServer(TestUDPServer): # - end of server_helper section + at support.requires_working_socket() class SMTPHandlerTest(BaseTest): # bpo-14314, bpo-19665, bpo-34092: don't wait forever TIMEOUT = support.LONG_TIMEOUT @@ -1681,6 +1686,7 @@ def test_defaults_do_no_interpolation(self): os.unlink(fn) + at support.requires_working_socket() class SocketHandlerTest(BaseTest): """Test for SocketHandler objects.""" @@ -1795,6 +1801,7 @@ def tearDown(self): SocketHandlerTest.tearDown(self) os_helper.unlink(self.address) + at support.requires_working_socket() class DatagramHandlerTest(BaseTest): """Test for DatagramHandler.""" @@ -1876,6 +1883,7 @@ def tearDown(self): DatagramHandlerTest.tearDown(self) os_helper.unlink(self.address) + at support.requires_working_socket() class SysLogHandlerTest(BaseTest): """Test for SysLogHandler using UDP.""" @@ -1985,6 +1993,7 @@ def tearDown(self): self.server_class.address_family = socket.AF_INET super(IPv6SysLogHandlerTest, self).tearDown() + at support.requires_working_socket() class HTTPHandlerTest(BaseTest): """Test for HTTPHandler.""" @@ -3261,6 +3270,7 @@ def setup_via_listener(self, text, verify=None): logging.config.stopListening() threading_helper.join_thread(t) + @support.requires_working_socket() def test_listen_config_10_ok(self): with support.captured_stdout() as output: self.setup_via_listener(json.dumps(self.config10)) @@ -3280,6 +3290,7 @@ def test_listen_config_10_ok(self): ('ERROR', '4'), ], stream=output) + @support.requires_working_socket() def test_listen_config_1_ok(self): with support.captured_stdout() as output: self.setup_via_listener(textwrap.dedent(ConfigFileTest.config1)) @@ -3294,6 +3305,7 @@ def test_listen_config_1_ok(self): # Original logger output is empty. self.assert_log_lines([]) + @support.requires_working_socket() def test_listen_verify(self): def verify_fail(stuff): diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py index 604fc4525f53e..20c460e300cc9 100644 --- a/Lib/test/test_mailbox.py +++ b/Lib/test/test_mailbox.py @@ -1061,7 +1061,7 @@ def test_add_and_close(self): self.assertEqual(contents, f.read()) self._box = self._factory(self._path) - @unittest.skipUnless(hasattr(os, 'fork'), "Test needs fork().") + @support.requires_fork() @unittest.skipUnless(hasattr(socket, 'socketpair'), "Test needs socketpair().") def test_lock_conflict(self): # Fork off a child process that will lock the mailbox temporarily, diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py index 014171cbb4911..213a44d56f37b 100644 --- a/Lib/test/test_mmap.py +++ b/Lib/test/test_mmap.py @@ -1,4 +1,6 @@ -from test.support import (requires, _2G, _4G, gc_collect, cpython_only) +from test.support import ( + requires, _2G, _4G, gc_collect, cpython_only, is_emscripten +) from test.support.import_helper import import_module from test.support.os_helper import TESTFN, unlink import unittest @@ -21,6 +23,12 @@ def random_tagname(length=10): suffix = ''.join(random.choices(string.ascii_uppercase, k=length)) return f'{tagname_prefix}_{suffix}' +# Python's mmap module dup()s the file descriptor. Emscripten's FS layer +# does not materialize file changes through a dupped fd to a new mmap. +if is_emscripten: + raise unittest.SkipTest("incompatible with Emscripten's mmap emulation.") + + class MmapTests(unittest.TestCase): def setUp(self): diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index d2bf3dc90ed23..bfa2cc92d2514 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -13,6 +13,7 @@ from contextlib import ExitStack, redirect_stdout from io import StringIO +from test import support from test.support import os_helper # This little helper class is essential for testing pdb under doctest. from test.test_doctest import _FakeInput @@ -1363,6 +1364,7 @@ def test_pdb_issue_43318(): """ + at support.requires_subprocess() class PdbTestCase(unittest.TestCase): def tearDown(self): os_helper.unlink(os_helper.TESTFN) diff --git a/Lib/test/test_peg_generator/test_c_parser.py b/Lib/test/test_peg_generator/test_c_parser.py index b761bd493f52c..51a4f7d7c07a0 100644 --- a/Lib/test/test_peg_generator/test_c_parser.py +++ b/Lib/test/test_peg_generator/test_c_parser.py @@ -70,6 +70,7 @@ def test_parse(self): """ + at support.requires_subprocess() class TestCParser(unittest.TestCase): def setUp(self): self._backup_config_vars = dict(sysconfig._CONFIG_VARS) diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py index d70ef155271f5..9b2cd201f3c2f 100644 --- a/Lib/test/test_platform.py +++ b/Lib/test/test_platform.py @@ -364,6 +364,7 @@ def test_mac_ver_with_fork(self): # parent support.wait_process(pid, exitcode=0) + @unittest.skipIf(support.is_emscripten, "Does not apply to Emscripten") def test_libc_ver(self): # check that libc_ver(executable) doesn't raise an exception if os.path.isdir(sys.executable) and \ diff --git a/Lib/test/test_poll.py b/Lib/test/test_poll.py index ae3ffc77e9924..7d542b5cfd783 100644 --- a/Lib/test/test_poll.py +++ b/Lib/test/test_poll.py @@ -7,7 +7,9 @@ import threading import time import unittest -from test.support import cpython_only, requires_subprocess +from test.support import ( + cpython_only, requires_subprocess, requires_working_socket +) from test.support import threading_helper from test.support.os_helper import TESTFN @@ -17,6 +19,7 @@ except AttributeError: raise unittest.SkipTest("select.poll not defined") +requires_working_socket(module=True) def find_ready_matching(ready, flag): match = [] diff --git a/Lib/test/test_poplib.py b/Lib/test/test_poplib.py index 1220ca32ef82e..57ccc541b81fe 100644 --- a/Lib/test/test_poplib.py +++ b/Lib/test/test_poplib.py @@ -22,6 +22,8 @@ import asynchat import asyncore +test_support.requires_working_socket(module=True) + HOST = socket_helper.HOST PORT = 0 diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py index 7cedf76fb3af4..e2dab1207172d 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -27,7 +27,7 @@ from test.support.script_helper import assert_python_ok, assert_python_failure from test.support import threading_helper from test.support import (reap_children, captured_output, captured_stdout, - captured_stderr, requires_docstrings) + captured_stderr, is_emscripten, requires_docstrings) from test.support.os_helper import (TESTFN, rmtree, unlink) from test import pydoc_mod @@ -1339,6 +1339,7 @@ def a_fn_with_https_link(): ) + at unittest.skipIf(is_emscripten, "Socket server not available on Emscripten.") class PydocServerTest(unittest.TestCase): """Tests for pydoc._start_server""" diff --git a/Lib/test/test_robotparser.py b/Lib/test/test_robotparser.py index b0bed431d4b05..08bdf59d333d4 100644 --- a/Lib/test/test_robotparser.py +++ b/Lib/test/test_robotparser.py @@ -308,6 +308,9 @@ def log_message(self, format, *args): pass + at unittest.skipIf( + support.is_emscripten, "Socket server not available on Emscripten." +) class PasswordProtectedSiteTestCase(unittest.TestCase): def setUp(self): diff --git a/Lib/test/test_select.py b/Lib/test/test_select.py index 8b59321121e49..ca2a9d9d24dab 100644 --- a/Lib/test/test_select.py +++ b/Lib/test/test_select.py @@ -7,6 +7,8 @@ import unittest from test import support +support.requires_working_socket(module=True) + @unittest.skipIf((sys.platform[:3]=='win'), "can't easily test on this system") class SelectTestCase(unittest.TestCase): diff --git a/Lib/test/test_selectors.py b/Lib/test/test_selectors.py index fe6b725a4bd05..c927331d438b0 100644 --- a/Lib/test/test_selectors.py +++ b/Lib/test/test_selectors.py @@ -19,6 +19,10 @@ resource = None +if support.is_emscripten: + raise unittest.SkipTest("Cannot create socketpair on Emscripten.") + + if hasattr(socket, 'socketpair'): socketpair = socket.socketpair else: diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py index 1a60fef8a428b..e798645a5ca66 100644 --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -29,6 +29,8 @@ import asyncore import smtpd +support.requires_working_socket(module=True) + HOST = socket_helper.HOST if sys.platform == 'darwin': diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 53aa5e90fa25c..97cc6260c3c2a 100755 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -37,6 +37,8 @@ except ImportError: fcntl = None +support.requires_working_socket(module=True) + HOST = socket_helper.HOST # test unicode string and carriage return MSG = 'Michael Gilfix was here\u1234\r\n'.encode('utf-8') diff --git a/Lib/test/test_socketserver.py b/Lib/test/test_socketserver.py index 211321f37617e..c498d3d12e24a 100644 --- a/Lib/test/test_socketserver.py +++ b/Lib/test/test_socketserver.py @@ -28,7 +28,7 @@ HAVE_UNIX_SOCKETS = hasattr(socket, "AF_UNIX") requires_unix_sockets = unittest.skipUnless(HAVE_UNIX_SOCKETS, 'requires Unix sockets') -HAVE_FORKING = hasattr(os, "fork") +HAVE_FORKING = test.support.has_fork_support requires_forking = unittest.skipUnless(HAVE_FORKING, 'requires forking') def signal_alarm(n): diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index fe6f7da0fd758..85d6bdf7221e3 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -8,6 +8,7 @@ from functools import wraps import asyncio +support.requires_working_socket(module=True) class tracecontext: """Context manager that traces its enter and exit.""" diff --git a/Lib/test/test_telnetlib.py b/Lib/test/test_telnetlib.py index 41c4fcd4195e3..b50df1459d1f4 100644 --- a/Lib/test/test_telnetlib.py +++ b/Lib/test/test_telnetlib.py @@ -8,6 +8,8 @@ from test.support import socket_helper import unittest +support.requires_working_socket(module=True) + HOST = socket_helper.HOST def server(evt, serv): diff --git a/Lib/test/test_tools/__init__.py b/Lib/test/test_tools/__init__.py index 34b0d3b8fb3eb..2102b9fceff56 100644 --- a/Lib/test/test_tools/__init__.py +++ b/Lib/test/test_tools/__init__.py @@ -13,6 +13,10 @@ raise unittest.SkipTest("test too slow on ASAN/MSAN build") +if not support.has_subprocess_support: + raise unittest.SkipTest("test module requires subprocess") + + basepath = os.path.normpath( os.path.dirname( # os.path.dirname( # Lib diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py index a4772a5b1d944..46a0ab1d83e60 100644 --- a/Lib/test/test_urllib2.py +++ b/Lib/test/test_urllib2.py @@ -24,6 +24,8 @@ import urllib.error import http.client +support.requires_working_socket(module=True) + # XXX # Request # CacheFTPHandler (hard to write) diff --git a/Lib/test/test_urllib2_localnet.py b/Lib/test/test_urllib2_localnet.py index 1b2baf2f366b5..36314312ac0eb 100644 --- a/Lib/test/test_urllib2_localnet.py +++ b/Lib/test/test_urllib2_localnet.py @@ -8,6 +8,7 @@ import unittest import hashlib +from test import support from test.support import hashlib_helper from test.support import threading_helper from test.support import warnings_helper @@ -17,6 +18,8 @@ except ImportError: ssl = None +support.requires_working_socket(module=True) + here = os.path.dirname(__file__) # Self-signed cert file for 'localhost' CERT_localhost = os.path.join(here, 'keycert.pem') diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py index db812f21dbc56..c91b75493841b 100644 --- a/Lib/test/test_venv.py +++ b/Lib/test/test_venv.py @@ -16,7 +16,7 @@ import tempfile from test.support import (captured_stdout, captured_stderr, requires_zlib, skip_if_broken_multiprocessing_synchronize, verbose, - requires_subprocess) + requires_subprocess, is_emscripten) from test.support.os_helper import (can_symlink, EnvironmentVarGuard, rmtree) import unittest import venv @@ -34,6 +34,9 @@ or sys._base_executable != sys.executable, 'cannot run venv.create from within a venv on this platform') +if is_emscripten: + raise unittest.SkipTest("venv is not available on Emscripten.") + @requires_subprocess() def check_output(cmd, encoding=None): p = subprocess.Popen(cmd, diff --git a/Lib/test/test_wait3.py b/Lib/test/test_wait3.py index aa166baa400bc..4ec7690ac19bb 100644 --- a/Lib/test/test_wait3.py +++ b/Lib/test/test_wait3.py @@ -9,8 +9,8 @@ from test.fork_wait import ForkWait from test import support -if not hasattr(os, 'fork'): - raise unittest.SkipTest("os.fork not defined") +if not support.has_fork_support: + raise unittest.SkipTest("requires working os.fork()") if not hasattr(os, 'wait3'): raise unittest.SkipTest("os.wait3 not defined") diff --git a/Lib/test/test_wait4.py b/Lib/test/test_wait4.py index f8d5e13014f0c..24f1aaec60c56 100644 --- a/Lib/test/test_wait4.py +++ b/Lib/test/test_wait4.py @@ -9,7 +9,9 @@ from test import support # If either of these do not exist, skip this test. -support.get_attribute(os, 'fork') +if not support.has_fork_support: + raise unittest.SkipTest("requires working os.fork()") + support.get_attribute(os, 'wait4') diff --git a/Lib/test/test_xmlrpc.py b/Lib/test/test_xmlrpc.py index 1f06f5fdf483e..6c4601ddaddcb 100644 --- a/Lib/test/test_xmlrpc.py +++ b/Lib/test/test_xmlrpc.py @@ -25,6 +25,8 @@ except ImportError: gzip = None +support.requires_working_socket(module=True) + alist = [{'astring': 'foo at bar.baz.spam', 'afloat': 7283.43, 'anint': 2**20, diff --git a/Lib/unittest/test/__init__.py b/Lib/unittest/test/__init__.py index cdae8a7442785..143f4ab5a3d87 100644 --- a/Lib/unittest/test/__init__.py +++ b/Lib/unittest/test/__init__.py @@ -11,7 +11,10 @@ def suite(): for fn in os.listdir(here): if fn.startswith("test") and fn.endswith(".py"): modname = "unittest.test." + fn[:-3] - __import__(modname) + try: + __import__(modname) + except unittest.SkipTest: + continue module = sys.modules[modname] suite.addTest(loader.loadTestsFromModule(module)) suite.addTest(loader.loadTestsFromName('unittest.test.testmock')) diff --git a/Lib/unittest/test/test_async_case.py b/Lib/unittest/test/test_async_case.py index 7dc8a6bffa019..a48140829cc21 100644 --- a/Lib/unittest/test/test_async_case.py +++ b/Lib/unittest/test/test_async_case.py @@ -3,6 +3,8 @@ import unittest from test import support +support.requires_working_socket(module=True) + class MyException(Exception): pass diff --git a/Lib/unittest/test/test_program.py b/Lib/unittest/test/test_program.py index fa9e6291caaf5..126497aa56656 100644 --- a/Lib/unittest/test/test_program.py +++ b/Lib/unittest/test/test_program.py @@ -196,6 +196,7 @@ def run(self, test): return RESULT + at support.requires_subprocess() class TestCommandLineArgs(unittest.TestCase): def setUp(self): diff --git a/Lib/unittest/test/test_runner.py b/Lib/unittest/test/test_runner.py index c487e9ec4efcb..18062ae5a5871 100644 --- a/Lib/unittest/test/test_runner.py +++ b/Lib/unittest/test/test_runner.py @@ -3,6 +3,7 @@ import sys import pickle import subprocess +from test import support import unittest from unittest.case import _Outcome @@ -1139,6 +1140,7 @@ def MockResultClass(*args): expectedresult = (runner.stream, DESCRIPTIONS, VERBOSITY) self.assertEqual(runner._makeResult(), expectedresult) + @support.requires_subprocess() def test_warnings(self): """ Check that warnings argument of TextTestRunner correctly affects the diff --git a/Lib/unittest/test/testmock/testasync.py b/Lib/unittest/test/testmock/testasync.py index 122e6956635d5..1bab671acdef1 100644 --- a/Lib/unittest/test/testmock/testasync.py +++ b/Lib/unittest/test/testmock/testasync.py @@ -4,6 +4,9 @@ import re import unittest from contextlib import contextmanager +from test import support + +support.requires_working_socket(module=True) from asyncio import run, iscoroutinefunction from unittest import IsolatedAsyncioTestCase diff --git a/Makefile.pre.in b/Makefile.pre.in index c4034dc248c65..4b9aab0a284ce 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -2352,7 +2352,7 @@ clean-retain-profile: pycremoval -rm -f pybuilddir.txt -rm -f Lib/lib2to3/*Grammar*.pickle -rm -f _bootstrap_python - -rm -f python.html python*.js python.data + -rm -f python.html python*.js python.data python*.symbols python*.map -rm -rf $(WASM_STDLIB) -rm -f Programs/_testembed Programs/_freeze_module -rm -f Python/deepfreeze/*.[co] diff --git a/Misc/NEWS.d/next/Tests/2022-03-19-10-25-04.bpo-40280.wBRSel.rst b/Misc/NEWS.d/next/Tests/2022-03-19-10-25-04.bpo-40280.wBRSel.rst new file mode 100644 index 0000000000000..2572c27a8211a --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2022-03-19-10-25-04.bpo-40280.wBRSel.rst @@ -0,0 +1,2 @@ +The test suite is now passing on the Emscripten platform. All fork, socket, +and subprocess-based tests are skipped. diff --git a/configure b/configure index 5fa6efaab4fb7..5ebcadd64239d 100755 --- a/configure +++ b/configure @@ -7396,6 +7396,13 @@ $as_echo "$as_me: llvm-ar found via xcrun: ${LLVM_AR}" >&6;} ;; esac ;; + *emcc*) + if test "$Py_LTO_POLICY" != "default"; then + as_fn_error $? "emcc supports only default lto." "$LINENO" 5 + fi + LTOFLAGS="-flto" + LTOCFLAGS="-flto" + ;; *gcc*) if test $Py_LTO_POLICY = thin then @@ -7717,17 +7724,34 @@ then fi # WASM flags +# TODO: Add -s MAIN_MODULE=2 for dlopen() support. +# The option disables code elimination, which increases code size of main +# binary. All objects must be built with -fPIC. case $ac_sys_system/$ac_sys_emscripten_target in #( Emscripten/browser) : - LDFLAGS_NODIST="$LDFLAGS_NODIST -s ASSERTIONS=1 -s ALLOW_MEMORY_GROWTH=1 --preload-file \$(WASM_ASSETS_DIR)" + LDFLAGS_NODIST="$LDFLAGS_NODIST -s ALLOW_MEMORY_GROWTH=1" + LINKFORSHARED="--preload-file \$(WASM_ASSETS_DIR)" WASM_ASSETS_DIR=".\$(prefix)" WASM_STDLIB="\$(WASM_ASSETS_DIR)/local/lib/python\$(VERSION)/os.py" + if test "$Py_DEBUG" = 'true'; then + LDFLAGS_NODIST="$LDFLAGS_NODIST -s ASSERTIONS=1" + LINKFORSHARED="$LINKFORSHARED -gsource-map --emit-symbol-map" + else + LINKFORSHARED="$LINKFORSHARED -O2 -g0" + fi ;; #( Emscripten/node) : - LDFLAGS_NODIST="$LDFLAGS_NODIST -s ASSERTIONS=1 -s ALLOW_MEMORY_GROWTH=1 -s NODERAWFS=1 -s EXIT_RUNTIME=1 -s USE_PTHREADS -s PROXY_TO_PTHREAD" + LDFLAGS_NODIST="$LDFLAGS_NODIST -s ALLOW_MEMORY_GROWTH=1 -s NODERAWFS=1 -s USE_PTHREADS=1" + LINKFORSHARED="-s PROXY_TO_PTHREAD=1 -s EXIT_RUNTIME=1" CFLAGS_NODIST="$CFLAGS_NODIST -pthread" + if test "$Py_DEBUG" = 'true'; then + LDFLAGS_NODIST="$LDFLAGS_NODIST -s ASSERTIONS=1" + LINKFORSHARED="$LINKFORSHARED -gseparate-dwarf --emit-symbol-map" + else + LINKFORSHARED="$LINKFORSHARED -O2 -gseparate-dwarf" + fi ;; #( WASI/*) : @@ -10403,6 +10427,10 @@ then Linux*|GNU*|QNX*|VxWorks*|Haiku*) LDSHARED='$(CC) -shared' LDCXXSHARED='$(CXX) -shared';; + Emscripten*) + LDSHARED='$(CC) -shared -s SIDE_MODULE=1' + LDCXXSHARED='$(CXX) -shared -s SIDE_MODULE=1' + ;; FreeBSD*) if [ "`$CC -dM -E - &6; } fi +if test "$have_zlib" = "yes" -a "$ac_sys_system" = "Emscripten" -a "$ZLIB_LIBS" = "-lz"; then + ZLIB_LIBS="-s USE_ZLIB=1" +fi + if test "x$have_zlib" = xyes; then : BINASCII_CFLAGS="-DUSE_ZLIB_CRC32 $ZLIB_CFLAGS" @@ -15292,6 +15324,11 @@ $as_echo "yes" >&6; } have_bzip2=yes fi +if test "$have_bzip2" = "yes" -a "$ac_sys_system" = "Emscripten" -a "$BZIP2_LIBS" = "-lbz2"; then + BZIP2_LIBS="-s USE_BZIP2=1" +fi + + pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBLZMA" >&5 diff --git a/configure.ac b/configure.ac index 7a37ad279d0fc..4afc898e81d50 100644 --- a/configure.ac +++ b/configure.ac @@ -1659,6 +1659,13 @@ if test "$Py_LTO" = 'true' ; then ;; esac ;; + *emcc*) + if test "$Py_LTO_POLICY" != "default"; then + AC_MSG_ERROR([emcc supports only default lto.]) + fi + LTOFLAGS="-flto" + LTOCFLAGS="-flto" + ;; *gcc*) if test $Py_LTO_POLICY = thin then @@ -1861,15 +1868,33 @@ then fi # WASM flags +# TODO: Add -s MAIN_MODULE=2 for dlopen() support. +# The option disables code elimination, which increases code size of main +# binary. All objects must be built with -fPIC. AS_CASE([$ac_sys_system/$ac_sys_emscripten_target], [Emscripten/browser], [ - LDFLAGS_NODIST="$LDFLAGS_NODIST -s ASSERTIONS=1 -s ALLOW_MEMORY_GROWTH=1 --preload-file \$(WASM_ASSETS_DIR)" + LDFLAGS_NODIST="$LDFLAGS_NODIST -s ALLOW_MEMORY_GROWTH=1" + LINKFORSHARED="--preload-file \$(WASM_ASSETS_DIR)" WASM_ASSETS_DIR=".\$(prefix)" WASM_STDLIB="\$(WASM_ASSETS_DIR)/local/lib/python\$(VERSION)/os.py" + dnl separate-dwarf does not seem to work in Chrome DevTools Support. + if test "$Py_DEBUG" = 'true'; then + LDFLAGS_NODIST="$LDFLAGS_NODIST -s ASSERTIONS=1" + LINKFORSHARED="$LINKFORSHARED -gsource-map --emit-symbol-map" + else + LINKFORSHARED="$LINKFORSHARED -O2 -g0" + fi ], [Emscripten/node], [ - LDFLAGS_NODIST="$LDFLAGS_NODIST -s ASSERTIONS=1 -s ALLOW_MEMORY_GROWTH=1 -s NODERAWFS=1 -s EXIT_RUNTIME=1 -s USE_PTHREADS -s PROXY_TO_PTHREAD" + LDFLAGS_NODIST="$LDFLAGS_NODIST -s ALLOW_MEMORY_GROWTH=1 -s NODERAWFS=1 -s USE_PTHREADS=1" + LINKFORSHARED="-s PROXY_TO_PTHREAD=1 -s EXIT_RUNTIME=1" CFLAGS_NODIST="$CFLAGS_NODIST -pthread" + if test "$Py_DEBUG" = 'true'; then + LDFLAGS_NODIST="$LDFLAGS_NODIST -s ASSERTIONS=1" + LINKFORSHARED="$LINKFORSHARED -gseparate-dwarf --emit-symbol-map" + else + LINKFORSHARED="$LINKFORSHARED -O2 -gseparate-dwarf" + fi ], [WASI/*], [ AC_DEFINE([_WASI_EMULATED_SIGNAL], [1], [Define to 1 if you want to emulate signals on WASI]) @@ -2880,6 +2905,10 @@ then Linux*|GNU*|QNX*|VxWorks*|Haiku*) LDSHARED='$(CC) -shared' LDCXXSHARED='$(CXX) -shared';; + Emscripten*) + LDSHARED='$(CC) -shared -s SIDE_MODULE=1' + LDCXXSHARED='$(CXX) -shared -s SIDE_MODULE=1' + ;; FreeBSD*) if [[ "`$CC -dM -E - = 1.2.0], [ ], [have_zlib=no]) ]) +if test "$have_zlib" = "yes" -a "$ac_sys_system" = "Emscripten" -a "$ZLIB_LIBS" = "-lz"; then + ZLIB_LIBS="-s USE_ZLIB=1" +fi + dnl binascii can use zlib for optimized crc32. AS_VAR_IF([have_zlib], [yes], [ BINASCII_CFLAGS="-DUSE_ZLIB_CRC32 $ZLIB_CFLAGS" @@ -4372,6 +4405,11 @@ PKG_CHECK_MODULES([BZIP2], [bzip2], [have_bzip2=yes], [ ], [have_bzip2=no]) ]) +if test "$have_bzip2" = "yes" -a "$ac_sys_system" = "Emscripten" -a "$BZIP2_LIBS" = "-lbz2"; then + BZIP2_LIBS="-s USE_BZIP2=1" +fi + + PKG_CHECK_MODULES([LIBLZMA], [liblzma], [have_liblzma=yes], [ AC_CHECK_HEADERS([lzma.h], [ WITH_SAVE_ENV([ diff --git a/setup.py b/setup.py index c3cf2417bc429..070ae9822bd5e 100644 --- a/setup.py +++ b/setup.py @@ -84,10 +84,15 @@ def get_platform(): MACOS = (HOST_PLATFORM == 'darwin') AIX = (HOST_PLATFORM.startswith('aix')) VXWORKS = ('vxworks' in HOST_PLATFORM) +EMSCRIPTEN = HOST_PLATFORM == 'emscripten-wasm32' CC = os.environ.get("CC") if not CC: CC = sysconfig.get_config_var("CC") +if EMSCRIPTEN: + # emcc is a Python script from a different Python interpreter. + os.environ.pop("PYTHONPATH", None) + SUMMARY = """ Python is an interpreted, interactive, object-oriented programming From webhook-mailer at python.org Tue Mar 22 07:39:11 2022 From: webhook-mailer at python.org (pablogsal) Date: Tue, 22 Mar 2022 11:39:11 -0000 Subject: [Python-checkins] bpo-46838: Syntax error improvements for function definitions (GH-31590) Message-ID: https://github.com/python/cpython/commit/7d810b6a4eab6eba689acc5bb05f85515478d690 commit: 7d810b6a4eab6eba689acc5bb05f85515478d690 branch: main author: Pablo Galindo Salgado committer: pablogsal date: 2022-03-22T11:38:41Z summary: bpo-46838: Syntax error improvements for function definitions (GH-31590) files: A Misc/NEWS.d/next/Core and Builtins/2022-02-25-22-42-30.bpo-46838.RB6kEy.rst M Grammar/python.gram M Lib/test/test_syntax.py M Parser/parser.c diff --git a/Grammar/python.gram b/Grammar/python.gram index c0a64696e85dc..696f6a11191e1 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -306,14 +306,16 @@ slash_with_default[SlashWithDefault*]: | a=param_no_default* b=param_with_default+ '/' &')' { _PyPegen_slash_with_default(p, (asdl_arg_seq *)a, b) } star_etc[StarEtc*]: + | invalid_star_etc | '*' a=param_no_default b=param_maybe_default* c=[kwds] { _PyPegen_star_etc(p, a, b, c) } | '*' ',' b=param_maybe_default+ c=[kwds] { _PyPegen_star_etc(p, NULL, b, c) } | a=kwds { _PyPegen_star_etc(p, NULL, NULL, a) } - | invalid_star_etc -kwds[arg_ty]: '**' a=param_no_default { a } +kwds[arg_ty]: + | invalid_kwds + | '**' a=param_no_default { a } # One parameter. This *includes* a following comma and type comment. # @@ -339,7 +341,7 @@ param_maybe_default[NameDefaultPair*]: | a=param c=default? tc=TYPE_COMMENT? &')' { _PyPegen_name_default_pair(p, a, c, tc) } param[arg_ty]: a=NAME b=annotation? { _PyAST_arg(a->v.Name.id, b, NULL, EXTRA) } annotation[expr_ty]: ':' a=expression { a } -default[expr_ty]: '=' a=expression { a } +default[expr_ty]: '=' a=expression { a } | invalid_default # If statement # ------------ @@ -836,14 +838,16 @@ lambda_slash_with_default[SlashWithDefault*]: | a=lambda_param_no_default* b=lambda_param_with_default+ '/' &':' { _PyPegen_slash_with_default(p, (asdl_arg_seq *)a, b) } lambda_star_etc[StarEtc*]: + | invalid_lambda_star_etc | '*' a=lambda_param_no_default b=lambda_param_maybe_default* c=[lambda_kwds] { _PyPegen_star_etc(p, a, b, c) } | '*' ',' b=lambda_param_maybe_default+ c=[lambda_kwds] { _PyPegen_star_etc(p, NULL, b, c) } | a=lambda_kwds { _PyPegen_star_etc(p, NULL, NULL, a) } - | invalid_lambda_star_etc -lambda_kwds[arg_ty]: '**' a=lambda_param_no_default { a } +lambda_kwds[arg_ty]: + | invalid_lambda_kwds + | '**' a=lambda_param_no_default { a } lambda_param_no_default[arg_ty]: | a=lambda_param ',' { a } @@ -1151,6 +1155,26 @@ invalid_parameters: RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "non-default argument follows default argument") } | param_no_default* a='(' param_no_default+ ','? b=')' { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "Function parameters cannot be parenthesized") } + | a="/" ',' { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "at least one argument must precede /") } + | (slash_no_default | slash_with_default) param_maybe_default* a='/' { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "/ may appear only once") } + | (slash_no_default | slash_with_default)? param_maybe_default* '*' (',' | param_no_default) param_maybe_default* a='/' { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "/ must be ahead of *") } + | param_maybe_default+ '/' a='*' { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "expected comma between / and *") } +invalid_default: + | a='=' &(')'|',') { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "expected default value expression") } +invalid_star_etc: + | a='*' (')' | ',' (')' | '**')) { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "named arguments must follow bare *") } + | '*' ',' TYPE_COMMENT { RAISE_SYNTAX_ERROR("bare * has associated type comment") } + | '*' param a='=' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "var-positional argument cannot have default value") } + | '*' (param_no_default | ',') param_maybe_default* a='*' (param_no_default | ',') { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "* argument may appear only once") } +invalid_kwds: + | '**' param a='=' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "var-keyword argument cannot have default value") } + | '**' param ',' a=param { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "arguments cannot follow var-keyword argument") } + | '**' param ',' a[Token*]=('*'|'**'|'/') { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "arguments cannot follow var-keyword argument") } invalid_parameters_helper: # This is only there to avoid type errors | a=slash_with_default { _PyPegen_singleton_seq(p, a) } | param_with_default+ @@ -1159,14 +1183,26 @@ invalid_lambda_parameters: RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "non-default argument follows default argument") } | lambda_param_no_default* a='(' ','.lambda_param+ ','? b=')' { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "Lambda expression parameters cannot be parenthesized") } + | a="/" ',' { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "at least one argument must precede /") } + | (lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* a='/' { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "/ may appear only once") } + | (lambda_slash_no_default | lambda_slash_with_default)? lambda_param_maybe_default* '*' (',' | lambda_param_no_default) lambda_param_maybe_default* a='/' { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "/ must be ahead of *") } + | lambda_param_maybe_default+ '/' a='*' { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "expected comma between / and *") } invalid_lambda_parameters_helper: | a=lambda_slash_with_default { _PyPegen_singleton_seq(p, a) } | lambda_param_with_default+ -invalid_star_etc: - | a='*' (')' | ',' (')' | '**')) { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "named arguments must follow bare *") } - | '*' ',' TYPE_COMMENT { RAISE_SYNTAX_ERROR("bare * has associated type comment") } invalid_lambda_star_etc: | '*' (':' | ',' (':' | '**')) { RAISE_SYNTAX_ERROR("named arguments must follow bare *") } + | '*' lambda_param a='=' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "var-positional argument cannot have default value") } + | '*' (lambda_param_no_default | ',') lambda_param_maybe_default* a='*' (lambda_param_no_default | ',') { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "* argument may appear only once") } +invalid_lambda_kwds: + | '**' lambda_param a='=' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "var-keyword argument cannot have default value") } + | '**' lambda_param ',' a=lambda_param { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "arguments cannot follow var-keyword argument") } + | '**' lambda_param ',' a[Token*]=('*'|'**'|'/') { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "arguments cannot follow var-keyword argument") } invalid_double_type_comments: | TYPE_COMMENT NEWLINE TYPE_COMMENT NEWLINE INDENT { RAISE_SYNTAX_ERROR("Cannot have two type comments on def") } @@ -1269,4 +1305,4 @@ invalid_kvpair: | a=expression !(':') { RAISE_ERROR_KNOWN_LOCATION(p, PyExc_SyntaxError, a->lineno, a->end_col_offset - 1, a->end_lineno, -1, "':' expected after dictionary key") } | expression ':' a='*' bitwise_or { RAISE_SYNTAX_ERROR_STARTING_FROM(a, "cannot use a starred expression in a dictionary value") } - | expression a=':' {RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "expression expected after dictionary key and ':'") } + | expression a=':' {RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "expression expected after dictionary key and ':'") } \ No newline at end of file diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 5134dcbe6521c..5f16a159f13d3 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -351,6 +351,210 @@ Traceback (most recent call last): SyntaxError: invalid syntax +>>> def foo(/,a,b=,c): +... pass +Traceback (most recent call last): +SyntaxError: at least one argument must precede / + +>>> def foo(a,/,/,b,c): +... pass +Traceback (most recent call last): +SyntaxError: / may appear only once + +>>> def foo(a,/,a1,/,b,c): +... pass +Traceback (most recent call last): +SyntaxError: / may appear only once + +>>> def foo(a=1,/,/,*b,/,c): +... pass +Traceback (most recent call last): +SyntaxError: / may appear only once + +>>> def foo(a,/,a1=1,/,b,c): +... pass +Traceback (most recent call last): +SyntaxError: / may appear only once + +>>> def foo(a,*b,c,/,d,e): +... pass +Traceback (most recent call last): +SyntaxError: / must be ahead of * + +>>> def foo(a=1,*b,c=3,/,d,e): +... pass +Traceback (most recent call last): +SyntaxError: / must be ahead of * + +>>> def foo(a,*b=3,c): +... pass +Traceback (most recent call last): +SyntaxError: var-positional argument cannot have default value + +>>> def foo(a,*b: int=,c): +... pass +Traceback (most recent call last): +SyntaxError: var-positional argument cannot have default value + +>>> def foo(a,**b=3): +... pass +Traceback (most recent call last): +SyntaxError: var-keyword argument cannot have default value + +>>> def foo(a,**b: int=3): +... pass +Traceback (most recent call last): +SyntaxError: var-keyword argument cannot have default value + +>>> def foo(a,*a, b, **c, d): +... pass +Traceback (most recent call last): +SyntaxError: arguments cannot follow var-keyword argument + +>>> def foo(a,*a, b, **c, d=4): +... pass +Traceback (most recent call last): +SyntaxError: arguments cannot follow var-keyword argument + +>>> def foo(a,*a, b, **c, *d): +... pass +Traceback (most recent call last): +SyntaxError: arguments cannot follow var-keyword argument + +>>> def foo(a,*a, b, **c, **d): +... pass +Traceback (most recent call last): +SyntaxError: arguments cannot follow var-keyword argument + +>>> def foo(a=1,/,**b,/,c): +... pass +Traceback (most recent call last): +SyntaxError: arguments cannot follow var-keyword argument + +>>> def foo(*b,*d): +... pass +Traceback (most recent call last): +SyntaxError: * argument may appear only once + +>>> def foo(a,*b,c,*d,*e,c): +... pass +Traceback (most recent call last): +SyntaxError: * argument may appear only once + +>>> def foo(a,b,/,c,*b,c,*d,*e,c): +... pass +Traceback (most recent call last): +SyntaxError: * argument may appear only once + +>>> def foo(a,b,/,c,*b,c,*d,**e): +... pass +Traceback (most recent call last): +SyntaxError: * argument may appear only once + +>>> def foo(a=1,/*,b,c): +... pass +Traceback (most recent call last): +SyntaxError: expected comma between / and * + +>>> def foo(a=1,d=,c): +... pass +Traceback (most recent call last): +SyntaxError: expected default value expression + +>>> def foo(a,d=,c): +... pass +Traceback (most recent call last): +SyntaxError: expected default value expression + +>>> def foo(a,d: int=,c): +... pass +Traceback (most recent call last): +SyntaxError: expected default value expression + +>>> lambda /,a,b,c: None +Traceback (most recent call last): +SyntaxError: at least one argument must precede / + +>>> lambda a,/,/,b,c: None +Traceback (most recent call last): +SyntaxError: / may appear only once + +>>> lambda a,/,a1,/,b,c: None +Traceback (most recent call last): +SyntaxError: / may appear only once + +>>> lambda a=1,/,/,*b,/,c: None +Traceback (most recent call last): +SyntaxError: / may appear only once + +>>> lambda a,/,a1=1,/,b,c: None +Traceback (most recent call last): +SyntaxError: / may appear only once + +>>> lambda a,*b,c,/,d,e: None +Traceback (most recent call last): +SyntaxError: / must be ahead of * + +>>> lambda a=1,*b,c=3,/,d,e: None +Traceback (most recent call last): +SyntaxError: / must be ahead of * + +>>> lambda a=1,/*,b,c: None +Traceback (most recent call last): +SyntaxError: expected comma between / and * + +>>> lambda a,*b=3,c: None +Traceback (most recent call last): +SyntaxError: var-positional argument cannot have default value + +>>> lambda a,**b=3: None +Traceback (most recent call last): +SyntaxError: var-keyword argument cannot have default value + +>>> lambda a, *a, b, **c, d: None +Traceback (most recent call last): +SyntaxError: arguments cannot follow var-keyword argument + +>>> lambda a,*a, b, **c, d=4: None +Traceback (most recent call last): +SyntaxError: arguments cannot follow var-keyword argument + +>>> lambda a,*a, b, **c, *d: None +Traceback (most recent call last): +SyntaxError: arguments cannot follow var-keyword argument + +>>> lambda a,*a, b, **c, **d: None +Traceback (most recent call last): +SyntaxError: arguments cannot follow var-keyword argument + +>>> lambda a=1,/,**b,/,c: None +Traceback (most recent call last): +SyntaxError: arguments cannot follow var-keyword argument + +>>> lambda *b,*d: None +Traceback (most recent call last): +SyntaxError: * argument may appear only once + +>>> lambda a,*b,c,*d,*e,c: None +Traceback (most recent call last): +SyntaxError: * argument may appear only once + +>>> lambda a,b,/,c,*b,c,*d,*e,c: None +Traceback (most recent call last): +SyntaxError: * argument may appear only once + +>>> lambda a,b,/,c,*b,c,*d,**e: None +Traceback (most recent call last): +SyntaxError: * argument may appear only once + +>>> lambda a=1,d=,c: None +Traceback (most recent call last): +SyntaxError: expected default value expression + +>>> lambda a,d=,c: None +Traceback (most recent call last): +SyntaxError: expected default value expression + >>> import ast; ast.parse(''' ... def f( ... *, # type: int diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-25-22-42-30.bpo-46838.RB6kEy.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-25-22-42-30.bpo-46838.RB6kEy.rst new file mode 100644 index 0000000000000..aa3cbca0cf9f2 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-02-25-22-42-30.bpo-46838.RB6kEy.rst @@ -0,0 +1,2 @@ +Improve syntax errors for incorrect function definitions. Patch by Pablo +Galindo diff --git a/Parser/parser.c b/Parser/parser.c index 7f2d125996d2f..8595efba73309 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -265,259 +265,285 @@ static char *soft_keywords[] = { #define invalid_comprehension_type 1189 #define invalid_dict_comprehension_type 1190 #define invalid_parameters_type 1191 -#define invalid_parameters_helper_type 1192 -#define invalid_lambda_parameters_type 1193 -#define invalid_lambda_parameters_helper_type 1194 -#define invalid_star_etc_type 1195 -#define invalid_lambda_star_etc_type 1196 -#define invalid_double_type_comments_type 1197 -#define invalid_with_item_type 1198 -#define invalid_for_target_type 1199 -#define invalid_group_type 1200 -#define invalid_import_from_targets_type 1201 -#define invalid_with_stmt_type 1202 -#define invalid_with_stmt_indent_type 1203 -#define invalid_try_stmt_type 1204 -#define invalid_except_stmt_type 1205 -#define invalid_finally_stmt_type 1206 -#define invalid_except_stmt_indent_type 1207 -#define invalid_except_star_stmt_indent_type 1208 -#define invalid_match_stmt_type 1209 -#define invalid_case_block_type 1210 -#define invalid_as_pattern_type 1211 -#define invalid_class_pattern_type 1212 -#define invalid_class_argument_pattern_type 1213 -#define invalid_if_stmt_type 1214 -#define invalid_elif_stmt_type 1215 -#define invalid_else_stmt_type 1216 -#define invalid_while_stmt_type 1217 -#define invalid_for_stmt_type 1218 -#define invalid_def_raw_type 1219 -#define invalid_class_def_raw_type 1220 -#define invalid_double_starred_kvpairs_type 1221 -#define invalid_kvpair_type 1222 -#define _loop0_1_type 1223 -#define _loop0_2_type 1224 -#define _loop1_3_type 1225 -#define _loop0_5_type 1226 -#define _gather_4_type 1227 -#define _tmp_6_type 1228 -#define _tmp_7_type 1229 -#define _tmp_8_type 1230 -#define _tmp_9_type 1231 -#define _tmp_10_type 1232 -#define _tmp_11_type 1233 -#define _tmp_12_type 1234 -#define _tmp_13_type 1235 -#define _loop1_14_type 1236 -#define _tmp_15_type 1237 -#define _tmp_16_type 1238 -#define _tmp_17_type 1239 -#define _loop0_19_type 1240 -#define _gather_18_type 1241 -#define _loop0_21_type 1242 -#define _gather_20_type 1243 -#define _tmp_22_type 1244 -#define _tmp_23_type 1245 -#define _loop0_24_type 1246 -#define _loop1_25_type 1247 -#define _loop0_27_type 1248 -#define _gather_26_type 1249 -#define _tmp_28_type 1250 -#define _loop0_30_type 1251 -#define _gather_29_type 1252 -#define _tmp_31_type 1253 -#define _loop1_32_type 1254 -#define _tmp_33_type 1255 -#define _tmp_34_type 1256 -#define _tmp_35_type 1257 -#define _loop0_36_type 1258 -#define _loop0_37_type 1259 -#define _loop0_38_type 1260 -#define _loop1_39_type 1261 -#define _loop0_40_type 1262 -#define _loop1_41_type 1263 -#define _loop1_42_type 1264 -#define _loop1_43_type 1265 -#define _loop0_44_type 1266 -#define _loop1_45_type 1267 -#define _loop0_46_type 1268 -#define _loop1_47_type 1269 -#define _loop0_48_type 1270 -#define _loop1_49_type 1271 -#define _loop0_51_type 1272 -#define _gather_50_type 1273 -#define _loop0_53_type 1274 -#define _gather_52_type 1275 -#define _loop0_55_type 1276 -#define _gather_54_type 1277 -#define _loop0_57_type 1278 -#define _gather_56_type 1279 -#define _tmp_58_type 1280 -#define _loop1_59_type 1281 -#define _loop1_60_type 1282 -#define _tmp_61_type 1283 -#define _tmp_62_type 1284 -#define _loop1_63_type 1285 -#define _loop0_65_type 1286 -#define _gather_64_type 1287 -#define _tmp_66_type 1288 -#define _tmp_67_type 1289 -#define _tmp_68_type 1290 -#define _tmp_69_type 1291 -#define _loop0_71_type 1292 -#define _gather_70_type 1293 -#define _loop0_73_type 1294 -#define _gather_72_type 1295 -#define _tmp_74_type 1296 -#define _loop0_76_type 1297 -#define _gather_75_type 1298 -#define _loop0_78_type 1299 -#define _gather_77_type 1300 -#define _loop1_79_type 1301 -#define _loop1_80_type 1302 -#define _loop0_82_type 1303 -#define _gather_81_type 1304 -#define _loop1_83_type 1305 -#define _loop1_84_type 1306 -#define _loop1_85_type 1307 -#define _tmp_86_type 1308 -#define _loop0_88_type 1309 -#define _gather_87_type 1310 -#define _tmp_89_type 1311 -#define _tmp_90_type 1312 -#define _tmp_91_type 1313 -#define _tmp_92_type 1314 -#define _tmp_93_type 1315 -#define _loop0_94_type 1316 -#define _loop0_95_type 1317 -#define _loop0_96_type 1318 -#define _loop1_97_type 1319 -#define _loop0_98_type 1320 -#define _loop1_99_type 1321 -#define _loop1_100_type 1322 -#define _loop1_101_type 1323 -#define _loop0_102_type 1324 -#define _loop1_103_type 1325 -#define _loop0_104_type 1326 -#define _loop1_105_type 1327 -#define _loop0_106_type 1328 -#define _loop1_107_type 1329 -#define _loop1_108_type 1330 -#define _tmp_109_type 1331 -#define _loop0_111_type 1332 -#define _gather_110_type 1333 -#define _loop1_112_type 1334 -#define _loop0_113_type 1335 -#define _loop0_114_type 1336 -#define _tmp_115_type 1337 -#define _loop0_117_type 1338 -#define _gather_116_type 1339 -#define _tmp_118_type 1340 -#define _loop0_120_type 1341 -#define _gather_119_type 1342 -#define _loop0_122_type 1343 -#define _gather_121_type 1344 -#define _loop0_124_type 1345 -#define _gather_123_type 1346 -#define _loop0_126_type 1347 -#define _gather_125_type 1348 -#define _loop0_127_type 1349 -#define _loop0_129_type 1350 -#define _gather_128_type 1351 -#define _loop1_130_type 1352 -#define _tmp_131_type 1353 -#define _loop0_133_type 1354 -#define _gather_132_type 1355 -#define _loop0_135_type 1356 -#define _gather_134_type 1357 -#define _loop0_137_type 1358 -#define _gather_136_type 1359 -#define _loop0_139_type 1360 -#define _gather_138_type 1361 -#define _loop0_141_type 1362 -#define _gather_140_type 1363 -#define _tmp_142_type 1364 -#define _tmp_143_type 1365 -#define _tmp_144_type 1366 -#define _tmp_145_type 1367 -#define _tmp_146_type 1368 -#define _tmp_147_type 1369 -#define _tmp_148_type 1370 -#define _tmp_149_type 1371 -#define _tmp_150_type 1372 -#define _loop0_151_type 1373 -#define _loop0_152_type 1374 -#define _loop0_153_type 1375 -#define _tmp_154_type 1376 -#define _tmp_155_type 1377 -#define _tmp_156_type 1378 -#define _tmp_157_type 1379 -#define _loop0_158_type 1380 -#define _loop0_159_type 1381 -#define _loop1_160_type 1382 -#define _loop1_161_type 1383 -#define _loop0_162_type 1384 -#define _loop0_163_type 1385 -#define _loop0_165_type 1386 -#define _gather_164_type 1387 -#define _loop1_166_type 1388 -#define _tmp_167_type 1389 -#define _tmp_168_type 1390 -#define _tmp_169_type 1391 -#define _loop0_171_type 1392 -#define _gather_170_type 1393 -#define _loop0_173_type 1394 -#define _gather_172_type 1395 -#define _loop0_175_type 1396 -#define _gather_174_type 1397 -#define _loop0_177_type 1398 -#define _gather_176_type 1399 -#define _tmp_178_type 1400 -#define _loop0_179_type 1401 -#define _tmp_180_type 1402 -#define _loop0_181_type 1403 -#define _tmp_182_type 1404 -#define _tmp_183_type 1405 -#define _tmp_184_type 1406 -#define _tmp_185_type 1407 -#define _tmp_186_type 1408 -#define _tmp_187_type 1409 -#define _tmp_188_type 1410 -#define _tmp_189_type 1411 -#define _loop0_191_type 1412 -#define _gather_190_type 1413 -#define _tmp_192_type 1414 -#define _tmp_193_type 1415 -#define _tmp_194_type 1416 -#define _tmp_195_type 1417 -#define _tmp_196_type 1418 -#define _tmp_197_type 1419 -#define _tmp_198_type 1420 -#define _tmp_199_type 1421 -#define _tmp_200_type 1422 -#define _tmp_201_type 1423 -#define _tmp_202_type 1424 -#define _tmp_203_type 1425 -#define _tmp_204_type 1426 -#define _tmp_205_type 1427 -#define _tmp_206_type 1428 -#define _tmp_207_type 1429 -#define _tmp_208_type 1430 -#define _tmp_209_type 1431 -#define _tmp_210_type 1432 -#define _tmp_211_type 1433 -#define _tmp_212_type 1434 -#define _tmp_213_type 1435 -#define _tmp_214_type 1436 -#define _tmp_215_type 1437 -#define _tmp_216_type 1438 -#define _tmp_217_type 1439 -#define _tmp_218_type 1440 -#define _tmp_219_type 1441 -#define _tmp_220_type 1442 -#define _loop1_221_type 1443 -#define _loop1_222_type 1444 +#define invalid_default_type 1192 +#define invalid_star_etc_type 1193 +#define invalid_kwds_type 1194 +#define invalid_parameters_helper_type 1195 +#define invalid_lambda_parameters_type 1196 +#define invalid_lambda_parameters_helper_type 1197 +#define invalid_lambda_star_etc_type 1198 +#define invalid_lambda_kwds_type 1199 +#define invalid_double_type_comments_type 1200 +#define invalid_with_item_type 1201 +#define invalid_for_target_type 1202 +#define invalid_group_type 1203 +#define invalid_import_from_targets_type 1204 +#define invalid_with_stmt_type 1205 +#define invalid_with_stmt_indent_type 1206 +#define invalid_try_stmt_type 1207 +#define invalid_except_stmt_type 1208 +#define invalid_finally_stmt_type 1209 +#define invalid_except_stmt_indent_type 1210 +#define invalid_except_star_stmt_indent_type 1211 +#define invalid_match_stmt_type 1212 +#define invalid_case_block_type 1213 +#define invalid_as_pattern_type 1214 +#define invalid_class_pattern_type 1215 +#define invalid_class_argument_pattern_type 1216 +#define invalid_if_stmt_type 1217 +#define invalid_elif_stmt_type 1218 +#define invalid_else_stmt_type 1219 +#define invalid_while_stmt_type 1220 +#define invalid_for_stmt_type 1221 +#define invalid_def_raw_type 1222 +#define invalid_class_def_raw_type 1223 +#define invalid_double_starred_kvpairs_type 1224 +#define invalid_kvpair_type 1225 +#define _loop0_1_type 1226 +#define _loop0_2_type 1227 +#define _loop1_3_type 1228 +#define _loop0_5_type 1229 +#define _gather_4_type 1230 +#define _tmp_6_type 1231 +#define _tmp_7_type 1232 +#define _tmp_8_type 1233 +#define _tmp_9_type 1234 +#define _tmp_10_type 1235 +#define _tmp_11_type 1236 +#define _tmp_12_type 1237 +#define _tmp_13_type 1238 +#define _loop1_14_type 1239 +#define _tmp_15_type 1240 +#define _tmp_16_type 1241 +#define _tmp_17_type 1242 +#define _loop0_19_type 1243 +#define _gather_18_type 1244 +#define _loop0_21_type 1245 +#define _gather_20_type 1246 +#define _tmp_22_type 1247 +#define _tmp_23_type 1248 +#define _loop0_24_type 1249 +#define _loop1_25_type 1250 +#define _loop0_27_type 1251 +#define _gather_26_type 1252 +#define _tmp_28_type 1253 +#define _loop0_30_type 1254 +#define _gather_29_type 1255 +#define _tmp_31_type 1256 +#define _loop1_32_type 1257 +#define _tmp_33_type 1258 +#define _tmp_34_type 1259 +#define _tmp_35_type 1260 +#define _loop0_36_type 1261 +#define _loop0_37_type 1262 +#define _loop0_38_type 1263 +#define _loop1_39_type 1264 +#define _loop0_40_type 1265 +#define _loop1_41_type 1266 +#define _loop1_42_type 1267 +#define _loop1_43_type 1268 +#define _loop0_44_type 1269 +#define _loop1_45_type 1270 +#define _loop0_46_type 1271 +#define _loop1_47_type 1272 +#define _loop0_48_type 1273 +#define _loop1_49_type 1274 +#define _loop0_51_type 1275 +#define _gather_50_type 1276 +#define _loop0_53_type 1277 +#define _gather_52_type 1278 +#define _loop0_55_type 1279 +#define _gather_54_type 1280 +#define _loop0_57_type 1281 +#define _gather_56_type 1282 +#define _tmp_58_type 1283 +#define _loop1_59_type 1284 +#define _loop1_60_type 1285 +#define _tmp_61_type 1286 +#define _tmp_62_type 1287 +#define _loop1_63_type 1288 +#define _loop0_65_type 1289 +#define _gather_64_type 1290 +#define _tmp_66_type 1291 +#define _tmp_67_type 1292 +#define _tmp_68_type 1293 +#define _tmp_69_type 1294 +#define _loop0_71_type 1295 +#define _gather_70_type 1296 +#define _loop0_73_type 1297 +#define _gather_72_type 1298 +#define _tmp_74_type 1299 +#define _loop0_76_type 1300 +#define _gather_75_type 1301 +#define _loop0_78_type 1302 +#define _gather_77_type 1303 +#define _loop1_79_type 1304 +#define _loop1_80_type 1305 +#define _loop0_82_type 1306 +#define _gather_81_type 1307 +#define _loop1_83_type 1308 +#define _loop1_84_type 1309 +#define _loop1_85_type 1310 +#define _tmp_86_type 1311 +#define _loop0_88_type 1312 +#define _gather_87_type 1313 +#define _tmp_89_type 1314 +#define _tmp_90_type 1315 +#define _tmp_91_type 1316 +#define _tmp_92_type 1317 +#define _tmp_93_type 1318 +#define _loop0_94_type 1319 +#define _loop0_95_type 1320 +#define _loop0_96_type 1321 +#define _loop1_97_type 1322 +#define _loop0_98_type 1323 +#define _loop1_99_type 1324 +#define _loop1_100_type 1325 +#define _loop1_101_type 1326 +#define _loop0_102_type 1327 +#define _loop1_103_type 1328 +#define _loop0_104_type 1329 +#define _loop1_105_type 1330 +#define _loop0_106_type 1331 +#define _loop1_107_type 1332 +#define _loop1_108_type 1333 +#define _tmp_109_type 1334 +#define _loop0_111_type 1335 +#define _gather_110_type 1336 +#define _loop1_112_type 1337 +#define _loop0_113_type 1338 +#define _loop0_114_type 1339 +#define _tmp_115_type 1340 +#define _loop0_117_type 1341 +#define _gather_116_type 1342 +#define _tmp_118_type 1343 +#define _loop0_120_type 1344 +#define _gather_119_type 1345 +#define _loop0_122_type 1346 +#define _gather_121_type 1347 +#define _loop0_124_type 1348 +#define _gather_123_type 1349 +#define _loop0_126_type 1350 +#define _gather_125_type 1351 +#define _loop0_127_type 1352 +#define _loop0_129_type 1353 +#define _gather_128_type 1354 +#define _loop1_130_type 1355 +#define _tmp_131_type 1356 +#define _loop0_133_type 1357 +#define _gather_132_type 1358 +#define _loop0_135_type 1359 +#define _gather_134_type 1360 +#define _loop0_137_type 1361 +#define _gather_136_type 1362 +#define _loop0_139_type 1363 +#define _gather_138_type 1364 +#define _loop0_141_type 1365 +#define _gather_140_type 1366 +#define _tmp_142_type 1367 +#define _tmp_143_type 1368 +#define _tmp_144_type 1369 +#define _tmp_145_type 1370 +#define _tmp_146_type 1371 +#define _tmp_147_type 1372 +#define _tmp_148_type 1373 +#define _tmp_149_type 1374 +#define _tmp_150_type 1375 +#define _loop0_151_type 1376 +#define _loop0_152_type 1377 +#define _loop0_153_type 1378 +#define _tmp_154_type 1379 +#define _tmp_155_type 1380 +#define _tmp_156_type 1381 +#define _tmp_157_type 1382 +#define _loop0_158_type 1383 +#define _loop0_159_type 1384 +#define _loop1_160_type 1385 +#define _tmp_161_type 1386 +#define _loop0_162_type 1387 +#define _tmp_163_type 1388 +#define _loop0_164_type 1389 +#define _tmp_165_type 1390 +#define _loop0_166_type 1391 +#define _loop1_167_type 1392 +#define _tmp_168_type 1393 +#define _tmp_169_type 1394 +#define _tmp_170_type 1395 +#define _loop0_171_type 1396 +#define _tmp_172_type 1397 +#define _tmp_173_type 1398 +#define _loop1_174_type 1399 +#define _loop0_175_type 1400 +#define _loop0_176_type 1401 +#define _loop0_178_type 1402 +#define _gather_177_type 1403 +#define _tmp_179_type 1404 +#define _loop0_180_type 1405 +#define _tmp_181_type 1406 +#define _loop0_182_type 1407 +#define _tmp_183_type 1408 +#define _loop0_184_type 1409 +#define _loop1_185_type 1410 +#define _loop1_186_type 1411 +#define _tmp_187_type 1412 +#define _tmp_188_type 1413 +#define _loop0_189_type 1414 +#define _tmp_190_type 1415 +#define _tmp_191_type 1416 +#define _tmp_192_type 1417 +#define _loop0_194_type 1418 +#define _gather_193_type 1419 +#define _loop0_196_type 1420 +#define _gather_195_type 1421 +#define _loop0_198_type 1422 +#define _gather_197_type 1423 +#define _loop0_200_type 1424 +#define _gather_199_type 1425 +#define _tmp_201_type 1426 +#define _loop0_202_type 1427 +#define _tmp_203_type 1428 +#define _loop0_204_type 1429 +#define _tmp_205_type 1430 +#define _tmp_206_type 1431 +#define _tmp_207_type 1432 +#define _tmp_208_type 1433 +#define _tmp_209_type 1434 +#define _tmp_210_type 1435 +#define _tmp_211_type 1436 +#define _tmp_212_type 1437 +#define _loop0_214_type 1438 +#define _gather_213_type 1439 +#define _tmp_215_type 1440 +#define _tmp_216_type 1441 +#define _tmp_217_type 1442 +#define _tmp_218_type 1443 +#define _tmp_219_type 1444 +#define _tmp_220_type 1445 +#define _tmp_221_type 1446 +#define _tmp_222_type 1447 +#define _tmp_223_type 1448 +#define _tmp_224_type 1449 +#define _tmp_225_type 1450 +#define _tmp_226_type 1451 +#define _tmp_227_type 1452 +#define _tmp_228_type 1453 +#define _tmp_229_type 1454 +#define _tmp_230_type 1455 +#define _tmp_231_type 1456 +#define _tmp_232_type 1457 +#define _tmp_233_type 1458 +#define _tmp_234_type 1459 +#define _tmp_235_type 1460 +#define _tmp_236_type 1461 +#define _tmp_237_type 1462 +#define _tmp_238_type 1463 +#define _tmp_239_type 1464 +#define _tmp_240_type 1465 +#define _tmp_241_type 1466 +#define _tmp_242_type 1467 +#define _tmp_243_type 1468 +#define _loop1_244_type 1469 +#define _loop1_245_type 1470 static mod_ty file_rule(Parser *p); static mod_ty interactive_rule(Parser *p); @@ -711,11 +737,14 @@ static void *invalid_block_rule(Parser *p); static void *invalid_comprehension_rule(Parser *p); static void *invalid_dict_comprehension_rule(Parser *p); static void *invalid_parameters_rule(Parser *p); +static void *invalid_default_rule(Parser *p); +static void *invalid_star_etc_rule(Parser *p); +static void *invalid_kwds_rule(Parser *p); static void *invalid_parameters_helper_rule(Parser *p); static void *invalid_lambda_parameters_rule(Parser *p); static void *invalid_lambda_parameters_helper_rule(Parser *p); -static void *invalid_star_etc_rule(Parser *p); static void *invalid_lambda_star_etc_rule(Parser *p); +static void *invalid_lambda_kwds_rule(Parser *p); static void *invalid_double_type_comments_rule(Parser *p); static void *invalid_with_item_rule(Parser *p); static void *invalid_for_target_rule(Parser *p); @@ -902,50 +931,50 @@ static void *_tmp_157_rule(Parser *p); static asdl_seq *_loop0_158_rule(Parser *p); static asdl_seq *_loop0_159_rule(Parser *p); static asdl_seq *_loop1_160_rule(Parser *p); -static asdl_seq *_loop1_161_rule(Parser *p); +static void *_tmp_161_rule(Parser *p); static asdl_seq *_loop0_162_rule(Parser *p); -static asdl_seq *_loop0_163_rule(Parser *p); -static asdl_seq *_loop0_165_rule(Parser *p); -static asdl_seq *_gather_164_rule(Parser *p); -static asdl_seq *_loop1_166_rule(Parser *p); -static void *_tmp_167_rule(Parser *p); +static void *_tmp_163_rule(Parser *p); +static asdl_seq *_loop0_164_rule(Parser *p); +static void *_tmp_165_rule(Parser *p); +static asdl_seq *_loop0_166_rule(Parser *p); +static asdl_seq *_loop1_167_rule(Parser *p); static void *_tmp_168_rule(Parser *p); static void *_tmp_169_rule(Parser *p); +static void *_tmp_170_rule(Parser *p); static asdl_seq *_loop0_171_rule(Parser *p); -static asdl_seq *_gather_170_rule(Parser *p); -static asdl_seq *_loop0_173_rule(Parser *p); -static asdl_seq *_gather_172_rule(Parser *p); +static void *_tmp_172_rule(Parser *p); +static void *_tmp_173_rule(Parser *p); +static asdl_seq *_loop1_174_rule(Parser *p); static asdl_seq *_loop0_175_rule(Parser *p); -static asdl_seq *_gather_174_rule(Parser *p); -static asdl_seq *_loop0_177_rule(Parser *p); -static asdl_seq *_gather_176_rule(Parser *p); -static void *_tmp_178_rule(Parser *p); -static asdl_seq *_loop0_179_rule(Parser *p); -static void *_tmp_180_rule(Parser *p); -static asdl_seq *_loop0_181_rule(Parser *p); -static void *_tmp_182_rule(Parser *p); +static asdl_seq *_loop0_176_rule(Parser *p); +static asdl_seq *_loop0_178_rule(Parser *p); +static asdl_seq *_gather_177_rule(Parser *p); +static void *_tmp_179_rule(Parser *p); +static asdl_seq *_loop0_180_rule(Parser *p); +static void *_tmp_181_rule(Parser *p); +static asdl_seq *_loop0_182_rule(Parser *p); static void *_tmp_183_rule(Parser *p); -static void *_tmp_184_rule(Parser *p); -static void *_tmp_185_rule(Parser *p); -static void *_tmp_186_rule(Parser *p); +static asdl_seq *_loop0_184_rule(Parser *p); +static asdl_seq *_loop1_185_rule(Parser *p); +static asdl_seq *_loop1_186_rule(Parser *p); static void *_tmp_187_rule(Parser *p); static void *_tmp_188_rule(Parser *p); -static void *_tmp_189_rule(Parser *p); -static asdl_seq *_loop0_191_rule(Parser *p); -static asdl_seq *_gather_190_rule(Parser *p); +static asdl_seq *_loop0_189_rule(Parser *p); +static void *_tmp_190_rule(Parser *p); +static void *_tmp_191_rule(Parser *p); static void *_tmp_192_rule(Parser *p); -static void *_tmp_193_rule(Parser *p); -static void *_tmp_194_rule(Parser *p); -static void *_tmp_195_rule(Parser *p); -static void *_tmp_196_rule(Parser *p); -static void *_tmp_197_rule(Parser *p); -static void *_tmp_198_rule(Parser *p); -static void *_tmp_199_rule(Parser *p); -static void *_tmp_200_rule(Parser *p); +static asdl_seq *_loop0_194_rule(Parser *p); +static asdl_seq *_gather_193_rule(Parser *p); +static asdl_seq *_loop0_196_rule(Parser *p); +static asdl_seq *_gather_195_rule(Parser *p); +static asdl_seq *_loop0_198_rule(Parser *p); +static asdl_seq *_gather_197_rule(Parser *p); +static asdl_seq *_loop0_200_rule(Parser *p); +static asdl_seq *_gather_199_rule(Parser *p); static void *_tmp_201_rule(Parser *p); -static void *_tmp_202_rule(Parser *p); +static asdl_seq *_loop0_202_rule(Parser *p); static void *_tmp_203_rule(Parser *p); -static void *_tmp_204_rule(Parser *p); +static asdl_seq *_loop0_204_rule(Parser *p); static void *_tmp_205_rule(Parser *p); static void *_tmp_206_rule(Parser *p); static void *_tmp_207_rule(Parser *p); @@ -954,16 +983,39 @@ static void *_tmp_209_rule(Parser *p); static void *_tmp_210_rule(Parser *p); static void *_tmp_211_rule(Parser *p); static void *_tmp_212_rule(Parser *p); -static void *_tmp_213_rule(Parser *p); -static void *_tmp_214_rule(Parser *p); +static asdl_seq *_loop0_214_rule(Parser *p); +static asdl_seq *_gather_213_rule(Parser *p); static void *_tmp_215_rule(Parser *p); static void *_tmp_216_rule(Parser *p); static void *_tmp_217_rule(Parser *p); static void *_tmp_218_rule(Parser *p); static void *_tmp_219_rule(Parser *p); static void *_tmp_220_rule(Parser *p); -static asdl_seq *_loop1_221_rule(Parser *p); -static asdl_seq *_loop1_222_rule(Parser *p); +static void *_tmp_221_rule(Parser *p); +static void *_tmp_222_rule(Parser *p); +static void *_tmp_223_rule(Parser *p); +static void *_tmp_224_rule(Parser *p); +static void *_tmp_225_rule(Parser *p); +static void *_tmp_226_rule(Parser *p); +static void *_tmp_227_rule(Parser *p); +static void *_tmp_228_rule(Parser *p); +static void *_tmp_229_rule(Parser *p); +static void *_tmp_230_rule(Parser *p); +static void *_tmp_231_rule(Parser *p); +static void *_tmp_232_rule(Parser *p); +static void *_tmp_233_rule(Parser *p); +static void *_tmp_234_rule(Parser *p); +static void *_tmp_235_rule(Parser *p); +static void *_tmp_236_rule(Parser *p); +static void *_tmp_237_rule(Parser *p); +static void *_tmp_238_rule(Parser *p); +static void *_tmp_239_rule(Parser *p); +static void *_tmp_240_rule(Parser *p); +static void *_tmp_241_rule(Parser *p); +static void *_tmp_242_rule(Parser *p); +static void *_tmp_243_rule(Parser *p); +static asdl_seq *_loop1_244_rule(Parser *p); +static asdl_seq *_loop1_245_rule(Parser *p); // file: statements? $ @@ -4863,10 +4915,10 @@ slash_with_default_rule(Parser *p) } // star_etc: +// | invalid_star_etc // | '*' param_no_default param_maybe_default* kwds? // | '*' ',' param_maybe_default+ kwds? // | kwds -// | invalid_star_etc static StarEtc* star_etc_rule(Parser *p) { @@ -4880,6 +4932,25 @@ star_etc_rule(Parser *p) } StarEtc* _res = NULL; int _mark = p->mark; + if (p->call_invalid_rules) { // invalid_star_etc + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_star_etc")); + void *invalid_star_etc_var; + if ( + (invalid_star_etc_var = invalid_star_etc_rule(p)) // invalid_star_etc + ) + { + D(fprintf(stderr, "%*c+ star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_star_etc")); + _res = invalid_star_etc_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_star_etc")); + } { // '*' param_no_default param_maybe_default* kwds? if (p->error_indicator) { p->level--; @@ -4970,32 +5041,13 @@ star_etc_rule(Parser *p) D(fprintf(stderr, "%*c%s star_etc[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwds")); } - if (p->call_invalid_rules) { // invalid_star_etc - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_star_etc")); - void *invalid_star_etc_var; - if ( - (invalid_star_etc_var = invalid_star_etc_rule(p)) // invalid_star_etc - ) - { - D(fprintf(stderr, "%*c+ star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_star_etc")); - _res = invalid_star_etc_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s star_etc[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_star_etc")); - } _res = NULL; done: p->level--; return _res; } -// kwds: '**' param_no_default +// kwds: invalid_kwds | '**' param_no_default static arg_ty kwds_rule(Parser *p) { @@ -5009,6 +5061,25 @@ kwds_rule(Parser *p) } arg_ty _res = NULL; int _mark = p->mark; + if (p->call_invalid_rules) { // invalid_kwds + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> kwds[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_kwds")); + void *invalid_kwds_var; + if ( + (invalid_kwds_var = invalid_kwds_rule(p)) // invalid_kwds + ) + { + D(fprintf(stderr, "%*c+ kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_kwds")); + _res = invalid_kwds_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s kwds[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_kwds")); + } { // '**' param_no_default if (p->error_indicator) { p->level--; @@ -5405,7 +5476,7 @@ annotation_rule(Parser *p) return _res; } -// default: '=' expression +// default: '=' expression | invalid_default static expr_ty default_rule(Parser *p) { @@ -5446,6 +5517,25 @@ default_rule(Parser *p) D(fprintf(stderr, "%*c%s default[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'=' expression")); } + if (p->call_invalid_rules) { // invalid_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_default")); + void *invalid_default_var; + if ( + (invalid_default_var = invalid_default_rule(p)) // invalid_default + ) + { + D(fprintf(stderr, "%*c+ default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_default")); + _res = invalid_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s default[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_default")); + } _res = NULL; done: p->level--; @@ -14612,10 +14702,10 @@ lambda_slash_with_default_rule(Parser *p) } // lambda_star_etc: +// | invalid_lambda_star_etc // | '*' lambda_param_no_default lambda_param_maybe_default* lambda_kwds? // | '*' ',' lambda_param_maybe_default+ lambda_kwds? // | lambda_kwds -// | invalid_lambda_star_etc static StarEtc* lambda_star_etc_rule(Parser *p) { @@ -14629,6 +14719,25 @@ lambda_star_etc_rule(Parser *p) } StarEtc* _res = NULL; int _mark = p->mark; + if (p->call_invalid_rules) { // invalid_lambda_star_etc + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_lambda_star_etc")); + void *invalid_lambda_star_etc_var; + if ( + (invalid_lambda_star_etc_var = invalid_lambda_star_etc_rule(p)) // invalid_lambda_star_etc + ) + { + D(fprintf(stderr, "%*c+ lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_lambda_star_etc")); + _res = invalid_lambda_star_etc_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_lambda_star_etc")); + } { // '*' lambda_param_no_default lambda_param_maybe_default* lambda_kwds? if (p->error_indicator) { p->level--; @@ -14719,32 +14828,13 @@ lambda_star_etc_rule(Parser *p) D(fprintf(stderr, "%*c%s lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_kwds")); } - if (p->call_invalid_rules) { // invalid_lambda_star_etc - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_lambda_star_etc")); - void *invalid_lambda_star_etc_var; - if ( - (invalid_lambda_star_etc_var = invalid_lambda_star_etc_rule(p)) // invalid_lambda_star_etc - ) - { - D(fprintf(stderr, "%*c+ lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_lambda_star_etc")); - _res = invalid_lambda_star_etc_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_lambda_star_etc")); - } _res = NULL; done: p->level--; return _res; } -// lambda_kwds: '**' lambda_param_no_default +// lambda_kwds: invalid_lambda_kwds | '**' lambda_param_no_default static arg_ty lambda_kwds_rule(Parser *p) { @@ -14758,6 +14848,25 @@ lambda_kwds_rule(Parser *p) } arg_ty _res = NULL; int _mark = p->mark; + if (p->call_invalid_rules) { // invalid_lambda_kwds + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> lambda_kwds[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_lambda_kwds")); + void *invalid_lambda_kwds_var; + if ( + (invalid_lambda_kwds_var = invalid_lambda_kwds_rule(p)) // invalid_lambda_kwds + ) + { + D(fprintf(stderr, "%*c+ lambda_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_lambda_kwds")); + _res = invalid_lambda_kwds_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s lambda_kwds[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_lambda_kwds")); + } { // '**' lambda_param_no_default if (p->error_indicator) { p->level--; @@ -19830,6 +19939,10 @@ invalid_dict_comprehension_rule(Parser *p) // invalid_parameters: // | param_no_default* invalid_parameters_helper param_no_default // | param_no_default* '(' param_no_default+ ','? ')' +// | "/" ',' +// | (slash_no_default | slash_with_default) param_maybe_default* '/' +// | [(slash_no_default | slash_with_default)] param_maybe_default* '*' (',' | param_no_default) param_maybe_default* '/' +// | param_maybe_default+ '/' '*' static void * invalid_parameters_rule(Parser *p) { @@ -19910,6 +20023,442 @@ invalid_parameters_rule(Parser *p) D(fprintf(stderr, "%*c%s invalid_parameters[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default* '(' param_no_default+ ','? ')'")); } + { // "/" ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"/\" ','")); + Token * _literal; + Token * a; + if ( + (a = _PyPegen_expect_token(p, 17)) // token='/' + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ invalid_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"/\" ','")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "at least one argument must precede /" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"/\" ','")); + } + { // (slash_no_default | slash_with_default) param_maybe_default* '/' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(slash_no_default | slash_with_default) param_maybe_default* '/'")); + asdl_seq * _loop0_162_var; + void *_tmp_161_var; + Token * a; + if ( + (_tmp_161_var = _tmp_161_rule(p)) // slash_no_default | slash_with_default + && + (_loop0_162_var = _loop0_162_rule(p)) // param_maybe_default* + && + (a = _PyPegen_expect_token(p, 17)) // token='/' + ) + { + D(fprintf(stderr, "%*c+ invalid_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(slash_no_default | slash_with_default) param_maybe_default* '/'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "/ may appear only once" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(slash_no_default | slash_with_default) param_maybe_default* '/'")); + } + { // [(slash_no_default | slash_with_default)] param_maybe_default* '*' (',' | param_no_default) param_maybe_default* '/' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "[(slash_no_default | slash_with_default)] param_maybe_default* '*' (',' | param_no_default) param_maybe_default* '/'")); + Token * _literal; + asdl_seq * _loop0_164_var; + asdl_seq * _loop0_166_var; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + void *_tmp_165_var; + Token * a; + if ( + (_opt_var = _tmp_163_rule(p), !p->error_indicator) // [(slash_no_default | slash_with_default)] + && + (_loop0_164_var = _loop0_164_rule(p)) // param_maybe_default* + && + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (_tmp_165_var = _tmp_165_rule(p)) // ',' | param_no_default + && + (_loop0_166_var = _loop0_166_rule(p)) // param_maybe_default* + && + (a = _PyPegen_expect_token(p, 17)) // token='/' + ) + { + D(fprintf(stderr, "%*c+ invalid_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "[(slash_no_default | slash_with_default)] param_maybe_default* '*' (',' | param_no_default) param_maybe_default* '/'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "/ must be ahead of *" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "[(slash_no_default | slash_with_default)] param_maybe_default* '*' (',' | param_no_default) param_maybe_default* '/'")); + } + { // param_maybe_default+ '/' '*' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default+ '/' '*'")); + Token * _literal; + asdl_seq * _loop1_167_var; + Token * a; + if ( + (_loop1_167_var = _loop1_167_rule(p)) // param_maybe_default+ + && + (_literal = _PyPegen_expect_token(p, 17)) // token='/' + && + (a = _PyPegen_expect_token(p, 16)) // token='*' + ) + { + D(fprintf(stderr, "%*c+ invalid_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_maybe_default+ '/' '*'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "expected comma between / and *" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default+ '/' '*'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_default: '=' &(')' | ',') +static void * +invalid_default_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // '=' &(')' | ',') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_default[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'=' &(')' | ',')")); + Token * a; + if ( + (a = _PyPegen_expect_token(p, 22)) // token='=' + && + _PyPegen_lookahead(1, _tmp_168_rule, p) + ) + { + D(fprintf(stderr, "%*c+ invalid_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'=' &(')' | ',')")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "expected default value expression" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_default[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'=' &(')' | ',')")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_star_etc: +// | '*' (')' | ',' (')' | '**')) +// | '*' ',' TYPE_COMMENT +// | '*' param '=' +// | '*' (param_no_default | ',') param_maybe_default* '*' (param_no_default | ',') +static void * +invalid_star_etc_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // '*' (')' | ',' (')' | '**')) + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); + void *_tmp_169_var; + Token * a; + if ( + (a = _PyPegen_expect_token(p, 16)) // token='*' + && + (_tmp_169_var = _tmp_169_rule(p)) // ')' | ',' (')' | '**') + ) + { + D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "named arguments must follow bare *" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); + } + { // '*' ',' TYPE_COMMENT + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' ',' TYPE_COMMENT")); + Token * _literal; + Token * _literal_1; + Token * type_comment_var; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' + && + (type_comment_var = _PyPegen_expect_token(p, TYPE_COMMENT)) // token='TYPE_COMMENT' + ) + { + D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' ',' TYPE_COMMENT")); + _res = RAISE_SYNTAX_ERROR ( "bare * has associated type comment" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' ',' TYPE_COMMENT")); + } + { // '*' param '=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' param '='")); + Token * _literal; + Token * a; + arg_ty param_var; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (param_var = param_rule(p)) // param + && + (a = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' param '='")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "var-positional argument cannot have default value" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' param '='")); + } + { // '*' (param_no_default | ',') param_maybe_default* '*' (param_no_default | ',') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (param_no_default | ',') param_maybe_default* '*' (param_no_default | ',')")); + Token * _literal; + asdl_seq * _loop0_171_var; + void *_tmp_170_var; + void *_tmp_172_var; + Token * a; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (_tmp_170_var = _tmp_170_rule(p)) // param_no_default | ',' + && + (_loop0_171_var = _loop0_171_rule(p)) // param_maybe_default* + && + (a = _PyPegen_expect_token(p, 16)) // token='*' + && + (_tmp_172_var = _tmp_172_rule(p)) // param_no_default | ',' + ) + { + D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (param_no_default | ',') param_maybe_default* '*' (param_no_default | ',')")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "* argument may appear only once" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' (param_no_default | ',') param_maybe_default* '*' (param_no_default | ',')")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// invalid_kwds: '**' param '=' | '**' param ',' param | '**' param ',' ('*' | '**' | '/') +static void * +invalid_kwds_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // '**' param '=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_kwds[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' param '='")); + Token * _literal; + Token * a; + arg_ty param_var; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + && + (param_var = param_rule(p)) // param + && + (a = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ invalid_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' param '='")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "var-keyword argument cannot have default value" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_kwds[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' param '='")); + } + { // '**' param ',' param + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_kwds[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' param ',' param")); + Token * _literal; + Token * _literal_1; + arg_ty a; + arg_ty param_var; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + && + (param_var = param_rule(p)) // param + && + (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' + && + (a = param_rule(p)) // param + ) + { + D(fprintf(stderr, "%*c+ invalid_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' param ',' param")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "arguments cannot follow var-keyword argument" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_kwds[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' param ',' param")); + } + { // '**' param ',' ('*' | '**' | '/') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_kwds[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' param ',' ('*' | '**' | '/')")); + Token * _literal; + Token * _literal_1; + Token* a; + arg_ty param_var; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + && + (param_var = param_rule(p)) // param + && + (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' + && + (a = (Token*)_tmp_173_rule(p)) // '*' | '**' | '/' + ) + { + D(fprintf(stderr, "%*c+ invalid_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' param ',' ('*' | '**' | '/')")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "arguments cannot follow var-keyword argument" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_kwds[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' param ',' ('*' | '**' | '/')")); + } _res = NULL; done: p->level--; @@ -19960,13 +20509,13 @@ invalid_parameters_helper_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_parameters_helper[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default+")); - asdl_seq * _loop1_161_var; + asdl_seq * _loop1_174_var; if ( - (_loop1_161_var = _loop1_161_rule(p)) // param_with_default+ + (_loop1_174_var = _loop1_174_rule(p)) // param_with_default+ ) { D(fprintf(stderr, "%*c+ invalid_parameters_helper[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_with_default+")); - _res = _loop1_161_var; + _res = _loop1_174_var; goto done; } p->mark = _mark; @@ -19982,6 +20531,10 @@ invalid_parameters_helper_rule(Parser *p) // invalid_lambda_parameters: // | lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default // | lambda_param_no_default* '(' ','.lambda_param+ ','? ')' +// | "/" ',' +// | (lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* '/' +// | [(lambda_slash_no_default | lambda_slash_with_default)] lambda_param_maybe_default* '*' (',' | lambda_param_no_default) lambda_param_maybe_default* '/' +// | lambda_param_maybe_default+ '/' '*' static void * invalid_lambda_parameters_rule(Parser *p) { @@ -20001,11 +20554,11 @@ invalid_lambda_parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default")); - asdl_seq * _loop0_162_var; + asdl_seq * _loop0_175_var; arg_ty a; void *invalid_lambda_parameters_helper_var; if ( - (_loop0_162_var = _loop0_162_rule(p)) // lambda_param_no_default* + (_loop0_175_var = _loop0_175_rule(p)) // lambda_param_no_default* && (invalid_lambda_parameters_helper_var = invalid_lambda_parameters_helper_rule(p)) // invalid_lambda_parameters_helper && @@ -20031,18 +20584,18 @@ invalid_lambda_parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* '(' ','.lambda_param+ ','? ')'")); - asdl_seq * _gather_164_var; - asdl_seq * _loop0_163_var; + asdl_seq * _gather_177_var; + asdl_seq * _loop0_176_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings Token * a; Token * b; if ( - (_loop0_163_var = _loop0_163_rule(p)) // lambda_param_no_default* + (_loop0_176_var = _loop0_176_rule(p)) // lambda_param_no_default* && (a = _PyPegen_expect_token(p, 7)) // token='(' && - (_gather_164_var = _gather_164_rule(p)) // ','.lambda_param+ + (_gather_177_var = _gather_177_rule(p)) // ','.lambda_param+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -20062,6 +20615,133 @@ invalid_lambda_parameters_rule(Parser *p) D(fprintf(stderr, "%*c%s invalid_lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default* '(' ','.lambda_param+ ','? ')'")); } + { // "/" ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"/\" ','")); + Token * _literal; + Token * a; + if ( + (a = _PyPegen_expect_token(p, 17)) // token='/' + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"/\" ','")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "at least one argument must precede /" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"/\" ','")); + } + { // (lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* '/' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* '/'")); + asdl_seq * _loop0_180_var; + void *_tmp_179_var; + Token * a; + if ( + (_tmp_179_var = _tmp_179_rule(p)) // lambda_slash_no_default | lambda_slash_with_default + && + (_loop0_180_var = _loop0_180_rule(p)) // lambda_param_maybe_default* + && + (a = _PyPegen_expect_token(p, 17)) // token='/' + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* '/'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "/ may appear only once" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* '/'")); + } + { // [(lambda_slash_no_default | lambda_slash_with_default)] lambda_param_maybe_default* '*' (',' | lambda_param_no_default) lambda_param_maybe_default* '/' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "[(lambda_slash_no_default | lambda_slash_with_default)] lambda_param_maybe_default* '*' (',' | lambda_param_no_default) lambda_param_maybe_default* '/'")); + Token * _literal; + asdl_seq * _loop0_182_var; + asdl_seq * _loop0_184_var; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + void *_tmp_183_var; + Token * a; + if ( + (_opt_var = _tmp_181_rule(p), !p->error_indicator) // [(lambda_slash_no_default | lambda_slash_with_default)] + && + (_loop0_182_var = _loop0_182_rule(p)) // lambda_param_maybe_default* + && + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (_tmp_183_var = _tmp_183_rule(p)) // ',' | lambda_param_no_default + && + (_loop0_184_var = _loop0_184_rule(p)) // lambda_param_maybe_default* + && + (a = _PyPegen_expect_token(p, 17)) // token='/' + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "[(lambda_slash_no_default | lambda_slash_with_default)] lambda_param_maybe_default* '*' (',' | lambda_param_no_default) lambda_param_maybe_default* '/'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "/ must be ahead of *" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "[(lambda_slash_no_default | lambda_slash_with_default)] lambda_param_maybe_default* '*' (',' | lambda_param_no_default) lambda_param_maybe_default* '/'")); + } + { // lambda_param_maybe_default+ '/' '*' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default+ '/' '*'")); + Token * _literal; + asdl_seq * _loop1_185_var; + Token * a; + if ( + (_loop1_185_var = _loop1_185_rule(p)) // lambda_param_maybe_default+ + && + (_literal = _PyPegen_expect_token(p, 17)) // token='/' + && + (a = _PyPegen_expect_token(p, 16)) // token='*' + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default+ '/' '*'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "expected comma between / and *" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default+ '/' '*'")); + } _res = NULL; done: p->level--; @@ -20114,13 +20794,13 @@ invalid_lambda_parameters_helper_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_lambda_parameters_helper[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+")); - asdl_seq * _loop1_166_var; + asdl_seq * _loop1_186_var; if ( - (_loop1_166_var = _loop1_166_rule(p)) // lambda_param_with_default+ + (_loop1_186_var = _loop1_186_rule(p)) // lambda_param_with_default+ ) { D(fprintf(stderr, "%*c+ invalid_lambda_parameters_helper[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+")); - _res = _loop1_166_var; + _res = _loop1_186_var; goto done; } p->mark = _mark; @@ -20133,9 +20813,12 @@ invalid_lambda_parameters_helper_rule(Parser *p) return _res; } -// invalid_star_etc: '*' (')' | ',' (')' | '**')) | '*' ',' TYPE_COMMENT +// invalid_lambda_star_etc: +// | '*' (':' | ',' (':' | '**')) +// | '*' lambda_param '=' +// | '*' (lambda_param_no_default | ',') lambda_param_maybe_default* '*' (lambda_param_no_default | ',') static void * -invalid_star_etc_rule(Parser *p) +invalid_lambda_star_etc_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -20147,22 +20830,52 @@ invalid_star_etc_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // '*' (')' | ',' (')' | '**')) + { // '*' (':' | ',' (':' | '**')) if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); - void *_tmp_167_var; + D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); + Token * _literal; + void *_tmp_187_var; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (_tmp_187_var = _tmp_187_rule(p)) // ':' | ',' (':' | '**') + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); + _res = RAISE_SYNTAX_ERROR ( "named arguments must follow bare *" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); + } + { // '*' lambda_param '=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' lambda_param '='")); + Token * _literal; Token * a; + arg_ty lambda_param_var; if ( - (a = _PyPegen_expect_token(p, 16)) // token='*' + (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_167_var = _tmp_167_rule(p)) // ')' | ',' (')' | '**') + (lambda_param_var = lambda_param_rule(p)) // lambda_param + && + (a = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "named arguments must follow bare *" ); + D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' lambda_param '='")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "var-positional argument cannot have default value" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -20171,28 +20884,34 @@ invalid_star_etc_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_star_etc[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); + D(fprintf(stderr, "%*c%s invalid_lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' lambda_param '='")); } - { // '*' ',' TYPE_COMMENT + { // '*' (lambda_param_no_default | ',') lambda_param_maybe_default* '*' (lambda_param_no_default | ',') if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' ',' TYPE_COMMENT")); + D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (lambda_param_no_default | ',') lambda_param_maybe_default* '*' (lambda_param_no_default | ',')")); Token * _literal; - Token * _literal_1; - Token * type_comment_var; + asdl_seq * _loop0_189_var; + void *_tmp_188_var; + void *_tmp_190_var; + Token * a; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' + (_tmp_188_var = _tmp_188_rule(p)) // lambda_param_no_default | ',' && - (type_comment_var = _PyPegen_expect_token(p, TYPE_COMMENT)) // token='TYPE_COMMENT' + (_loop0_189_var = _loop0_189_rule(p)) // lambda_param_maybe_default* + && + (a = _PyPegen_expect_token(p, 16)) // token='*' + && + (_tmp_190_var = _tmp_190_rule(p)) // lambda_param_no_default | ',' ) { - D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' ',' TYPE_COMMENT")); - _res = RAISE_SYNTAX_ERROR ( "bare * has associated type comment" ); + D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (lambda_param_no_default | ',') lambda_param_maybe_default* '*' (lambda_param_no_default | ',')")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "* argument may appear only once" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -20201,8 +20920,8 @@ invalid_star_etc_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_star_etc[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' ',' TYPE_COMMENT")); + D(fprintf(stderr, "%*c%s invalid_lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' (lambda_param_no_default | ',') lambda_param_maybe_default* '*' (lambda_param_no_default | ',')")); } _res = NULL; done: @@ -20210,9 +20929,12 @@ invalid_star_etc_rule(Parser *p) return _res; } -// invalid_lambda_star_etc: '*' (':' | ',' (':' | '**')) +// invalid_lambda_kwds: +// | '**' lambda_param '=' +// | '**' lambda_param ',' lambda_param +// | '**' lambda_param ',' ('*' | '**' | '/') static void * -invalid_lambda_star_etc_rule(Parser *p) +invalid_lambda_kwds_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -20224,22 +20946,25 @@ invalid_lambda_star_etc_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // '*' (':' | ',' (':' | '**')) + { // '**' lambda_param '=' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); + D(fprintf(stderr, "%*c> invalid_lambda_kwds[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' lambda_param '='")); Token * _literal; - void *_tmp_168_var; + Token * a; + arg_ty lambda_param_var; if ( - (_literal = _PyPegen_expect_token(p, 16)) // token='*' + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + && + (lambda_param_var = lambda_param_rule(p)) // lambda_param && - (_tmp_168_var = _tmp_168_rule(p)) // ':' | ',' (':' | '**') + (a = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); - _res = RAISE_SYNTAX_ERROR ( "named arguments must follow bare *" ); + D(fprintf(stderr, "%*c+ invalid_lambda_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' lambda_param '='")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "var-keyword argument cannot have default value" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -20248,8 +20973,74 @@ invalid_lambda_star_etc_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s invalid_lambda_star_etc[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); + D(fprintf(stderr, "%*c%s invalid_lambda_kwds[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' lambda_param '='")); + } + { // '**' lambda_param ',' lambda_param + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_kwds[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' lambda_param ',' lambda_param")); + Token * _literal; + Token * _literal_1; + arg_ty a; + arg_ty lambda_param_var; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + && + (lambda_param_var = lambda_param_rule(p)) // lambda_param + && + (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' + && + (a = lambda_param_rule(p)) // lambda_param + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' lambda_param ',' lambda_param")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "arguments cannot follow var-keyword argument" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_lambda_kwds[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' lambda_param ',' lambda_param")); + } + { // '**' lambda_param ',' ('*' | '**' | '/') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_lambda_kwds[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' lambda_param ',' ('*' | '**' | '/')")); + Token * _literal; + Token * _literal_1; + Token* a; + arg_ty lambda_param_var; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + && + (lambda_param_var = lambda_param_rule(p)) // lambda_param + && + (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' + && + (a = (Token*)_tmp_191_rule(p)) // '*' | '**' | '/' + ) + { + D(fprintf(stderr, "%*c+ invalid_lambda_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' lambda_param ',' ('*' | '**' | '/')")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "arguments cannot follow var-keyword argument" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_lambda_kwds[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' lambda_param ',' ('*' | '**' | '/')")); } _res = NULL; done: @@ -20343,7 +21134,7 @@ invalid_with_item_rule(Parser *p) && (a = expression_rule(p)) // expression && - _PyPegen_lookahead(1, _tmp_169_rule, p) + _PyPegen_lookahead(1, _tmp_192_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_with_item[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression 'as' expression &(',' | ')' | ':')")); @@ -20571,7 +21362,7 @@ invalid_with_stmt_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ &&':'")); - asdl_seq * _gather_170_var; + asdl_seq * _gather_193_var; Token * _keyword; Token * _literal; void *_opt_var; @@ -20581,13 +21372,13 @@ invalid_with_stmt_rule(Parser *p) && (_keyword = _PyPegen_expect_token(p, 612)) // token='with' && - (_gather_170_var = _gather_170_rule(p)) // ','.(expression ['as' star_target])+ + (_gather_193_var = _gather_193_rule(p)) // ','.(expression ['as' star_target])+ && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' ) { D(fprintf(stderr, "%*c+ invalid_with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ &&':'")); - _res = _PyPegen_dummy_name(p, _opt_var, _keyword, _gather_170_var, _literal); + _res = _PyPegen_dummy_name(p, _opt_var, _keyword, _gather_193_var, _literal); goto done; } p->mark = _mark; @@ -20600,7 +21391,7 @@ invalid_with_stmt_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' &&':'")); - asdl_seq * _gather_172_var; + asdl_seq * _gather_195_var; Token * _keyword; Token * _literal; Token * _literal_1; @@ -20616,7 +21407,7 @@ invalid_with_stmt_rule(Parser *p) && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (_gather_172_var = _gather_172_rule(p)) // ','.(expressions ['as' star_target])+ + (_gather_195_var = _gather_195_rule(p)) // ','.(expressions ['as' star_target])+ && (_opt_var_1 = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -20626,7 +21417,7 @@ invalid_with_stmt_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ invalid_with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' &&':'")); - _res = _PyPegen_dummy_name(p, _opt_var, _keyword, _literal, _gather_172_var, _opt_var_1, _literal_1, _literal_2); + _res = _PyPegen_dummy_name(p, _opt_var, _keyword, _literal, _gather_195_var, _opt_var_1, _literal_1, _literal_2); goto done; } p->mark = _mark; @@ -20661,7 +21452,7 @@ invalid_with_stmt_indent_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_with_stmt_indent[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT")); - asdl_seq * _gather_174_var; + asdl_seq * _gather_197_var; Token * _literal; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings @@ -20672,7 +21463,7 @@ invalid_with_stmt_indent_rule(Parser *p) && (a = _PyPegen_expect_token(p, 612)) // token='with' && - (_gather_174_var = _gather_174_rule(p)) // ','.(expression ['as' star_target])+ + (_gather_197_var = _gather_197_rule(p)) // ','.(expression ['as' star_target])+ && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -20700,7 +21491,7 @@ invalid_with_stmt_indent_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_with_stmt_indent[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT")); - asdl_seq * _gather_176_var; + asdl_seq * _gather_199_var; Token * _literal; Token * _literal_1; Token * _literal_2; @@ -20717,7 +21508,7 @@ invalid_with_stmt_indent_rule(Parser *p) && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (_gather_176_var = _gather_176_rule(p)) // ','.(expressions ['as' star_target])+ + (_gather_199_var = _gather_199_rule(p)) // ','.(expressions ['as' star_target])+ && (_opt_var_1 = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -20814,7 +21605,7 @@ invalid_try_stmt_rule(Parser *p) && (block_var = block_rule(p)) // block && - _PyPegen_lookahead(0, _tmp_178_rule, p) + _PyPegen_lookahead(0, _tmp_201_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' ':' block !('except' | 'finally')")); @@ -20838,19 +21629,19 @@ invalid_try_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> invalid_try_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'try' ':' block* ((except_block+ except_star_block) | (except_star_block+ except_block)) block*")); Token * _keyword; Token * _literal; - asdl_seq * _loop0_179_var; - asdl_seq * _loop0_181_var; - void *_tmp_180_var; + asdl_seq * _loop0_202_var; + asdl_seq * _loop0_204_var; + void *_tmp_203_var; if ( (_keyword = _PyPegen_expect_token(p, 618)) // token='try' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && - (_loop0_179_var = _loop0_179_rule(p)) // block* + (_loop0_202_var = _loop0_202_rule(p)) // block* && - (_tmp_180_var = _tmp_180_rule(p)) // (except_block+ except_star_block) | (except_star_block+ except_block) + (_tmp_203_var = _tmp_203_rule(p)) // (except_block+ except_star_block) | (except_star_block+ except_block) && - (_loop0_181_var = _loop0_181_rule(p)) // block* + (_loop0_204_var = _loop0_204_rule(p)) // block* ) { D(fprintf(stderr, "%*c+ invalid_try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' ':' block* ((except_block+ except_star_block) | (except_star_block+ except_block)) block*")); @@ -20916,7 +21707,7 @@ invalid_except_stmt_rule(Parser *p) && (expressions_var = expressions_rule(p)) // expressions && - (_opt_var_1 = _tmp_182_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var_1 = _tmp_205_rule(p), !p->error_indicator) // ['as' NAME] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' ) @@ -20954,7 +21745,7 @@ invalid_except_stmt_rule(Parser *p) && (expression_var = expression_rule(p)) // expression && - (_opt_var_1 = _tmp_183_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var_1 = _tmp_206_rule(p), !p->error_indicator) // ['as' NAME] && (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) @@ -21006,14 +21797,14 @@ invalid_except_stmt_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_except_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' '*' (NEWLINE | ':')")); Token * _literal; - void *_tmp_184_var; + void *_tmp_207_var; Token * a; if ( (a = _PyPegen_expect_token(p, 629)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_184_var = _tmp_184_rule(p)) // NEWLINE | ':' + (_tmp_207_var = _tmp_207_rule(p)) // NEWLINE | ':' ) { D(fprintf(stderr, "%*c+ invalid_except_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' '*' (NEWLINE | ':')")); @@ -21120,7 +21911,7 @@ invalid_except_stmt_indent_rule(Parser *p) && (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_185_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var = _tmp_208_rule(p), !p->error_indicator) // ['as' NAME] && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -21215,7 +22006,7 @@ invalid_except_star_stmt_indent_rule(Parser *p) && (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_186_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var = _tmp_209_rule(p), !p->error_indicator) // ['as' NAME] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' && @@ -21582,7 +22373,7 @@ invalid_class_argument_pattern_rule(Parser *p) asdl_pattern_seq* a; asdl_seq* keyword_patterns_var; if ( - (_opt_var = _tmp_187_rule(p), !p->error_indicator) // [positional_patterns ','] + (_opt_var = _tmp_210_rule(p), !p->error_indicator) // [positional_patterns ','] && (keyword_patterns_var = keyword_patterns_rule(p)) // keyword_patterns && @@ -22034,7 +22825,7 @@ invalid_def_raw_rule(Parser *p) && (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' && - (_opt_var_2 = _tmp_188_rule(p), !p->error_indicator) // ['->' expression] + (_opt_var_2 = _tmp_211_rule(p), !p->error_indicator) // ['->' expression] && (_literal_2 = _PyPegen_expect_token(p, 11)) // token=':' && @@ -22093,7 +22884,7 @@ invalid_class_def_raw_rule(Parser *p) && (name_var = _PyPegen_name_token(p)) // NAME && - (_opt_var = _tmp_189_rule(p), !p->error_indicator) // ['(' arguments? ')'] + (_opt_var = _tmp_212_rule(p), !p->error_indicator) // ['(' arguments? ')'] && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -22144,11 +22935,11 @@ invalid_double_starred_kvpairs_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_double_starred_kvpairs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.double_starred_kvpair+ ',' invalid_kvpair")); - asdl_seq * _gather_190_var; + asdl_seq * _gather_213_var; Token * _literal; void *invalid_kvpair_var; if ( - (_gather_190_var = _gather_190_rule(p)) // ','.double_starred_kvpair+ + (_gather_213_var = _gather_213_rule(p)) // ','.double_starred_kvpair+ && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && @@ -22156,7 +22947,7 @@ invalid_double_starred_kvpairs_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ invalid_double_starred_kvpairs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.double_starred_kvpair+ ',' invalid_kvpair")); - _res = _PyPegen_dummy_name(p, _gather_190_var, _literal, invalid_kvpair_var); + _res = _PyPegen_dummy_name(p, _gather_213_var, _literal, invalid_kvpair_var); goto done; } p->mark = _mark; @@ -22209,7 +23000,7 @@ invalid_double_starred_kvpairs_rule(Parser *p) && (a = _PyPegen_expect_token(p, 11)) // token=':' && - _PyPegen_lookahead(1, _tmp_192_rule, p) + _PyPegen_lookahead(1, _tmp_215_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_double_starred_kvpairs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' &('}' | ',')")); @@ -23171,12 +23962,12 @@ _loop1_14_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_14[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_193_var; + void *_tmp_216_var; while ( - (_tmp_193_var = _tmp_193_rule(p)) // star_targets '=' + (_tmp_216_var = _tmp_216_rule(p)) // star_targets '=' ) { - _res = _tmp_193_var; + _res = _tmp_216_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -23753,12 +24544,12 @@ _loop0_24_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_24[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); - void *_tmp_194_var; + void *_tmp_217_var; while ( - (_tmp_194_var = _tmp_194_rule(p)) // '.' | '...' + (_tmp_217_var = _tmp_217_rule(p)) // '.' | '...' ) { - _res = _tmp_194_var; + _res = _tmp_217_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -23822,12 +24613,12 @@ _loop1_25_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_25[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); - void *_tmp_195_var; + void *_tmp_218_var; while ( - (_tmp_195_var = _tmp_195_rule(p)) // '.' | '...' + (_tmp_218_var = _tmp_218_rule(p)) // '.' | '...' ) { - _res = _tmp_195_var; + _res = _tmp_218_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -24230,12 +25021,12 @@ _loop1_32_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_32[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('@' named_expression NEWLINE)")); - void *_tmp_196_var; + void *_tmp_219_var; while ( - (_tmp_196_var = _tmp_196_rule(p)) // '@' named_expression NEWLINE + (_tmp_219_var = _tmp_219_rule(p)) // '@' named_expression NEWLINE ) { - _res = _tmp_196_var; + _res = _tmp_219_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -27250,12 +28041,12 @@ _loop1_79_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_79[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' expression)")); - void *_tmp_197_var; + void *_tmp_220_var; while ( - (_tmp_197_var = _tmp_197_rule(p)) // ',' expression + (_tmp_220_var = _tmp_220_rule(p)) // ',' expression ) { - _res = _tmp_197_var; + _res = _tmp_220_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -27324,12 +28115,12 @@ _loop1_80_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_80[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_expression)")); - void *_tmp_198_var; + void *_tmp_221_var; while ( - (_tmp_198_var = _tmp_198_rule(p)) // ',' star_expression + (_tmp_221_var = _tmp_221_rule(p)) // ',' star_expression ) { - _res = _tmp_198_var; + _res = _tmp_221_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -27518,12 +28309,12 @@ _loop1_83_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_83[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('or' conjunction)")); - void *_tmp_199_var; + void *_tmp_222_var; while ( - (_tmp_199_var = _tmp_199_rule(p)) // 'or' conjunction + (_tmp_222_var = _tmp_222_rule(p)) // 'or' conjunction ) { - _res = _tmp_199_var; + _res = _tmp_222_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -27592,12 +28383,12 @@ _loop1_84_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_84[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('and' inversion)")); - void *_tmp_200_var; + void *_tmp_223_var; while ( - (_tmp_200_var = _tmp_200_rule(p)) // 'and' inversion + (_tmp_223_var = _tmp_223_rule(p)) // 'and' inversion ) { - _res = _tmp_200_var; + _res = _tmp_223_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -29559,12 +30350,12 @@ _loop0_113_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_113[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); - void *_tmp_201_var; + void *_tmp_224_var; while ( - (_tmp_201_var = _tmp_201_rule(p)) // 'if' disjunction + (_tmp_224_var = _tmp_224_rule(p)) // 'if' disjunction ) { - _res = _tmp_201_var; + _res = _tmp_224_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -29628,12 +30419,12 @@ _loop0_114_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_114[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); - void *_tmp_202_var; + void *_tmp_225_var; while ( - (_tmp_202_var = _tmp_202_rule(p)) // 'if' disjunction + (_tmp_225_var = _tmp_225_rule(p)) // 'if' disjunction ) { - _res = _tmp_202_var; + _res = _tmp_225_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -29762,7 +30553,7 @@ _loop0_117_rule(Parser *p) while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_203_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' + (elem = _tmp_226_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' ) { _res = elem; @@ -29829,7 +30620,7 @@ _gather_116_rule(Parser *p) void *elem; asdl_seq * seq; if ( - (elem = _tmp_203_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' + (elem = _tmp_226_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' && (seq = _loop0_117_rule(p)) // _loop0_117 ) @@ -30405,12 +31196,12 @@ _loop0_127_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_127[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); - void *_tmp_204_var; + void *_tmp_227_var; while ( - (_tmp_204_var = _tmp_204_rule(p)) // ',' star_target + (_tmp_227_var = _tmp_227_rule(p)) // ',' star_target ) { - _res = _tmp_204_var; + _res = _tmp_227_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -30594,12 +31385,12 @@ _loop1_130_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); - void *_tmp_205_var; + void *_tmp_228_var; while ( - (_tmp_205_var = _tmp_205_rule(p)) // ',' star_target + (_tmp_228_var = _tmp_228_rule(p)) // ',' star_target ) { - _res = _tmp_205_var; + _res = _tmp_228_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -31969,12 +32760,12 @@ _loop0_152_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_206_var; + void *_tmp_229_var; while ( - (_tmp_206_var = _tmp_206_rule(p)) // star_targets '=' + (_tmp_229_var = _tmp_229_rule(p)) // star_targets '=' ) { - _res = _tmp_206_var; + _res = _tmp_229_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -32038,12 +32829,12 @@ _loop0_153_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_207_var; + void *_tmp_230_var; while ( - (_tmp_207_var = _tmp_207_rule(p)) // star_targets '=' + (_tmp_230_var = _tmp_230_rule(p)) // star_targets '=' ) { - _res = _tmp_207_var; + _res = _tmp_230_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -32540,9 +33331,9 @@ _loop1_160_rule(Parser *p) return _seq; } -// _loop1_161: param_with_default -static asdl_seq * -_loop1_161_rule(Parser *p) +// _tmp_161: slash_no_default | slash_with_default +static void * +_tmp_161_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -32552,71 +33343,976 @@ _loop1_161_rule(Parser *p) p->level--; return NULL; } - void *_res = NULL; + void * _res = NULL; int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // param_with_default + { // slash_no_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_161[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); - NameDefaultPair* param_with_default_var; - while ( - (param_with_default_var = param_with_default_rule(p)) // param_with_default + D(fprintf(stderr, "%*c> _tmp_161[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + asdl_arg_seq* slash_no_default_var; + if ( + (slash_no_default_var = slash_no_default_rule(p)) // slash_no_default ) { - _res = param_with_default_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; + D(fprintf(stderr, "%*c+ _tmp_161[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + _res = slash_no_default_var; + goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_161[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); - } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - p->level--; - return NULL; + D(fprintf(stderr, "%*c%s _tmp_161[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_no_default")); } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; + { // slash_with_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_161[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + SlashWithDefault* slash_with_default_var; + if ( + (slash_with_default_var = slash_with_default_rule(p)) // slash_with_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_161[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + _res = slash_with_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_161[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default")); } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_161_type, _seq); + _res = NULL; + done: p->level--; - return _seq; + return _res; } -// _loop0_162: lambda_param_no_default +// _loop0_162: param_maybe_default static asdl_seq * _loop0_162_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // param_maybe_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + NameDefaultPair* param_maybe_default_var; + while ( + (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default + ) + { + _res = param_maybe_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_162[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_162_type, _seq); + p->level--; + return _seq; +} + +// _tmp_163: slash_no_default | slash_with_default +static void * +_tmp_163_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // slash_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + asdl_arg_seq* slash_no_default_var; + if ( + (slash_no_default_var = slash_no_default_rule(p)) // slash_no_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_163[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + _res = slash_no_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_163[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_no_default")); + } + { // slash_with_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + SlashWithDefault* slash_with_default_var; + if ( + (slash_with_default_var = slash_with_default_rule(p)) // slash_with_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_163[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + _res = slash_with_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_163[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_164: param_maybe_default +static asdl_seq * +_loop0_164_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // param_maybe_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + NameDefaultPair* param_maybe_default_var; + while ( + (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default + ) + { + _res = param_maybe_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_164[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_164_type, _seq); + p->level--; + return _seq; +} + +// _tmp_165: ',' | param_no_default +static void * +_tmp_165_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_165[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + } + { // param_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + arg_ty param_no_default_var; + if ( + (param_no_default_var = param_no_default_rule(p)) // param_no_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); + _res = param_no_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_165[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_166: param_maybe_default +static asdl_seq * +_loop0_166_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // param_maybe_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + NameDefaultPair* param_maybe_default_var; + while ( + (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default + ) + { + _res = param_maybe_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_166[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_166_type, _seq); + p->level--; + return _seq; +} + +// _loop1_167: param_maybe_default +static asdl_seq * +_loop1_167_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // param_maybe_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + NameDefaultPair* param_maybe_default_var; + while ( + (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default + ) + { + _res = param_maybe_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop1_167[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); + } + if (_n == 0 || p->error_indicator) { + PyMem_Free(_children); + p->level--; + return NULL; + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop1_167_type, _seq); + p->level--; + return _seq; +} + +// _tmp_168: ')' | ',' +static void * +_tmp_168_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_168[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ _tmp_168[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_168[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); + } + { // ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_168[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ _tmp_168[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_168[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_169: ')' | ',' (')' | '**') +static void * +_tmp_169_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_169[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ _tmp_169[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_169[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); + } + { // ',' (')' | '**') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_169[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); + Token * _literal; + void *_tmp_231_var; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (_tmp_231_var = _tmp_231_rule(p)) // ')' | '**' + ) + { + D(fprintf(stderr, "%*c+ _tmp_169[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); + _res = _PyPegen_dummy_name(p, _literal, _tmp_231_var); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_169[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (')' | '**')")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_170: param_no_default | ',' +static void * +_tmp_170_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // param_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_170[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + arg_ty param_no_default_var; + if ( + (param_no_default_var = param_no_default_rule(p)) // param_no_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_170[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); + _res = param_no_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_170[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); + } + { // ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_170[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ _tmp_170[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_170[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_171: param_maybe_default +static asdl_seq * +_loop0_171_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // param_maybe_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_171[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + NameDefaultPair* param_maybe_default_var; + while ( + (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default + ) + { + _res = param_maybe_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_171[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_171_type, _seq); + p->level--; + return _seq; +} + +// _tmp_172: param_no_default | ',' +static void * +_tmp_172_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // param_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_172[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + arg_ty param_no_default_var; + if ( + (param_no_default_var = param_no_default_rule(p)) // param_no_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_172[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); + _res = param_no_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_172[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); + } + { // ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_172[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ _tmp_172[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_172[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_173: '*' | '**' | '/' +static void * +_tmp_173_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // '*' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + ) + { + D(fprintf(stderr, "%*c+ _tmp_173[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_173[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*'")); + } + { // '**' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + ) + { + D(fprintf(stderr, "%*c+ _tmp_173[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_173[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); + } + { // '/' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 17)) // token='/' + ) + { + D(fprintf(stderr, "%*c+ _tmp_173[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_173[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'/'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop1_174: param_with_default +static asdl_seq * +_loop1_174_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // param_with_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); + NameDefaultPair* param_with_default_var; + while ( + (param_with_default_var = param_with_default_rule(p)) // param_with_default + ) + { + _res = param_with_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop1_174[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); + } + if (_n == 0 || p->error_indicator) { + PyMem_Free(_children); + p->level--; + return NULL; + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop1_174_type, _seq); + p->level--; + return _seq; +} + +// _loop0_175: lambda_param_no_default +static asdl_seq * +_loop0_175_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // lambda_param_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_175[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + arg_ty lambda_param_no_default_var; + while ( + (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default + ) + { + _res = lambda_param_no_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_175[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_175_type, _seq); + p->level--; + return _seq; +} + +// _loop0_176: lambda_param_no_default +static asdl_seq * +_loop0_176_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -32643,13 +34339,260 @@ _loop0_162_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); - arg_ty lambda_param_no_default_var; + D(fprintf(stderr, "%*c> _loop0_176[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + arg_ty lambda_param_no_default_var; + while ( + (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default + ) + { + _res = lambda_param_no_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_176[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_176_type, _seq); + p->level--; + return _seq; +} + +// _loop0_178: ',' lambda_param +static asdl_seq * +_loop0_178_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' lambda_param + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' lambda_param")); + Token * _literal; + arg_ty elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = lambda_param_rule(p)) // lambda_param + ) + { + _res = elem; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + PyMem_Free(_children); + p->level--; + return NULL; + } + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_178[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' lambda_param")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_178_type, _seq); + p->level--; + return _seq; +} + +// _gather_177: lambda_param _loop0_178 +static asdl_seq * +_gather_177_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // lambda_param _loop0_178 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_177[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_178")); + arg_ty elem; + asdl_seq * seq; + if ( + (elem = lambda_param_rule(p)) // lambda_param + && + (seq = _loop0_178_rule(p)) // _loop0_178 + ) + { + D(fprintf(stderr, "%*c+ _gather_177[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_178")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_177[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param _loop0_178")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_179: lambda_slash_no_default | lambda_slash_with_default +static void * +_tmp_179_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // lambda_slash_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + asdl_arg_seq* lambda_slash_no_default_var; + if ( + (lambda_slash_no_default_var = lambda_slash_no_default_rule(p)) // lambda_slash_no_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_179[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + _res = lambda_slash_no_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_179[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_no_default")); + } + { // lambda_slash_with_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + SlashWithDefault* lambda_slash_with_default_var; + if ( + (lambda_slash_with_default_var = lambda_slash_with_default_rule(p)) // lambda_slash_with_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_179[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + _res = lambda_slash_with_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_179[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_180: lambda_param_maybe_default +static asdl_seq * +_loop0_180_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // lambda_param_maybe_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + NameDefaultPair* lambda_param_maybe_default_var; while ( - (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default + (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default ) { - _res = lambda_param_no_default_var; + _res = lambda_param_maybe_default_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -32665,8 +34608,8 @@ _loop0_162_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_162[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c%s _loop0_180[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -32678,14 +34621,72 @@ _loop0_162_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_162_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_180_type, _seq); p->level--; return _seq; } -// _loop0_163: lambda_param_no_default +// _tmp_181: lambda_slash_no_default | lambda_slash_with_default +static void * +_tmp_181_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // lambda_slash_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + asdl_arg_seq* lambda_slash_no_default_var; + if ( + (lambda_slash_no_default_var = lambda_slash_no_default_rule(p)) // lambda_slash_no_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_181[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + _res = lambda_slash_no_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_181[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_no_default")); + } + { // lambda_slash_with_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + SlashWithDefault* lambda_slash_with_default_var; + if ( + (lambda_slash_with_default_var = lambda_slash_with_default_rule(p)) // lambda_slash_with_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_181[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + _res = lambda_slash_with_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_181[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_182: lambda_param_maybe_default static asdl_seq * -_loop0_163_rule(Parser *p) +_loop0_182_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -32707,18 +34708,145 @@ _loop0_163_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; + { // lambda_param_maybe_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + NameDefaultPair* lambda_param_maybe_default_var; + while ( + (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default + ) + { + _res = lambda_param_maybe_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_182[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_182_type, _seq); + p->level--; + return _seq; +} + +// _tmp_183: ',' | lambda_param_no_default +static void * +_tmp_183_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ _tmp_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_183[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + } { // lambda_param_no_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _tmp_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; - while ( + if ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default ) { + D(fprintf(stderr, "%*c+ _tmp_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); _res = lambda_param_no_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_183[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_184: lambda_param_maybe_default +static asdl_seq * +_loop0_184_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // lambda_param_maybe_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_184[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + NameDefaultPair* lambda_param_maybe_default_var; + while ( + (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default + ) + { + _res = lambda_param_maybe_default_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -32734,8 +34862,156 @@ _loop0_163_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_163[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c%s _loop0_184[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_184_type, _seq); + p->level--; + return _seq; +} + +// _loop1_185: lambda_param_maybe_default +static asdl_seq * +_loop1_185_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // lambda_param_maybe_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_185[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + NameDefaultPair* lambda_param_maybe_default_var; + while ( + (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default + ) + { + _res = lambda_param_maybe_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop1_185[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); + } + if (_n == 0 || p->error_indicator) { + PyMem_Free(_children); + p->level--; + return NULL; + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop1_185_type, _seq); + p->level--; + return _seq; +} + +// _loop1_186: lambda_param_with_default +static asdl_seq * +_loop1_186_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // lambda_param_with_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_186[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + NameDefaultPair* lambda_param_with_default_var; + while ( + (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default + ) + { + _res = lambda_param_with_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop1_186[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); + } + if (_n == 0 || p->error_indicator) { + PyMem_Free(_children); + p->level--; + return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -32747,14 +35023,133 @@ _loop0_163_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_163_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_186_type, _seq); p->level--; return _seq; } -// _loop0_165: ',' lambda_param +// _tmp_187: ':' | ',' (':' | '**') +static void * +_tmp_187_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // ':' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_187[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + ) + { + D(fprintf(stderr, "%*c+ _tmp_187[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_187[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); + } + { // ',' (':' | '**') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_187[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); + Token * _literal; + void *_tmp_232_var; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (_tmp_232_var = _tmp_232_rule(p)) // ':' | '**' + ) + { + D(fprintf(stderr, "%*c+ _tmp_187[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); + _res = _PyPegen_dummy_name(p, _literal, _tmp_232_var); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_187[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (':' | '**')")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_188: lambda_param_no_default | ',' +static void * +_tmp_188_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // lambda_param_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_188[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + arg_ty lambda_param_no_default_var; + if ( + (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_188[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + _res = lambda_param_no_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_188[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); + } + { // ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_188[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ _tmp_188[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_188[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_189: lambda_param_maybe_default static asdl_seq * -_loop0_165_rule(Parser *p) +_loop0_189_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -32776,27 +35171,18 @@ _loop0_165_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // ',' lambda_param + { // lambda_param_maybe_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' lambda_param")); - Token * _literal; - arg_ty elem; + D(fprintf(stderr, "%*c> _loop0_189[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + NameDefaultPair* lambda_param_maybe_default_var; while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (elem = lambda_param_rule(p)) // lambda_param + (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default ) { - _res = elem; - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - PyMem_Free(_children); - p->level--; - return NULL; - } + _res = lambda_param_maybe_default_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -32812,8 +35198,8 @@ _loop0_165_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_165[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' lambda_param")); + D(fprintf(stderr, "%*c%s _loop0_189[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -32825,14 +35211,14 @@ _loop0_165_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_165_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_189_type, _seq); p->level--; return _seq; } -// _gather_164: lambda_param _loop0_165 -static asdl_seq * -_gather_164_rule(Parser *p) +// _tmp_190: lambda_param_no_default | ',' +static void * +_tmp_190_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -32842,113 +35228,55 @@ _gather_164_rule(Parser *p) p->level--; return NULL; } - asdl_seq * _res = NULL; + void * _res = NULL; int _mark = p->mark; - { // lambda_param _loop0_165 + { // lambda_param_no_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_165")); - arg_ty elem; - asdl_seq * seq; + D(fprintf(stderr, "%*c> _tmp_190[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + arg_ty lambda_param_no_default_var; if ( - (elem = lambda_param_rule(p)) // lambda_param - && - (seq = _loop0_165_rule(p)) // _loop0_165 + (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default ) { - D(fprintf(stderr, "%*c+ _gather_164[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_165")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); + D(fprintf(stderr, "%*c+ _tmp_190[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + _res = lambda_param_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_164[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param _loop0_165")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _loop1_166: lambda_param_with_default -static asdl_seq * -_loop1_166_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - void *_res = NULL; - int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; + D(fprintf(stderr, "%*c%s _tmp_190[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // lambda_param_with_default + { // ',' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); - NameDefaultPair* lambda_param_with_default_var; - while ( - (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default + D(fprintf(stderr, "%*c> _tmp_190[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - _res = lambda_param_with_default_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; + D(fprintf(stderr, "%*c+ _tmp_190[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_166[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); - } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - p->level--; - return NULL; - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; + D(fprintf(stderr, "%*c%s _tmp_190[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_166_type, _seq); + _res = NULL; + done: p->level--; - return _seq; + return _res; } -// _tmp_167: ')' | ',' (')' | '**') +// _tmp_191: '*' | '**' | '/' static void * -_tmp_167_rule(Parser *p) +_tmp_191_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -32960,107 +35288,62 @@ _tmp_167_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // ')' + { // '*' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); Token * _literal; if ( - (_literal = _PyPegen_expect_token(p, 8)) // token=')' + (_literal = _PyPegen_expect_token(p, 16)) // token='*' ) { - D(fprintf(stderr, "%*c+ _tmp_167[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_191[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_167[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); - } - { // ',' (')' | '**') - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); - Token * _literal; - void *_tmp_208_var; - if ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (_tmp_208_var = _tmp_208_rule(p)) // ')' | '**' - ) - { - D(fprintf(stderr, "%*c+ _tmp_167[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_208_var); - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_167[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (')' | '**')")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_168: ':' | ',' (':' | '**') -static void * -_tmp_168_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; + D(fprintf(stderr, "%*c%s _tmp_191[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*'")); } - void * _res = NULL; - int _mark = p->mark; - { // ':' + { // '**' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_168[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( - (_literal = _PyPegen_expect_token(p, 11)) // token=':' + (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_168[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_191[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_168[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c%s _tmp_191[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } - { // ',' (':' | '**') + { // '/' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_168[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); + D(fprintf(stderr, "%*c> _tmp_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); Token * _literal; - void *_tmp_209_var; if ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (_tmp_209_var = _tmp_209_rule(p)) // ':' | '**' + (_literal = _PyPegen_expect_token(p, 17)) // token='/' ) { - D(fprintf(stderr, "%*c+ _tmp_168[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_209_var); + D(fprintf(stderr, "%*c+ _tmp_191[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); + _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_168[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (':' | '**')")); + D(fprintf(stderr, "%*c%s _tmp_191[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'/'")); } _res = NULL; done: @@ -33068,9 +35351,9 @@ _tmp_168_rule(Parser *p) return _res; } -// _tmp_169: ',' | ')' | ':' +// _tmp_192: ',' | ')' | ':' static void * -_tmp_169_rule(Parser *p) +_tmp_192_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33087,18 +35370,18 @@ _tmp_169_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_169[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_169[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_169[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_192[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } { // ')' @@ -33106,18 +35389,18 @@ _tmp_169_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_169[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_169[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_169[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_192[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // ':' @@ -33125,18 +35408,18 @@ _tmp_169_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_169[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_169[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_169[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_192[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } _res = NULL; @@ -33145,9 +35428,9 @@ _tmp_169_rule(Parser *p) return _res; } -// _loop0_171: ',' (expression ['as' star_target]) +// _loop0_194: ',' (expression ['as' star_target]) static asdl_seq * -_loop0_171_rule(Parser *p) +_loop0_194_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33174,13 +35457,13 @@ _loop0_171_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_171[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); + D(fprintf(stderr, "%*c> _loop0_194[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); Token * _literal; void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_210_rule(p)) // expression ['as' star_target] + (elem = _tmp_233_rule(p)) // expression ['as' star_target] ) { _res = elem; @@ -33205,7 +35488,7 @@ _loop0_171_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_171[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_194[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expression ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -33218,14 +35501,14 @@ _loop0_171_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_171_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_194_type, _seq); p->level--; return _seq; } -// _gather_170: (expression ['as' star_target]) _loop0_171 +// _gather_193: (expression ['as' star_target]) _loop0_194 static asdl_seq * -_gather_170_rule(Parser *p) +_gather_193_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33237,27 +35520,27 @@ _gather_170_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // (expression ['as' star_target]) _loop0_171 + { // (expression ['as' star_target]) _loop0_194 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_170[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_171")); + D(fprintf(stderr, "%*c> _gather_193[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_194")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_210_rule(p)) // expression ['as' star_target] + (elem = _tmp_233_rule(p)) // expression ['as' star_target] && - (seq = _loop0_171_rule(p)) // _loop0_171 + (seq = _loop0_194_rule(p)) // _loop0_194 ) { - D(fprintf(stderr, "%*c+ _gather_170[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_171")); + D(fprintf(stderr, "%*c+ _gather_193[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_194")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_170[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_171")); + D(fprintf(stderr, "%*c%s _gather_193[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_194")); } _res = NULL; done: @@ -33265,9 +35548,9 @@ _gather_170_rule(Parser *p) return _res; } -// _loop0_173: ',' (expressions ['as' star_target]) +// _loop0_196: ',' (expressions ['as' star_target]) static asdl_seq * -_loop0_173_rule(Parser *p) +_loop0_196_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33294,13 +35577,13 @@ _loop0_173_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); + D(fprintf(stderr, "%*c> _loop0_196[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); Token * _literal; void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_211_rule(p)) // expressions ['as' star_target] + (elem = _tmp_234_rule(p)) // expressions ['as' star_target] ) { _res = elem; @@ -33325,7 +35608,7 @@ _loop0_173_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_173[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_196[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expressions ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -33338,14 +35621,14 @@ _loop0_173_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_173_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_196_type, _seq); p->level--; return _seq; } -// _gather_172: (expressions ['as' star_target]) _loop0_173 +// _gather_195: (expressions ['as' star_target]) _loop0_196 static asdl_seq * -_gather_172_rule(Parser *p) +_gather_195_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33357,27 +35640,27 @@ _gather_172_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // (expressions ['as' star_target]) _loop0_173 + { // (expressions ['as' star_target]) _loop0_196 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_172[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_173")); + D(fprintf(stderr, "%*c> _gather_195[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_196")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_211_rule(p)) // expressions ['as' star_target] + (elem = _tmp_234_rule(p)) // expressions ['as' star_target] && - (seq = _loop0_173_rule(p)) // _loop0_173 + (seq = _loop0_196_rule(p)) // _loop0_196 ) { - D(fprintf(stderr, "%*c+ _gather_172[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_173")); + D(fprintf(stderr, "%*c+ _gather_195[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_196")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_172[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_173")); + D(fprintf(stderr, "%*c%s _gather_195[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_196")); } _res = NULL; done: @@ -33385,9 +35668,9 @@ _gather_172_rule(Parser *p) return _res; } -// _loop0_175: ',' (expression ['as' star_target]) +// _loop0_198: ',' (expression ['as' star_target]) static asdl_seq * -_loop0_175_rule(Parser *p) +_loop0_198_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33414,13 +35697,13 @@ _loop0_175_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_175[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); + D(fprintf(stderr, "%*c> _loop0_198[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); Token * _literal; void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_212_rule(p)) // expression ['as' star_target] + (elem = _tmp_235_rule(p)) // expression ['as' star_target] ) { _res = elem; @@ -33445,7 +35728,7 @@ _loop0_175_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_175[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_198[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expression ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -33458,14 +35741,14 @@ _loop0_175_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_175_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_198_type, _seq); p->level--; return _seq; } -// _gather_174: (expression ['as' star_target]) _loop0_175 +// _gather_197: (expression ['as' star_target]) _loop0_198 static asdl_seq * -_gather_174_rule(Parser *p) +_gather_197_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33477,27 +35760,27 @@ _gather_174_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // (expression ['as' star_target]) _loop0_175 + { // (expression ['as' star_target]) _loop0_198 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_175")); + D(fprintf(stderr, "%*c> _gather_197[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_198")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_212_rule(p)) // expression ['as' star_target] + (elem = _tmp_235_rule(p)) // expression ['as' star_target] && - (seq = _loop0_175_rule(p)) // _loop0_175 + (seq = _loop0_198_rule(p)) // _loop0_198 ) { - D(fprintf(stderr, "%*c+ _gather_174[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_175")); + D(fprintf(stderr, "%*c+ _gather_197[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_198")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_174[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_175")); + D(fprintf(stderr, "%*c%s _gather_197[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_198")); } _res = NULL; done: @@ -33505,9 +35788,9 @@ _gather_174_rule(Parser *p) return _res; } -// _loop0_177: ',' (expressions ['as' star_target]) +// _loop0_200: ',' (expressions ['as' star_target]) static asdl_seq * -_loop0_177_rule(Parser *p) +_loop0_200_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33534,13 +35817,13 @@ _loop0_177_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_177[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); + D(fprintf(stderr, "%*c> _loop0_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); Token * _literal; void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_213_rule(p)) // expressions ['as' star_target] + (elem = _tmp_236_rule(p)) // expressions ['as' star_target] ) { _res = elem; @@ -33565,7 +35848,7 @@ _loop0_177_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_177[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_200[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expressions ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -33578,14 +35861,14 @@ _loop0_177_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_177_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_200_type, _seq); p->level--; return _seq; } -// _gather_176: (expressions ['as' star_target]) _loop0_177 +// _gather_199: (expressions ['as' star_target]) _loop0_200 static asdl_seq * -_gather_176_rule(Parser *p) +_gather_199_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33597,27 +35880,27 @@ _gather_176_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // (expressions ['as' star_target]) _loop0_177 + { // (expressions ['as' star_target]) _loop0_200 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_176[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_177")); + D(fprintf(stderr, "%*c> _gather_199[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_200")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_213_rule(p)) // expressions ['as' star_target] + (elem = _tmp_236_rule(p)) // expressions ['as' star_target] && - (seq = _loop0_177_rule(p)) // _loop0_177 + (seq = _loop0_200_rule(p)) // _loop0_200 ) { - D(fprintf(stderr, "%*c+ _gather_176[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_177")); + D(fprintf(stderr, "%*c+ _gather_199[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_200")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_176[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_177")); + D(fprintf(stderr, "%*c%s _gather_199[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_200")); } _res = NULL; done: @@ -33625,9 +35908,9 @@ _gather_176_rule(Parser *p) return _res; } -// _tmp_178: 'except' | 'finally' +// _tmp_201: 'except' | 'finally' static void * -_tmp_178_rule(Parser *p) +_tmp_201_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33644,18 +35927,18 @@ _tmp_178_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except'")); + D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 629)) // token='except' ) { - D(fprintf(stderr, "%*c+ _tmp_178[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except'")); + D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_178[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except'")); } { // 'finally' @@ -33663,18 +35946,18 @@ _tmp_178_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally'")); + D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 625)) // token='finally' ) { - D(fprintf(stderr, "%*c+ _tmp_178[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally'")); + D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_178[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'finally'")); } _res = NULL; @@ -33683,9 +35966,9 @@ _tmp_178_rule(Parser *p) return _res; } -// _loop0_179: block +// _loop0_202: block static asdl_seq * -_loop0_179_rule(Parser *p) +_loop0_202_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33712,7 +35995,7 @@ _loop0_179_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); + D(fprintf(stderr, "%*c> _loop0_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); asdl_stmt_seq* block_var; while ( (block_var = block_rule(p)) // block @@ -33734,7 +36017,7 @@ _loop0_179_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_179[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_202[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "block")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -33747,14 +36030,14 @@ _loop0_179_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_179_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_202_type, _seq); p->level--; return _seq; } -// _tmp_180: (except_block+ except_star_block) | (except_star_block+ except_block) +// _tmp_203: (except_block+ except_star_block) | (except_star_block+ except_block) static void * -_tmp_180_rule(Parser *p) +_tmp_203_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33771,18 +36054,18 @@ _tmp_180_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(except_block+ except_star_block)")); - void *_tmp_214_var; + D(fprintf(stderr, "%*c> _tmp_203[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(except_block+ except_star_block)")); + void *_tmp_237_var; if ( - (_tmp_214_var = _tmp_214_rule(p)) // except_block+ except_star_block + (_tmp_237_var = _tmp_237_rule(p)) // except_block+ except_star_block ) { - D(fprintf(stderr, "%*c+ _tmp_180[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(except_block+ except_star_block)")); - _res = _tmp_214_var; + D(fprintf(stderr, "%*c+ _tmp_203[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(except_block+ except_star_block)")); + _res = _tmp_237_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_180[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_203[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(except_block+ except_star_block)")); } { // (except_star_block+ except_block) @@ -33790,18 +36073,18 @@ _tmp_180_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(except_star_block+ except_block)")); - void *_tmp_215_var; + D(fprintf(stderr, "%*c> _tmp_203[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(except_star_block+ except_block)")); + void *_tmp_238_var; if ( - (_tmp_215_var = _tmp_215_rule(p)) // except_star_block+ except_block + (_tmp_238_var = _tmp_238_rule(p)) // except_star_block+ except_block ) { - D(fprintf(stderr, "%*c+ _tmp_180[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(except_star_block+ except_block)")); - _res = _tmp_215_var; + D(fprintf(stderr, "%*c+ _tmp_203[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(except_star_block+ except_block)")); + _res = _tmp_238_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_180[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_203[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(except_star_block+ except_block)")); } _res = NULL; @@ -33810,9 +36093,9 @@ _tmp_180_rule(Parser *p) return _res; } -// _loop0_181: block +// _loop0_204: block static asdl_seq * -_loop0_181_rule(Parser *p) +_loop0_204_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33839,7 +36122,7 @@ _loop0_181_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); + D(fprintf(stderr, "%*c> _loop0_204[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); asdl_stmt_seq* block_var; while ( (block_var = block_rule(p)) // block @@ -33861,7 +36144,7 @@ _loop0_181_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_181[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_204[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "block")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -33874,14 +36157,14 @@ _loop0_181_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_181_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_204_type, _seq); p->level--; return _seq; } -// _tmp_182: 'as' NAME +// _tmp_205: 'as' NAME static void * -_tmp_182_rule(Parser *p) +_tmp_205_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33898,7 +36181,7 @@ _tmp_182_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_205[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( @@ -33907,12 +36190,12 @@ _tmp_182_rule(Parser *p) (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_182[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_205[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_182[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_205[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -33921,9 +36204,9 @@ _tmp_182_rule(Parser *p) return _res; } -// _tmp_183: 'as' NAME +// _tmp_206: 'as' NAME static void * -_tmp_183_rule(Parser *p) +_tmp_206_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33940,7 +36223,7 @@ _tmp_183_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_206[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( @@ -33949,12 +36232,12 @@ _tmp_183_rule(Parser *p) (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_206[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_183[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_206[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -33963,9 +36246,9 @@ _tmp_183_rule(Parser *p) return _res; } -// _tmp_184: NEWLINE | ':' +// _tmp_207: NEWLINE | ':' static void * -_tmp_184_rule(Parser *p) +_tmp_207_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33982,18 +36265,18 @@ _tmp_184_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_184[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE")); + D(fprintf(stderr, "%*c> _tmp_207[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE")); Token * newline_var; if ( (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) { - D(fprintf(stderr, "%*c+ _tmp_184[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE")); + D(fprintf(stderr, "%*c+ _tmp_207[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE")); _res = newline_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_184[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_207[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE")); } { // ':' @@ -34001,18 +36284,18 @@ _tmp_184_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_184[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_207[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_184[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_207[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_184[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_207[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } _res = NULL; @@ -34021,9 +36304,9 @@ _tmp_184_rule(Parser *p) return _res; } -// _tmp_185: 'as' NAME +// _tmp_208: 'as' NAME static void * -_tmp_185_rule(Parser *p) +_tmp_208_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34040,7 +36323,7 @@ _tmp_185_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_185[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_208[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( @@ -34049,12 +36332,12 @@ _tmp_185_rule(Parser *p) (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_185[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_208[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_185[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_208[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -34063,9 +36346,9 @@ _tmp_185_rule(Parser *p) return _res; } -// _tmp_186: 'as' NAME +// _tmp_209: 'as' NAME static void * -_tmp_186_rule(Parser *p) +_tmp_209_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34082,7 +36365,7 @@ _tmp_186_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_186[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_209[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( @@ -34091,12 +36374,12 @@ _tmp_186_rule(Parser *p) (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_186[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_209[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_186[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_209[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -34105,9 +36388,9 @@ _tmp_186_rule(Parser *p) return _res; } -// _tmp_187: positional_patterns ',' +// _tmp_210: positional_patterns ',' static void * -_tmp_187_rule(Parser *p) +_tmp_210_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34124,7 +36407,7 @@ _tmp_187_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_187[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); + D(fprintf(stderr, "%*c> _tmp_210[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); Token * _literal; asdl_pattern_seq* positional_patterns_var; if ( @@ -34133,12 +36416,12 @@ _tmp_187_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_187[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); + D(fprintf(stderr, "%*c+ _tmp_210[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); _res = _PyPegen_dummy_name(p, positional_patterns_var, _literal); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_187[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_210[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "positional_patterns ','")); } _res = NULL; @@ -34147,9 +36430,9 @@ _tmp_187_rule(Parser *p) return _res; } -// _tmp_188: '->' expression +// _tmp_211: '->' expression static void * -_tmp_188_rule(Parser *p) +_tmp_211_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34166,7 +36449,7 @@ _tmp_188_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_188[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); + D(fprintf(stderr, "%*c> _tmp_211[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); Token * _literal; expr_ty expression_var; if ( @@ -34175,12 +36458,12 @@ _tmp_188_rule(Parser *p) (expression_var = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ _tmp_188[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'->' expression")); + D(fprintf(stderr, "%*c+ _tmp_211[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'->' expression")); _res = _PyPegen_dummy_name(p, _literal, expression_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_188[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_211[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'->' expression")); } _res = NULL; @@ -34189,9 +36472,9 @@ _tmp_188_rule(Parser *p) return _res; } -// _tmp_189: '(' arguments? ')' +// _tmp_212: '(' arguments? ')' static void * -_tmp_189_rule(Parser *p) +_tmp_212_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34208,7 +36491,7 @@ _tmp_189_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_189[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + D(fprintf(stderr, "%*c> _tmp_212[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); Token * _literal; Token * _literal_1; void *_opt_var; @@ -34221,12 +36504,12 @@ _tmp_189_rule(Parser *p) (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_189[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + D(fprintf(stderr, "%*c+ _tmp_212[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); _res = _PyPegen_dummy_name(p, _literal, _opt_var, _literal_1); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_189[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_212[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' arguments? ')'")); } _res = NULL; @@ -34235,9 +36518,9 @@ _tmp_189_rule(Parser *p) return _res; } -// _loop0_191: ',' double_starred_kvpair +// _loop0_214: ',' double_starred_kvpair static asdl_seq * -_loop0_191_rule(Parser *p) +_loop0_214_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34264,7 +36547,7 @@ _loop0_191_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair")); + D(fprintf(stderr, "%*c> _loop0_214[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair")); Token * _literal; KeyValuePair* elem; while ( @@ -34295,7 +36578,7 @@ _loop0_191_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_191[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_214[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' double_starred_kvpair")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -34308,14 +36591,14 @@ _loop0_191_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_191_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_214_type, _seq); p->level--; return _seq; } -// _gather_190: double_starred_kvpair _loop0_191 +// _gather_213: double_starred_kvpair _loop0_214 static asdl_seq * -_gather_190_rule(Parser *p) +_gather_213_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34327,27 +36610,27 @@ _gather_190_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // double_starred_kvpair _loop0_191 + { // double_starred_kvpair _loop0_214 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_190[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_191")); + D(fprintf(stderr, "%*c> _gather_213[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_214")); KeyValuePair* elem; asdl_seq * seq; if ( (elem = double_starred_kvpair_rule(p)) // double_starred_kvpair && - (seq = _loop0_191_rule(p)) // _loop0_191 + (seq = _loop0_214_rule(p)) // _loop0_214 ) { - D(fprintf(stderr, "%*c+ _gather_190[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_191")); + D(fprintf(stderr, "%*c+ _gather_213[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_214")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_190[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_191")); + D(fprintf(stderr, "%*c%s _gather_213[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_214")); } _res = NULL; done: @@ -34355,9 +36638,9 @@ _gather_190_rule(Parser *p) return _res; } -// _tmp_192: '}' | ',' +// _tmp_215: '}' | ',' static void * -_tmp_192_rule(Parser *p) +_tmp_215_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34374,18 +36657,18 @@ _tmp_192_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c> _tmp_215[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 26)) // token='}' ) { - D(fprintf(stderr, "%*c+ _tmp_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c+ _tmp_215[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_192[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_215[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); } { // ',' @@ -34393,18 +36676,18 @@ _tmp_192_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_215[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_215[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_192[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_215[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -34413,9 +36696,9 @@ _tmp_192_rule(Parser *p) return _res; } -// _tmp_193: star_targets '=' +// _tmp_216: star_targets '=' static void * -_tmp_193_rule(Parser *p) +_tmp_216_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34432,7 +36715,7 @@ _tmp_193_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_193[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_216[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty z; if ( @@ -34441,7 +36724,7 @@ _tmp_193_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_193[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_216[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -34451,7 +36734,7 @@ _tmp_193_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_193[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_216[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; @@ -34460,9 +36743,9 @@ _tmp_193_rule(Parser *p) return _res; } -// _tmp_194: '.' | '...' +// _tmp_217: '.' | '...' static void * -_tmp_194_rule(Parser *p) +_tmp_217_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34479,18 +36762,18 @@ _tmp_194_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_194[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_217[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_194[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_217[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_194[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_217[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '...' @@ -34498,18 +36781,18 @@ _tmp_194_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_194[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c> _tmp_217[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 52)) // token='...' ) { - D(fprintf(stderr, "%*c+ _tmp_194[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c+ _tmp_217[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_194[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_217[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'")); } _res = NULL; @@ -34518,9 +36801,9 @@ _tmp_194_rule(Parser *p) return _res; } -// _tmp_195: '.' | '...' +// _tmp_218: '.' | '...' static void * -_tmp_195_rule(Parser *p) +_tmp_218_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34537,18 +36820,18 @@ _tmp_195_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_195[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_218[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_195[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_218[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_195[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_218[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '...' @@ -34556,18 +36839,18 @@ _tmp_195_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_195[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c> _tmp_218[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 52)) // token='...' ) { - D(fprintf(stderr, "%*c+ _tmp_195[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c+ _tmp_218[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_195[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_218[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'")); } _res = NULL; @@ -34576,9 +36859,9 @@ _tmp_195_rule(Parser *p) return _res; } -// _tmp_196: '@' named_expression NEWLINE +// _tmp_219: '@' named_expression NEWLINE static void * -_tmp_196_rule(Parser *p) +_tmp_219_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34595,7 +36878,7 @@ _tmp_196_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_196[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); + D(fprintf(stderr, "%*c> _tmp_219[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); Token * _literal; expr_ty f; Token * newline_var; @@ -34607,7 +36890,7 @@ _tmp_196_rule(Parser *p) (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) { - D(fprintf(stderr, "%*c+ _tmp_196[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); + D(fprintf(stderr, "%*c+ _tmp_219[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); _res = f; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -34617,7 +36900,7 @@ _tmp_196_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_196[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_219[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'@' named_expression NEWLINE")); } _res = NULL; @@ -34626,9 +36909,9 @@ _tmp_196_rule(Parser *p) return _res; } -// _tmp_197: ',' expression +// _tmp_220: ',' expression static void * -_tmp_197_rule(Parser *p) +_tmp_220_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34645,7 +36928,7 @@ _tmp_197_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_197[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c> _tmp_220[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); Token * _literal; expr_ty c; if ( @@ -34654,7 +36937,7 @@ _tmp_197_rule(Parser *p) (c = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ _tmp_197[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c+ _tmp_220[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -34664,7 +36947,7 @@ _tmp_197_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_197[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_220[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } _res = NULL; @@ -34673,9 +36956,9 @@ _tmp_197_rule(Parser *p) return _res; } -// _tmp_198: ',' star_expression +// _tmp_221: ',' star_expression static void * -_tmp_198_rule(Parser *p) +_tmp_221_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34692,7 +36975,7 @@ _tmp_198_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_198[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression")); + D(fprintf(stderr, "%*c> _tmp_221[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression")); Token * _literal; expr_ty c; if ( @@ -34701,7 +36984,7 @@ _tmp_198_rule(Parser *p) (c = star_expression_rule(p)) // star_expression ) { - D(fprintf(stderr, "%*c+ _tmp_198[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression")); + D(fprintf(stderr, "%*c+ _tmp_221[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -34711,7 +36994,7 @@ _tmp_198_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_198[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_221[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_expression")); } _res = NULL; @@ -34720,9 +37003,9 @@ _tmp_198_rule(Parser *p) return _res; } -// _tmp_199: 'or' conjunction +// _tmp_222: 'or' conjunction static void * -_tmp_199_rule(Parser *p) +_tmp_222_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34739,7 +37022,7 @@ _tmp_199_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_199[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); + D(fprintf(stderr, "%*c> _tmp_222[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); Token * _keyword; expr_ty c; if ( @@ -34748,7 +37031,7 @@ _tmp_199_rule(Parser *p) (c = conjunction_rule(p)) // conjunction ) { - D(fprintf(stderr, "%*c+ _tmp_199[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); + D(fprintf(stderr, "%*c+ _tmp_222[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -34758,7 +37041,7 @@ _tmp_199_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_199[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_222[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'or' conjunction")); } _res = NULL; @@ -34767,9 +37050,9 @@ _tmp_199_rule(Parser *p) return _res; } -// _tmp_200: 'and' inversion +// _tmp_223: 'and' inversion static void * -_tmp_200_rule(Parser *p) +_tmp_223_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34786,7 +37069,7 @@ _tmp_200_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion")); + D(fprintf(stderr, "%*c> _tmp_223[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion")); Token * _keyword; expr_ty c; if ( @@ -34795,7 +37078,7 @@ _tmp_200_rule(Parser *p) (c = inversion_rule(p)) // inversion ) { - D(fprintf(stderr, "%*c+ _tmp_200[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion")); + D(fprintf(stderr, "%*c+ _tmp_223[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -34805,7 +37088,7 @@ _tmp_200_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_200[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_223[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'and' inversion")); } _res = NULL; @@ -34814,9 +37097,9 @@ _tmp_200_rule(Parser *p) return _res; } -// _tmp_201: 'if' disjunction +// _tmp_224: 'if' disjunction static void * -_tmp_201_rule(Parser *p) +_tmp_224_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34833,7 +37116,7 @@ _tmp_201_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c> _tmp_224[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); Token * _keyword; expr_ty z; if ( @@ -34842,7 +37125,7 @@ _tmp_201_rule(Parser *p) (z = disjunction_rule(p)) // disjunction ) { - D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c+ _tmp_224[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -34852,7 +37135,7 @@ _tmp_201_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_224[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction")); } _res = NULL; @@ -34861,9 +37144,9 @@ _tmp_201_rule(Parser *p) return _res; } -// _tmp_202: 'if' disjunction +// _tmp_225: 'if' disjunction static void * -_tmp_202_rule(Parser *p) +_tmp_225_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34880,7 +37163,7 @@ _tmp_202_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c> _tmp_225[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); Token * _keyword; expr_ty z; if ( @@ -34889,7 +37172,7 @@ _tmp_202_rule(Parser *p) (z = disjunction_rule(p)) // disjunction ) { - D(fprintf(stderr, "%*c+ _tmp_202[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c+ _tmp_225[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -34899,7 +37182,7 @@ _tmp_202_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_202[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_225[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction")); } _res = NULL; @@ -34908,9 +37191,9 @@ _tmp_202_rule(Parser *p) return _res; } -// _tmp_203: starred_expression | (assignment_expression | expression !':=') !'=' +// _tmp_226: starred_expression | (assignment_expression | expression !':=') !'=' static void * -_tmp_203_rule(Parser *p) +_tmp_226_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34927,18 +37210,18 @@ _tmp_203_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_203[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); + D(fprintf(stderr, "%*c> _tmp_226[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); expr_ty starred_expression_var; if ( (starred_expression_var = starred_expression_rule(p)) // starred_expression ) { - D(fprintf(stderr, "%*c+ _tmp_203[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); + D(fprintf(stderr, "%*c+ _tmp_226[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); _res = starred_expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_203[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_226[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression")); } { // (assignment_expression | expression !':=') !'=' @@ -34946,20 +37229,20 @@ _tmp_203_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_203[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); - void *_tmp_216_var; + D(fprintf(stderr, "%*c> _tmp_226[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); + void *_tmp_239_var; if ( - (_tmp_216_var = _tmp_216_rule(p)) // assignment_expression | expression !':=' + (_tmp_239_var = _tmp_239_rule(p)) // assignment_expression | expression !':=' && _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 22) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_203[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); - _res = _tmp_216_var; + D(fprintf(stderr, "%*c+ _tmp_226[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); + _res = _tmp_239_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_203[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_226[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(assignment_expression | expression !':=') !'='")); } _res = NULL; @@ -34968,9 +37251,9 @@ _tmp_203_rule(Parser *p) return _res; } -// _tmp_204: ',' star_target +// _tmp_227: ',' star_target static void * -_tmp_204_rule(Parser *p) +_tmp_227_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34987,7 +37270,7 @@ _tmp_204_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_204[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c> _tmp_227[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); Token * _literal; expr_ty c; if ( @@ -34996,7 +37279,7 @@ _tmp_204_rule(Parser *p) (c = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_204[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c+ _tmp_227[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -35006,7 +37289,7 @@ _tmp_204_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_204[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_227[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target")); } _res = NULL; @@ -35015,9 +37298,9 @@ _tmp_204_rule(Parser *p) return _res; } -// _tmp_205: ',' star_target +// _tmp_228: ',' star_target static void * -_tmp_205_rule(Parser *p) +_tmp_228_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35034,7 +37317,7 @@ _tmp_205_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_205[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c> _tmp_228[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); Token * _literal; expr_ty c; if ( @@ -35043,7 +37326,7 @@ _tmp_205_rule(Parser *p) (c = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_205[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c+ _tmp_228[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -35053,7 +37336,7 @@ _tmp_205_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_205[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_228[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target")); } _res = NULL; @@ -35062,9 +37345,9 @@ _tmp_205_rule(Parser *p) return _res; } -// _tmp_206: star_targets '=' +// _tmp_229: star_targets '=' static void * -_tmp_206_rule(Parser *p) +_tmp_229_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35081,7 +37364,7 @@ _tmp_206_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_206[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_229[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty star_targets_var; if ( @@ -35090,12 +37373,12 @@ _tmp_206_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_206[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_229[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); _res = _PyPegen_dummy_name(p, star_targets_var, _literal); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_206[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_229[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; @@ -35104,9 +37387,9 @@ _tmp_206_rule(Parser *p) return _res; } -// _tmp_207: star_targets '=' +// _tmp_230: star_targets '=' static void * -_tmp_207_rule(Parser *p) +_tmp_230_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35123,7 +37406,7 @@ _tmp_207_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_207[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_230[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty star_targets_var; if ( @@ -35132,12 +37415,12 @@ _tmp_207_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_207[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_230[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); _res = _PyPegen_dummy_name(p, star_targets_var, _literal); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_207[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_230[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; @@ -35146,9 +37429,9 @@ _tmp_207_rule(Parser *p) return _res; } -// _tmp_208: ')' | '**' +// _tmp_231: ')' | '**' static void * -_tmp_208_rule(Parser *p) +_tmp_231_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35165,18 +37448,18 @@ _tmp_208_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_208[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_231[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_208[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_231[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_208[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_231[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // '**' @@ -35184,18 +37467,18 @@ _tmp_208_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_208[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_231[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_208[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_231[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_208[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_231[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } _res = NULL; @@ -35204,9 +37487,9 @@ _tmp_208_rule(Parser *p) return _res; } -// _tmp_209: ':' | '**' +// _tmp_232: ':' | '**' static void * -_tmp_209_rule(Parser *p) +_tmp_232_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35223,18 +37506,18 @@ _tmp_209_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_209[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_232[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_209[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_232[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_209[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_232[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // '**' @@ -35242,18 +37525,18 @@ _tmp_209_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_209[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_232[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_209[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_232[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_209[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_232[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } _res = NULL; @@ -35262,9 +37545,9 @@ _tmp_209_rule(Parser *p) return _res; } -// _tmp_210: expression ['as' star_target] +// _tmp_233: expression ['as' star_target] static void * -_tmp_210_rule(Parser *p) +_tmp_233_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35281,22 +37564,22 @@ _tmp_210_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_210[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_233[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty expression_var; if ( (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_217_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_240_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_210[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_233[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); _res = _PyPegen_dummy_name(p, expression_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_210[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_233[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' star_target]")); } _res = NULL; @@ -35305,9 +37588,9 @@ _tmp_210_rule(Parser *p) return _res; } -// _tmp_211: expressions ['as' star_target] +// _tmp_234: expressions ['as' star_target] static void * -_tmp_211_rule(Parser *p) +_tmp_234_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35324,22 +37607,22 @@ _tmp_211_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_211[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty expressions_var; if ( (expressions_var = expressions_rule(p)) // expressions && - (_opt_var = _tmp_218_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_241_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_211[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); _res = _PyPegen_dummy_name(p, expressions_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_211[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expressions ['as' star_target]")); } _res = NULL; @@ -35348,9 +37631,9 @@ _tmp_211_rule(Parser *p) return _res; } -// _tmp_212: expression ['as' star_target] +// _tmp_235: expression ['as' star_target] static void * -_tmp_212_rule(Parser *p) +_tmp_235_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35367,22 +37650,22 @@ _tmp_212_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_212[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty expression_var; if ( (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_219_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_242_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_212[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); _res = _PyPegen_dummy_name(p, expression_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_212[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_235[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' star_target]")); } _res = NULL; @@ -35391,9 +37674,9 @@ _tmp_212_rule(Parser *p) return _res; } -// _tmp_213: expressions ['as' star_target] +// _tmp_236: expressions ['as' star_target] static void * -_tmp_213_rule(Parser *p) +_tmp_236_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35410,22 +37693,22 @@ _tmp_213_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_213[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty expressions_var; if ( (expressions_var = expressions_rule(p)) // expressions && - (_opt_var = _tmp_220_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_243_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_213[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); _res = _PyPegen_dummy_name(p, expressions_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_213[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_236[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expressions ['as' star_target]")); } _res = NULL; @@ -35434,9 +37717,9 @@ _tmp_213_rule(Parser *p) return _res; } -// _tmp_214: except_block+ except_star_block +// _tmp_237: except_block+ except_star_block static void * -_tmp_214_rule(Parser *p) +_tmp_237_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35453,21 +37736,21 @@ _tmp_214_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_214[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block+ except_star_block")); - asdl_seq * _loop1_221_var; + D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block+ except_star_block")); + asdl_seq * _loop1_244_var; excepthandler_ty except_star_block_var; if ( - (_loop1_221_var = _loop1_221_rule(p)) // except_block+ + (_loop1_244_var = _loop1_244_rule(p)) // except_block+ && (except_star_block_var = except_star_block_rule(p)) // except_star_block ) { - D(fprintf(stderr, "%*c+ _tmp_214[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "except_block+ except_star_block")); - _res = _PyPegen_dummy_name(p, _loop1_221_var, except_star_block_var); + D(fprintf(stderr, "%*c+ _tmp_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "except_block+ except_star_block")); + _res = _PyPegen_dummy_name(p, _loop1_244_var, except_star_block_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_214[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_237[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_block+ except_star_block")); } _res = NULL; @@ -35476,9 +37759,9 @@ _tmp_214_rule(Parser *p) return _res; } -// _tmp_215: except_star_block+ except_block +// _tmp_238: except_star_block+ except_block static void * -_tmp_215_rule(Parser *p) +_tmp_238_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35495,21 +37778,21 @@ _tmp_215_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_215[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block+ except_block")); - asdl_seq * _loop1_222_var; + D(fprintf(stderr, "%*c> _tmp_238[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block+ except_block")); + asdl_seq * _loop1_245_var; excepthandler_ty except_block_var; if ( - (_loop1_222_var = _loop1_222_rule(p)) // except_star_block+ + (_loop1_245_var = _loop1_245_rule(p)) // except_star_block+ && (except_block_var = except_block_rule(p)) // except_block ) { - D(fprintf(stderr, "%*c+ _tmp_215[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "except_star_block+ except_block")); - _res = _PyPegen_dummy_name(p, _loop1_222_var, except_block_var); + D(fprintf(stderr, "%*c+ _tmp_238[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "except_star_block+ except_block")); + _res = _PyPegen_dummy_name(p, _loop1_245_var, except_block_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_215[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_238[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_star_block+ except_block")); } _res = NULL; @@ -35518,9 +37801,9 @@ _tmp_215_rule(Parser *p) return _res; } -// _tmp_216: assignment_expression | expression !':=' +// _tmp_239: assignment_expression | expression !':=' static void * -_tmp_216_rule(Parser *p) +_tmp_239_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35537,18 +37820,18 @@ _tmp_216_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_216[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + D(fprintf(stderr, "%*c> _tmp_239[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); expr_ty assignment_expression_var; if ( (assignment_expression_var = assignment_expression_rule(p)) // assignment_expression ) { - D(fprintf(stderr, "%*c+ _tmp_216[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + D(fprintf(stderr, "%*c+ _tmp_239[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression")); _res = assignment_expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_216[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_239[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "assignment_expression")); } { // expression !':=' @@ -35556,7 +37839,7 @@ _tmp_216_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_216[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); + D(fprintf(stderr, "%*c> _tmp_239[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); expr_ty expression_var; if ( (expression_var = expression_rule(p)) // expression @@ -35564,12 +37847,12 @@ _tmp_216_rule(Parser *p) _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 53) // token=':=' ) { - D(fprintf(stderr, "%*c+ _tmp_216[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); + D(fprintf(stderr, "%*c+ _tmp_239[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); _res = expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_216[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_239[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression !':='")); } _res = NULL; @@ -35578,9 +37861,9 @@ _tmp_216_rule(Parser *p) return _res; } -// _tmp_217: 'as' star_target +// _tmp_240: 'as' star_target static void * -_tmp_217_rule(Parser *p) +_tmp_240_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35597,7 +37880,7 @@ _tmp_217_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_217[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_240[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( @@ -35606,12 +37889,12 @@ _tmp_217_rule(Parser *p) (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_217[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_240[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); _res = _PyPegen_dummy_name(p, _keyword, star_target_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_217[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_240[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; @@ -35620,9 +37903,9 @@ _tmp_217_rule(Parser *p) return _res; } -// _tmp_218: 'as' star_target +// _tmp_241: 'as' star_target static void * -_tmp_218_rule(Parser *p) +_tmp_241_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35639,7 +37922,7 @@ _tmp_218_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_218[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_241[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( @@ -35648,12 +37931,12 @@ _tmp_218_rule(Parser *p) (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_218[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); _res = _PyPegen_dummy_name(p, _keyword, star_target_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_218[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_241[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; @@ -35662,9 +37945,9 @@ _tmp_218_rule(Parser *p) return _res; } -// _tmp_219: 'as' star_target +// _tmp_242: 'as' star_target static void * -_tmp_219_rule(Parser *p) +_tmp_242_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35681,7 +37964,7 @@ _tmp_219_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_219[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_242[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( @@ -35690,12 +37973,12 @@ _tmp_219_rule(Parser *p) (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_219[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_242[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); _res = _PyPegen_dummy_name(p, _keyword, star_target_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_219[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_242[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; @@ -35704,9 +37987,9 @@ _tmp_219_rule(Parser *p) return _res; } -// _tmp_220: 'as' star_target +// _tmp_243: 'as' star_target static void * -_tmp_220_rule(Parser *p) +_tmp_243_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35723,7 +38006,7 @@ _tmp_220_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_220[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_243[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( @@ -35732,12 +38015,12 @@ _tmp_220_rule(Parser *p) (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_220[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_243[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); _res = _PyPegen_dummy_name(p, _keyword, star_target_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_220[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_243[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; @@ -35746,9 +38029,9 @@ _tmp_220_rule(Parser *p) return _res; } -// _loop1_221: except_block +// _loop1_244: except_block static asdl_seq * -_loop1_221_rule(Parser *p) +_loop1_244_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35775,7 +38058,7 @@ _loop1_221_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_221[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block")); + D(fprintf(stderr, "%*c> _loop1_244[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block")); excepthandler_ty except_block_var; while ( (except_block_var = except_block_rule(p)) // except_block @@ -35797,7 +38080,7 @@ _loop1_221_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_221[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_244[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_block")); } if (_n == 0 || p->error_indicator) { @@ -35815,14 +38098,14 @@ _loop1_221_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_221_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_244_type, _seq); p->level--; return _seq; } -// _loop1_222: except_star_block +// _loop1_245: except_star_block static asdl_seq * -_loop1_222_rule(Parser *p) +_loop1_245_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35849,7 +38132,7 @@ _loop1_222_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_222[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block")); + D(fprintf(stderr, "%*c> _loop1_245[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block")); excepthandler_ty except_star_block_var; while ( (except_star_block_var = except_star_block_rule(p)) // except_star_block @@ -35871,7 +38154,7 @@ _loop1_222_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_222[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_245[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_star_block")); } if (_n == 0 || p->error_indicator) { @@ -35889,7 +38172,7 @@ _loop1_222_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_222_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_245_type, _seq); p->level--; return _seq; } From webhook-mailer at python.org Tue Mar 22 08:54:00 2022 From: webhook-mailer at python.org (vstinner) Date: Tue, 22 Mar 2022 12:54:00 -0000 Subject: [Python-checkins] bpo-47084: Clear Unicode cached representations on finalization (GH-32032) Message-ID: https://github.com/python/cpython/commit/88872a29f19092d2fde27365af230abd6d301941 commit: 88872a29f19092d2fde27365af230abd6d301941 branch: main author: Jeremy Kloth committer: vstinner date: 2022-03-22T13:53:51+01:00 summary: bpo-47084: Clear Unicode cached representations on finalization (GH-32032) files: M Include/internal/pycore_unicodeobject.h M Lib/__hello__.py M Lib/test/test_embed.py M Objects/unicodeobject.c M Tools/scripts/deepfreeze.py diff --git a/Include/internal/pycore_unicodeobject.h b/Include/internal/pycore_unicodeobject.h index 4394ce939b567..c7f06051a622f 100644 --- a/Include/internal/pycore_unicodeobject.h +++ b/Include/internal/pycore_unicodeobject.h @@ -18,6 +18,7 @@ extern PyStatus _PyUnicode_InitGlobalObjects(PyInterpreterState *); extern PyStatus _PyUnicode_InitTypes(PyInterpreterState *); extern void _PyUnicode_Fini(PyInterpreterState *); extern void _PyUnicode_FiniTypes(PyInterpreterState *); +extern void _PyStaticUnicode_Dealloc(PyObject *); /* other API */ diff --git a/Lib/__hello__.py b/Lib/__hello__.py index d37bd2766ac1c..c09d6a4f52332 100644 --- a/Lib/__hello__.py +++ b/Lib/__hello__.py @@ -1,5 +1,14 @@ initialized = True +class TestFrozenUtf8_1: + """\u00b6""" + +class TestFrozenUtf8_2: + """\u03c0""" + +class TestFrozenUtf8_4: + """\U0001f600""" + def main(): print("Hello world!") diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 80b9674c1c258..f0c88de68e89e 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -1645,24 +1645,29 @@ def test_frozenmain(self): '-X showrefcount requires a Python debug build') def test_no_memleak(self): # bpo-1635741: Python must release all memory at exit - cmd = [sys.executable, "-I", "-X", "showrefcount", "-c", "pass"] - proc = subprocess.run(cmd, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - text=True) - self.assertEqual(proc.returncode, 0) - out = proc.stdout.rstrip() - match = re.match(r'^\[(-?\d+) refs, (-?\d+) blocks\]', out) - if not match: - self.fail(f"unexpected output: {out!a}") - refs = int(match.group(1)) - blocks = int(match.group(2)) - self.assertEqual(refs, 0, out) - if not MS_WINDOWS: - self.assertEqual(blocks, 0, out) - else: - # bpo-46857: on Windows, Python still leaks 1 memory block at exit - self.assertIn(blocks, (0, 1), out) + tests = ( + ('off', 'pass'), + ('on', 'pass'), + ('off', 'import __hello__'), + ('on', 'import __hello__'), + ) + for flag, stmt in tests: + xopt = f"frozen_modules={flag}" + cmd = [sys.executable, "-I", "-X", "showrefcount", "-X", xopt, "-c", stmt] + proc = subprocess.run(cmd, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True) + self.assertEqual(proc.returncode, 0) + out = proc.stdout.rstrip() + match = re.match(r'^\[(-?\d+) refs, (-?\d+) blocks\]', out) + if not match: + self.fail(f"unexpected output: {out!a}") + refs = int(match.group(1)) + blocks = int(match.group(2)) + with self.subTest(frozen_modules=flag, stmt=stmt): + self.assertEqual(refs, 0, out) + self.assertEqual(blocks, 0, out) class StdPrinterTests(EmbeddingTestsMixin, unittest.TestCase): diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 5dfe6e1e93f9f..ce3ebce1ff72d 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -16057,6 +16057,35 @@ _PyUnicode_FiniTypes(PyInterpreterState *interp) } +static void unicode_static_dealloc(PyObject *op) +{ + PyASCIIObject* ascii = (PyASCIIObject*)op; + + assert(ascii->state.compact); + + if (ascii->state.ascii) { + if (ascii->wstr) { + PyObject_Free(ascii->wstr); + ascii->wstr = NULL; + } + } + else { + PyCompactUnicodeObject* compact = (PyCompactUnicodeObject*)op; + void* data = (void*)(compact + 1); + if (ascii->wstr && ascii->wstr != data) { + PyObject_Free(ascii->wstr); + ascii->wstr = NULL; + compact->wstr_length = 0; + } + if (compact->utf8) { + PyObject_Free(compact->utf8); + compact->utf8 = NULL; + compact->utf8_length = 0; + } + } +} + + void _PyUnicode_Fini(PyInterpreterState *interp) { @@ -16070,6 +16099,21 @@ _PyUnicode_Fini(PyInterpreterState *interp) _PyUnicode_FiniEncodings(&state->fs_codec); unicode_clear_identifiers(state); + + // Clear the single character singletons + for (int i = 0; i < 128; i++) { + unicode_static_dealloc((PyObject*)&_Py_SINGLETON(strings).ascii[i]); + } + for (int i = 0; i < 128; i++) { + unicode_static_dealloc((PyObject*)&_Py_SINGLETON(strings).latin1[i]); + } +} + + +void +_PyStaticUnicode_Dealloc(PyObject *op) +{ + unicode_static_dealloc(op); } diff --git a/Tools/scripts/deepfreeze.py b/Tools/scripts/deepfreeze.py index d208258dbc54c..1831c15784af7 100644 --- a/Tools/scripts/deepfreeze.py +++ b/Tools/scripts/deepfreeze.py @@ -185,6 +185,7 @@ def generate_unicode(self, name: str, s: str) -> str: else: self.write("PyCompactUnicodeObject _compact;") self.write(f"{datatype} _data[{len(s)+1}];") + self.deallocs.append(f"_PyStaticUnicode_Dealloc((PyObject *)&{name});") with self.block(f"{name} =", ";"): if ascii: with self.block("._ascii =", ","): From webhook-mailer at python.org Tue Mar 22 08:57:29 2022 From: webhook-mailer at python.org (markshannon) Date: Tue, 22 Mar 2022 12:57:29 -0000 Subject: [Python-checkins] bpo-47045: Remove `f_state` field (GH-31963) Message-ID: https://github.com/python/cpython/commit/49daf6dba8178c5ae5d4d65408b20566d39c36a8 commit: 49daf6dba8178c5ae5d4d65408b20566d39c36a8 branch: main author: Mark Shannon committer: markshannon date: 2022-03-22T12:57:19Z summary: bpo-47045: Remove `f_state` field (GH-31963) * Remove the f_state field from _PyInterpreterFrame * Make ownership of the frame explicit, replacing the is_generator field with an owner field. files: A Misc/NEWS.d/next/Core and Builtins/2022-03-17-16-25-57.bpo-47045.xQgHul.rst M Include/cpython/genobject.h M Include/cpython/pystate.h M Include/internal/pycore_frame.h M Modules/_xxsubinterpretersmodule.c M Objects/frameobject.c M Objects/genobject.c M Python/ceval.c M Python/frame.c diff --git a/Include/cpython/genobject.h b/Include/cpython/genobject.h index b485ac6183e2e..40eaa19d3fad9 100644 --- a/Include/cpython/genobject.h +++ b/Include/cpython/genobject.h @@ -27,7 +27,7 @@ extern "C" { char prefix##_closed; \ char prefix##_running_async; \ /* The frame */ \ - char prefix##_frame_valid; \ + int8_t prefix##_frame_state; \ PyObject *prefix##_iframe[1]; typedef struct { diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 26d6f7576e524..1af21a2c947d9 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -103,6 +103,7 @@ struct _ts { This is to prevent the actual trace/profile code from being recorded in the trace/profile. */ int tracing; + int tracing_what; /* The event currently being traced, if any. */ /* Pointer to current _PyCFrame in the C stack frame of the currently, * or most recently, executing _PyEval_EvalFrameDefault. */ diff --git a/Include/internal/pycore_frame.h b/Include/internal/pycore_frame.h index e2f551ef2c062..14fba8cd1f941 100644 --- a/Include/internal/pycore_frame.h +++ b/Include/internal/pycore_frame.h @@ -5,6 +5,7 @@ extern "C" { #endif #include +#include struct _frame { PyObject_HEAD @@ -14,7 +15,6 @@ struct _frame { int f_lineno; /* Current line number. Only valid if non-zero */ char f_trace_lines; /* Emit per-line trace events? */ char f_trace_opcodes; /* Emit per-opcode trace events? */ - char f_owns_frame; /* This frame owns the frame */ /* The frame data, if this frame object owns the frame */ PyObject *_f_frame_data[1]; }; @@ -24,20 +24,19 @@ extern PyFrameObject* _PyFrame_New_NoTrack(PyCodeObject *code); /* other API */ -/* These values are chosen so that the inline functions below all - * compare f_state to zero. - */ -enum _framestate { +typedef enum _framestate { FRAME_CREATED = -2, FRAME_SUSPENDED = -1, FRAME_EXECUTING = 0, - FRAME_RETURNED = 1, - FRAME_UNWINDING = 2, - FRAME_RAISED = 3, + FRAME_COMPLETED = 1, FRAME_CLEARED = 4 -}; +} PyFrameState; -typedef signed char PyFrameState; +enum _frameowner { + FRAME_OWNED_BY_THREAD = 0, + FRAME_OWNED_BY_GENERATOR = 1, + FRAME_OWNED_BY_FRAME_OBJECT = 2 +}; /* frame->f_lasti refers to the index of the last instruction, @@ -54,24 +53,11 @@ typedef struct _PyInterpreterFrame { struct _PyInterpreterFrame *previous; int f_lasti; /* Last instruction if called */ int stacktop; /* Offset of TOS from localsplus */ - PyFrameState f_state; /* What state the frame is in */ bool is_entry; // Whether this is the "root" frame for the current _PyCFrame. - bool is_generator; + char owner; PyObject *localsplus[1]; } _PyInterpreterFrame; -static inline int _PyFrame_IsRunnable(_PyInterpreterFrame *f) { - return f->f_state < FRAME_EXECUTING; -} - -static inline int _PyFrame_IsExecuting(_PyInterpreterFrame *f) { - return f->f_state == FRAME_EXECUTING; -} - -static inline int _PyFrameHasCompleted(_PyInterpreterFrame *f) { - return f->f_state > FRAME_EXECUTING; -} - static inline PyObject **_PyFrame_Stackbase(_PyInterpreterFrame *f) { return f->localsplus + f->f_code->co_nlocalsplus; } @@ -111,9 +97,8 @@ _PyFrame_InitializeSpecials( frame->stacktop = nlocalsplus; frame->frame_obj = NULL; frame->f_lasti = -1; - frame->f_state = FRAME_CREATED; frame->is_entry = false; - frame->is_generator = false; + frame->owner = FRAME_OWNED_BY_THREAD; } /* Gets the pointer to the locals array @@ -200,6 +185,15 @@ void _PyThreadState_PopFrame(PyThreadState *tstate, _PyInterpreterFrame *frame); _PyInterpreterFrame * _PyFrame_Push(PyThreadState *tstate, PyFunctionObject *func); + +static inline +PyGenObject *_PyFrame_GetGenerator(_PyInterpreterFrame *frame) +{ + assert(frame->owner == FRAME_OWNED_BY_GENERATOR); + size_t offset_in_gen = offsetof(PyGenObject, gi_iframe); + return (PyGenObject *)(((char *)frame) - offset_in_gen); +} + #ifdef __cplusplus } #endif diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-17-16-25-57.bpo-47045.xQgHul.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-17-16-25-57.bpo-47045.xQgHul.rst new file mode 100644 index 0000000000000..388258884299e --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-17-16-25-57.bpo-47045.xQgHul.rst @@ -0,0 +1,3 @@ +Remove the ``f_state`` field from the _PyInterpreterFrame struct. Add the +``owner`` field to the _PyInterpreterFrame struct to make ownership explicit +to simplify clearing and deallocing frames and generators. diff --git a/Modules/_xxsubinterpretersmodule.c b/Modules/_xxsubinterpretersmodule.c index 846b24d5efa9a..0e37ce0aa3fe3 100644 --- a/Modules/_xxsubinterpretersmodule.c +++ b/Modules/_xxsubinterpretersmodule.c @@ -1843,10 +1843,7 @@ _is_running(PyInterpreterState *interp) if (frame == NULL) { return 0; } - - int executing = _PyFrame_IsExecuting(frame); - - return executing; + return 1; } static int diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 7ccd300e2b454..5c6a8bcb9008d 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -412,6 +412,42 @@ frame_stack_pop(PyFrameObject *f) Py_DECREF(v); } +static PyFrameState +_PyFrame_GetState(PyFrameObject *frame) +{ + if (frame->f_frame->stacktop == 0) { + return FRAME_CLEARED; + } + switch(frame->f_frame->owner) { + case FRAME_OWNED_BY_GENERATOR: + { + PyGenObject *gen = _PyFrame_GetGenerator(frame->f_frame); + return gen->gi_frame_state; + } + case FRAME_OWNED_BY_THREAD: + { + if (frame->f_frame->f_lasti < 0) { + return FRAME_CREATED; + } + uint8_t *code = (uint8_t *)frame->f_frame->f_code->co_code_adaptive; + int opcode = code[frame->f_frame->f_lasti*sizeof(_Py_CODEUNIT)]; + switch(_PyOpcode_Deopt[opcode]) { + case COPY_FREE_VARS: + case MAKE_CELL: + case RETURN_GENERATOR: + /* Frame not fully initialized */ + return FRAME_CREATED; + default: + return FRAME_EXECUTING; + } + } + case FRAME_OWNED_BY_FRAME_OBJECT: + return FRAME_COMPLETED; + } + Py_UNREACHABLE(); +} + + /* Setter for f_lineno - you can set f_lineno from within a trace function in * order to jump to a given line of code, subject to some restrictions. Most * lines are OK to jump to because they don't make any assumptions about the @@ -440,6 +476,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore return -1; } + PyFrameState state = _PyFrame_GetState(f); /* * This code preserves the historical restrictions on * setting the line number of a frame. @@ -448,28 +485,31 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore * In addition, jumps are forbidden when not tracing, * as this is a debugging feature. */ - switch(f->f_frame->f_state) { - case FRAME_CREATED: + switch(PyThreadState_GET()->tracing_what) { + case PyTrace_EXCEPTION: + PyErr_SetString(PyExc_ValueError, + "can only jump from a 'line' trace event"); + return -1; + case PyTrace_CALL: PyErr_Format(PyExc_ValueError, "can't jump from the 'call' trace event of a new frame"); return -1; - case FRAME_RETURNED: - case FRAME_UNWINDING: - case FRAME_RAISED: - case FRAME_CLEARED: + case PyTrace_LINE: + break; + case PyTrace_RETURN: + if (state == FRAME_SUSPENDED) { + break; + } + /* fall through */ + default: PyErr_SetString(PyExc_ValueError, "can only jump from a 'line' trace event"); return -1; - case FRAME_EXECUTING: - case FRAME_SUSPENDED: - /* You can only do this from within a trace function, not via - * _getframe or similar hackery. */ - if (!f->f_trace) { - PyErr_Format(PyExc_ValueError, - "f_lineno can only be set by a trace function"); - return -1; - } - break; + } + if (!f->f_trace) { + PyErr_Format(PyExc_ValueError, + "f_lineno can only be set by a trace function"); + return -1; } int new_lineno; @@ -555,8 +595,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore PyErr_SetString(PyExc_ValueError, msg); return -1; } - /* Unwind block stack. */ - if (f->f_frame->f_state == FRAME_SUSPENDED) { + if (state == FRAME_SUSPENDED) { /* Account for value popped by yield */ start_stack = pop_value(start_stack); } @@ -623,7 +662,9 @@ frame_dealloc(PyFrameObject *f) { /* It is the responsibility of the owning generator/coroutine * to have cleared the generator pointer */ - assert(!f->f_frame->is_generator); + + assert(f->f_frame->owner != FRAME_OWNED_BY_GENERATOR || + _PyFrame_GetGenerator(f->f_frame)->gi_frame_state == FRAME_CLEARED); if (_PyObject_GC_IS_TRACKED(f)) { _PyObject_GC_UNTRACK(f); @@ -633,8 +674,7 @@ frame_dealloc(PyFrameObject *f) PyCodeObject *co = NULL; /* Kill all local variables including specials, if we own them */ - if (f->f_owns_frame) { - f->f_owns_frame = 0; + if (f->f_frame->owner == FRAME_OWNED_BY_FRAME_OBJECT) { assert(f->f_frame == (_PyInterpreterFrame *)f->_f_frame_data); _PyInterpreterFrame *frame = (_PyInterpreterFrame *)f->_f_frame_data; /* Don't clear code object until the end */ @@ -659,7 +699,7 @@ frame_traverse(PyFrameObject *f, visitproc visit, void *arg) { Py_VISIT(f->f_back); Py_VISIT(f->f_trace); - if (f->f_owns_frame == 0) { + if (f->f_frame->owner != FRAME_OWNED_BY_FRAME_OBJECT) { return 0; } assert(f->f_frame->frame_obj == NULL); @@ -669,13 +709,6 @@ frame_traverse(PyFrameObject *f, visitproc visit, void *arg) static int frame_tp_clear(PyFrameObject *f) { - /* Before anything else, make sure that this frame is clearly marked - * as being defunct! Else, e.g., a generator reachable from this - * frame may also point to this frame, believe itself to still be - * active, and try cleaning up this frame again. - */ - f->f_frame->f_state = FRAME_CLEARED; - Py_CLEAR(f->f_trace); /* locals and stack */ @@ -691,19 +724,25 @@ frame_tp_clear(PyFrameObject *f) static PyObject * frame_clear(PyFrameObject *f, PyObject *Py_UNUSED(ignored)) { - if (_PyFrame_IsExecuting(f->f_frame)) { - PyErr_SetString(PyExc_RuntimeError, - "cannot clear an executing frame"); - return NULL; + if (f->f_frame->owner == FRAME_OWNED_BY_GENERATOR) { + PyGenObject *gen = _PyFrame_GetGenerator(f->f_frame); + if (gen->gi_frame_state == FRAME_EXECUTING) { + goto running; + } + _PyGen_Finalize((PyObject *)gen); } - if (f->f_frame->is_generator) { - assert(!f->f_owns_frame); - size_t offset_in_gen = offsetof(PyGenObject, gi_iframe); - PyObject *gen = (PyObject *)(((char *)f->f_frame) - offset_in_gen); - _PyGen_Finalize(gen); + else if (f->f_frame->owner == FRAME_OWNED_BY_THREAD) { + goto running; + } + else { + assert(f->f_frame->owner == FRAME_OWNED_BY_FRAME_OBJECT); + (void)frame_tp_clear(f); } - (void)frame_tp_clear(f); Py_RETURN_NONE; +running: + PyErr_SetString(PyExc_RuntimeError, + "cannot clear an executing frame"); + return NULL; } PyDoc_STRVAR(clear__doc__, @@ -835,7 +874,7 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, } init_frame((_PyInterpreterFrame *)f->_f_frame_data, func, locals); f->f_frame = (_PyInterpreterFrame *)f->_f_frame_data; - f->f_owns_frame = 1; + f->f_frame->owner = FRAME_OWNED_BY_FRAME_OBJECT; Py_DECREF(func); _PyObject_GC_TRACK(f); return f; @@ -912,7 +951,7 @@ _PyFrame_FastToLocalsWithError(_PyInterpreterFrame *frame) { PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i); PyObject *value = fast[i]; - if (frame->f_state != FRAME_CLEARED) { + if (frame->stacktop) { if (kind & CO_FAST_FREE) { // The cell was set by COPY_FREE_VARS. assert(value != NULL && PyCell_Check(value)); @@ -1049,7 +1088,7 @@ _PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear) void PyFrame_LocalsToFast(PyFrameObject *f, int clear) { - if (f == NULL || f->f_frame->f_state == FRAME_CLEARED) { + if (f == NULL || _PyFrame_GetState(f) == FRAME_CLEARED) { return; } _PyFrame_LocalsToFast(f->f_frame, clear); @@ -1096,3 +1135,5 @@ _PyEval_BuiltinsFromGlobals(PyThreadState *tstate, PyObject *globals) return _PyEval_GetBuiltins(tstate); } + + diff --git a/Objects/genobject.c b/Objects/genobject.c index 3ad8dc1c45942..f071390d6d32b 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -35,9 +35,10 @@ gen_traverse(PyGenObject *gen, visitproc visit, void *arg) Py_VISIT(gen->gi_code); Py_VISIT(gen->gi_name); Py_VISIT(gen->gi_qualname); - if (gen->gi_frame_valid) { + if (gen->gi_frame_state < FRAME_CLEARED) { _PyInterpreterFrame *frame = (_PyInterpreterFrame *)(gen->gi_iframe); - assert(frame->frame_obj == NULL || frame->frame_obj->f_owns_frame == 0); + assert(frame->frame_obj == NULL || + frame->frame_obj->f_frame->owner == FRAME_OWNED_BY_GENERATOR); int err = _PyFrame_Traverse(frame, visit, arg); if (err) { return err; @@ -55,7 +56,7 @@ _PyGen_Finalize(PyObject *self) PyObject *res = NULL; PyObject *error_type, *error_value, *error_traceback; - if (gen->gi_frame_valid == 0 || _PyFrameHasCompleted((_PyInterpreterFrame *)gen->gi_iframe)) { + if (gen->gi_frame_state >= FRAME_COMPLETED) { /* Generator isn't paused, so no need to close */ return; } @@ -87,7 +88,7 @@ _PyGen_Finalize(PyObject *self) issue a RuntimeWarning. */ if (gen->gi_code != NULL && ((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE && - ((_PyInterpreterFrame *)gen->gi_iframe)->f_state == FRAME_CREATED) + gen->gi_frame_state == FRAME_CREATED) { _PyErr_WarnUnawaitedCoroutine((PyObject *)gen); } @@ -130,10 +131,9 @@ gen_dealloc(PyGenObject *gen) and GC_Del. */ Py_CLEAR(((PyAsyncGenObject*)gen)->ag_origin_or_finalizer); } - if (gen->gi_frame_valid) { + if (gen->gi_frame_state < FRAME_CLEARED) { _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe; - gen->gi_frame_valid = 0; - frame->is_generator = false; + gen->gi_frame_state = FRAME_CLEARED; frame->previous = NULL; _PyFrame_Clear(frame); } @@ -156,7 +156,7 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, PyObject *result; *presult = NULL; - if (frame->f_state == FRAME_CREATED && arg && arg != Py_None) { + if (gen->gi_frame_state == FRAME_CREATED && arg && arg != Py_None) { const char *msg = "can't send non-None value to a " "just-started generator"; if (PyCoro_CheckExact(gen)) { @@ -169,7 +169,7 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, PyErr_SetString(PyExc_TypeError, msg); return PYGEN_ERROR; } - if (gen->gi_frame_valid && _PyFrame_IsExecuting(frame)) { + if (gen->gi_frame_state == FRAME_EXECUTING) { const char *msg = "generator already executing"; if (PyCoro_CheckExact(gen)) { msg = "coroutine already executing"; @@ -180,7 +180,7 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, PyErr_SetString(PyExc_ValueError, msg); return PYGEN_ERROR; } - if (gen->gi_frame_valid == 0 || _PyFrameHasCompleted(frame)) { + if (gen->gi_frame_state >= FRAME_COMPLETED) { if (PyCoro_CheckExact(gen) && !closing) { /* `gen` is an exhausted coroutine: raise an error, except when called from gen_close(), which should @@ -199,8 +199,7 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, return PYGEN_ERROR; } - assert(gen->gi_frame_valid); - assert(_PyFrame_IsRunnable(frame)); + assert(gen->gi_frame_state < FRAME_EXECUTING); /* Push arg onto the frame's value stack */ result = arg ? arg : Py_None; Py_INCREF(result); @@ -216,7 +215,11 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, _PyErr_ChainStackItem(NULL); } + gen->gi_frame_state = FRAME_EXECUTING; result = _PyEval_EvalFrame(tstate, frame, exc); + if (gen->gi_frame_state == FRAME_EXECUTING) { + gen->gi_frame_state = FRAME_COMPLETED; + } tstate->exc_info = gen->gi_exc_state.previous_item; gen->gi_exc_state.previous_item = NULL; @@ -229,7 +232,7 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, /* If the generator just returned (as opposed to yielding), signal * that the generator is exhausted. */ if (result) { - if (!_PyFrameHasCompleted(frame)) { + if (gen->gi_frame_state == FRAME_SUSPENDED) { *presult = result; return PYGEN_NEXT; } @@ -265,8 +268,7 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, /* first clean reference cycle through stored exception traceback */ _PyErr_ClearExcState(&gen->gi_exc_state); - frame->is_generator = false; - gen->gi_frame_valid = 0; + gen->gi_frame_state = FRAME_CLEARED; _PyFrame_Clear(frame); *presult = result; return result ? PYGEN_RETURN : PYGEN_ERROR; @@ -347,7 +349,7 @@ _PyGen_yf(PyGenObject *gen) { PyObject *yf = NULL; - if (gen->gi_frame_valid) { + if (gen->gi_frame_state < FRAME_CLEARED) { _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe; if (frame->f_lasti < 1) { @@ -378,11 +380,10 @@ gen_close(PyGenObject *gen, PyObject *args) int err = 0; if (yf) { - _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe; - PyFrameState state = frame->f_state; - frame->f_state = FRAME_EXECUTING; + PyFrameState state = gen->gi_frame_state; + gen->gi_frame_state = FRAME_EXECUTING; err = gen_close_iter(yf); - frame->f_state = state; + gen->gi_frame_state = state; Py_DECREF(yf); } if (err == 0) @@ -429,10 +430,10 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, We have to allow some awaits to work it through, hence the `close_on_genexit` parameter here. */ - PyFrameState state = frame->f_state; - frame->f_state = FRAME_EXECUTING; + PyFrameState state = gen->gi_frame_state; + gen->gi_frame_state = FRAME_EXECUTING; err = gen_close_iter(yf); - frame->f_state = state; + gen->gi_frame_state = state; Py_DECREF(yf); if (err < 0) return gen_send_ex(gen, Py_None, 1, 0); @@ -451,11 +452,11 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, tstate->cframe->current_frame = frame; /* Close the generator that we are currently iterating with 'yield from' or awaiting on with 'await'. */ - PyFrameState state = frame->f_state; - frame->f_state = FRAME_EXECUTING; + PyFrameState state = gen->gi_frame_state; + gen->gi_frame_state = FRAME_EXECUTING; ret = _gen_throw((PyGenObject *)yf, close_on_genexit, typ, val, tb); - frame->f_state = state; + gen->gi_frame_state = state; tstate->cframe->current_frame = prev; frame->previous = NULL; } else { @@ -469,17 +470,17 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, Py_DECREF(yf); goto throw_here; } - PyFrameState state = frame->f_state; - frame->f_state = FRAME_EXECUTING; + PyFrameState state = gen->gi_frame_state; + gen->gi_frame_state = FRAME_EXECUTING; ret = PyObject_CallFunctionObjArgs(meth, typ, val, tb, NULL); - frame->f_state = state; + gen->gi_frame_state = state; Py_DECREF(meth); } Py_DECREF(yf); if (!ret) { PyObject *val; /* Pop subiterator from stack */ - assert(gen->gi_frame_valid); + assert(gen->gi_frame_state < FRAME_CLEARED); ret = _PyFrame_StackPop((_PyInterpreterFrame *)gen->gi_iframe); assert(ret == yf); Py_DECREF(ret); @@ -756,19 +757,16 @@ gen_getyieldfrom(PyGenObject *gen, void *Py_UNUSED(ignored)) static PyObject * gen_getrunning(PyGenObject *gen, void *Py_UNUSED(ignored)) { - if (gen->gi_frame_valid == 0) { - Py_RETURN_FALSE; + if (gen->gi_frame_state == FRAME_EXECUTING) { + Py_RETURN_TRUE; } - return PyBool_FromLong(_PyFrame_IsExecuting((_PyInterpreterFrame *)gen->gi_iframe)); + Py_RETURN_FALSE; } static PyObject * gen_getsuspended(PyGenObject *gen, void *Py_UNUSED(ignored)) { - if (gen->gi_frame_valid == 0) { - Py_RETURN_FALSE; - } - return PyBool_FromLong(((_PyInterpreterFrame *)gen->gi_iframe)->f_state == FRAME_SUSPENDED); + return PyBool_FromLong(gen->gi_frame_state == FRAME_SUSPENDED); } static PyObject * @@ -777,7 +775,7 @@ _gen_getframe(PyGenObject *gen, const char *const name) if (PySys_Audit("object.__getattr__", "Os", gen, name) < 0) { return NULL; } - if (gen->gi_frame_valid == 0) { + if (gen->gi_frame_state == FRAME_CLEARED) { Py_RETURN_NONE; } return _Py_XNewRef((PyObject *)_PyFrame_GetFrameObject((_PyInterpreterFrame *)gen->gi_iframe)); @@ -899,7 +897,7 @@ make_gen(PyTypeObject *type, PyFunctionObject *func) if (gen == NULL) { return NULL; } - gen->gi_frame_valid = 0; + gen->gi_frame_state = FRAME_CLEARED; gen->gi_code = (PyCodeObject *)func->func_code; Py_INCREF(gen->gi_code); gen->gi_weakreflist = NULL; @@ -972,14 +970,13 @@ gen_new_with_qualname(PyTypeObject *type, PyFrameObject *f, } /* Copy the frame */ assert(f->f_frame->frame_obj == NULL); - assert(f->f_owns_frame); + assert(f->f_frame->owner == FRAME_OWNED_BY_FRAME_OBJECT); _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe; _PyFrame_Copy((_PyInterpreterFrame *)f->_f_frame_data, frame); - gen->gi_frame_valid = 1; + gen->gi_frame_state = FRAME_CREATED; assert(frame->frame_obj == f); - f->f_owns_frame = 0; f->f_frame = frame; - frame->is_generator = true; + frame->owner = FRAME_OWNED_BY_GENERATOR; assert(PyObject_GC_IsTracked((PyObject *)f)); gen->gi_code = PyFrame_GetCode(f); Py_INCREF(gen->gi_code); @@ -1114,19 +1111,19 @@ coro_get_cr_await(PyCoroObject *coro, void *Py_UNUSED(ignored)) static PyObject * cr_getsuspended(PyCoroObject *coro, void *Py_UNUSED(ignored)) { - if (coro->cr_frame_valid == 0) { - Py_RETURN_FALSE; + if (coro->cr_frame_state == FRAME_SUSPENDED) { + Py_RETURN_TRUE; } - return PyBool_FromLong(((_PyInterpreterFrame *)coro->cr_iframe)->f_state == FRAME_SUSPENDED); + Py_RETURN_FALSE; } static PyObject * cr_getrunning(PyCoroObject *coro, void *Py_UNUSED(ignored)) { - if (coro->cr_frame_valid == 0) { - Py_RETURN_FALSE; + if (coro->cr_frame_state == FRAME_EXECUTING) { + Py_RETURN_TRUE; } - return PyBool_FromLong(_PyFrame_IsExecuting((_PyInterpreterFrame *)coro->cr_iframe)); + Py_RETURN_FALSE; } static PyObject * @@ -2063,7 +2060,6 @@ static PyObject * async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg) { PyGenObject *gen = (PyGenObject*)o->agt_gen; - _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe; PyObject *retval; if (o->agt_state == AWAITABLE_STATE_CLOSED) { @@ -2073,7 +2069,7 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg) return NULL; } - if (gen->gi_frame_valid == 0 || _PyFrameHasCompleted(frame)) { + if (gen->gi_frame_state >= FRAME_COMPLETED) { o->agt_state = AWAITABLE_STATE_CLOSED; PyErr_SetNone(PyExc_StopIteration); return NULL; diff --git a/Python/ceval.c b/Python/ceval.c index 7c6bfd46900e6..73179c810b7e5 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1730,7 +1730,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int PREDICTED(RESUME_QUICK); assert(tstate->cframe == &cframe); assert(frame == cframe.current_frame); - frame->f_state = FRAME_EXECUTING; if (_Py_atomic_load_relaxed(eval_breaker) && oparg < 2) { goto handle_eval_breaker; } @@ -2373,7 +2372,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int TARGET(RETURN_VALUE) { PyObject *retval = POP(); assert(EMPTY()); - frame->f_state = FRAME_RETURNED; _PyFrame_SetStackPointer(frame, stack_pointer); TRACE_FUNCTION_EXIT(); DTRACE_FUNCTION_EXIT(); @@ -2585,7 +2583,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int TARGET(YIELD_VALUE) { assert(frame->is_entry); PyObject *retval = POP(); - frame->f_state = FRAME_SUSPENDED; + _PyFrame_GetGenerator(frame)->gi_frame_state = FRAME_SUSPENDED; _PyFrame_SetStackPointer(frame, stack_pointer); TRACE_FUNCTION_EXIT(); DTRACE_FUNCTION_EXIT(); @@ -4068,7 +4066,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int * generator or coroutine, so we deliberately do not check it here. * (see bpo-30039). */ - frame->f_state = FRAME_EXECUTING; JUMPTO(oparg); DISPATCH(); } @@ -5253,9 +5250,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; _PyFrame_Copy(frame, gen_frame); assert(frame->frame_obj == NULL); - gen->gi_frame_valid = 1; - gen_frame->is_generator = true; - gen_frame->f_state = FRAME_CREATED; + gen->gi_frame_state = FRAME_CREATED; + gen_frame->owner = FRAME_OWNED_BY_GENERATOR; _Py_LeaveRecursiveCall(tstate); if (!frame->is_entry) { _PyInterpreterFrame *prev = frame->previous; @@ -5429,41 +5425,47 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int int instr_prev = frame->f_lasti; frame->f_lasti = INSTR_OFFSET(); TRACING_NEXTOPARG(); - if (opcode == RESUME) { - if (oparg < 2) { - CHECK_EVAL_BREAKER(); - } - /* Call tracing */ - TRACE_FUNCTION_ENTRY(); - DTRACE_FUNCTION_ENTRY(); - } - else if (frame->f_state > FRAME_CREATED) { - /* line-by-line tracing support */ - if (PyDTrace_LINE_ENABLED()) { - maybe_dtrace_line(frame, &tstate->trace_info, instr_prev); - } - - if (cframe.use_tracing && - tstate->c_tracefunc != NULL && !tstate->tracing) { - int err; - /* see maybe_call_line_trace() - for expository comments */ - _PyFrame_SetStackPointer(frame, stack_pointer); - - err = maybe_call_line_trace(tstate->c_tracefunc, - tstate->c_traceobj, - tstate, frame, instr_prev); - if (err) { - /* trace function raised an exception */ - next_instr++; - goto error; + switch(opcode) { + case COPY_FREE_VARS: + case MAKE_CELL: + case RETURN_GENERATOR: + /* Frame not fully initialized */ + break; + case RESUME: + if (oparg < 2) { + CHECK_EVAL_BREAKER(); + } + /* Call tracing */ + TRACE_FUNCTION_ENTRY(); + DTRACE_FUNCTION_ENTRY(); + break; + default: + /* line-by-line tracing support */ + if (PyDTrace_LINE_ENABLED()) { + maybe_dtrace_line(frame, &tstate->trace_info, instr_prev); } - /* Reload possibly changed frame fields */ - JUMPTO(frame->f_lasti); - stack_pointer = _PyFrame_GetStackPointer(frame); - frame->stacktop = -1; - } + if (cframe.use_tracing && + tstate->c_tracefunc != NULL && !tstate->tracing) { + int err; + /* see maybe_call_line_trace() + for expository comments */ + _PyFrame_SetStackPointer(frame, stack_pointer); + + err = maybe_call_line_trace(tstate->c_tracefunc, + tstate->c_traceobj, + tstate, frame, instr_prev); + if (err) { + /* trace function raised an exception */ + next_instr++; + goto error; + } + /* Reload possibly changed frame fields */ + JUMPTO(frame->f_lasti); + + stack_pointer = _PyFrame_GetStackPointer(frame); + frame->stacktop = -1; + } } } TRACING_NEXTOPARG(); @@ -5558,65 +5560,63 @@ MISS_WITH_INLINE_CACHE(STORE_SUBSCR) if (tstate->c_tracefunc != NULL) { /* Make sure state is set to FRAME_UNWINDING for tracing */ - frame->f_state = FRAME_UNWINDING; call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, frame); } exception_unwind: - frame->f_state = FRAME_UNWINDING; - /* We can't use frame->f_lasti here, as RERAISE may have set it */ - int offset = INSTR_OFFSET()-1; - int level, handler, lasti; - if (get_exception_handler(frame->f_code, offset, &level, &handler, &lasti) == 0) { - // No handlers, so exit. - assert(_PyErr_Occurred(tstate)); - - /* Pop remaining stack entries. */ - PyObject **stackbase = _PyFrame_Stackbase(frame); - while (stack_pointer > stackbase) { - PyObject *o = POP(); - Py_XDECREF(o); - } - assert(STACK_LEVEL() == 0); - _PyFrame_SetStackPointer(frame, stack_pointer); - frame->f_state = FRAME_RAISED; - TRACE_FUNCTION_UNWIND(); - DTRACE_FUNCTION_EXIT(); - goto exit_unwind; - } + { + /* We can't use frame->f_lasti here, as RERAISE may have set it */ + int offset = INSTR_OFFSET()-1; + int level, handler, lasti; + if (get_exception_handler(frame->f_code, offset, &level, &handler, &lasti) == 0) { + // No handlers, so exit. + assert(_PyErr_Occurred(tstate)); + + /* Pop remaining stack entries. */ + PyObject **stackbase = _PyFrame_Stackbase(frame); + while (stack_pointer > stackbase) { + PyObject *o = POP(); + Py_XDECREF(o); + } + assert(STACK_LEVEL() == 0); + _PyFrame_SetStackPointer(frame, stack_pointer); + TRACE_FUNCTION_UNWIND(); + DTRACE_FUNCTION_EXIT(); + goto exit_unwind; + } - assert(STACK_LEVEL() >= level); - PyObject **new_top = _PyFrame_Stackbase(frame) + level; - while (stack_pointer > new_top) { - PyObject *v = POP(); - Py_XDECREF(v); - } - PyObject *exc, *val, *tb; - if (lasti) { - PyObject *lasti = PyLong_FromLong(frame->f_lasti); - if (lasti == NULL) { - goto exception_unwind; + assert(STACK_LEVEL() >= level); + PyObject **new_top = _PyFrame_Stackbase(frame) + level; + while (stack_pointer > new_top) { + PyObject *v = POP(); + Py_XDECREF(v); } - PUSH(lasti); + PyObject *exc, *val, *tb; + if (lasti) { + PyObject *lasti = PyLong_FromLong(frame->f_lasti); + if (lasti == NULL) { + goto exception_unwind; + } + PUSH(lasti); + } + _PyErr_Fetch(tstate, &exc, &val, &tb); + /* Make the raw exception data + available to the handler, + so a program can emulate the + Python main loop. */ + _PyErr_NormalizeException(tstate, &exc, &val, &tb); + if (tb != NULL) + PyException_SetTraceback(val, tb); + else + PyException_SetTraceback(val, Py_None); + Py_XDECREF(tb); + Py_XDECREF(exc); + PUSH(val); + JUMPTO(handler); + /* Resume normal execution */ + DISPATCH(); } - _PyErr_Fetch(tstate, &exc, &val, &tb); - /* Make the raw exception data - available to the handler, - so a program can emulate the - Python main loop. */ - _PyErr_NormalizeException(tstate, &exc, &val, &tb); - if (tb != NULL) - PyException_SetTraceback(val, tb); - else - PyException_SetTraceback(val, Py_None); - Py_XDECREF(tb); - Py_XDECREF(exc); - PUSH(val); - JUMPTO(handler); - /* Resume normal execution */ - frame->f_state = FRAME_EXECUTING; - DISPATCH(); } exit_unwind: @@ -6180,6 +6180,7 @@ _PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func, localsarray[i] = NULL; } if (initialize_locals(tstate, func, localsarray, args, argcount, kwnames)) { + assert(frame->owner != FRAME_OWNED_BY_GENERATOR); _PyFrame_Clear(frame); return NULL; } @@ -6203,7 +6204,8 @@ static void _PyEvalFrameClearAndPop(PyThreadState *tstate, _PyInterpreterFrame * frame) { tstate->recursion_remaining--; - assert(frame->frame_obj == NULL || frame->frame_obj->f_owns_frame == 0); + assert(frame->frame_obj == NULL || frame->frame_obj->f_frame == frame); + assert(frame->owner == FRAME_OWNED_BY_THREAD); _PyFrame_Clear(frame); tstate->recursion_remaining++; _PyThreadState_PopFrame(tstate, frame); @@ -6681,6 +6683,8 @@ call_trace(Py_tracefunc func, PyObject *obj, if (f == NULL) { return -1; } + int old_what = tstate->tracing_what; + tstate->tracing_what = what; PyThreadState_EnterTracing(tstate); assert (frame->f_lasti >= 0); initialize_trace_info(&tstate->trace_info, frame); @@ -6688,6 +6692,7 @@ call_trace(Py_tracefunc func, PyObject *obj, result = func(obj, f, what, arg); f->f_lineno = 0; PyThreadState_LeaveTracing(tstate); + tstate->tracing_what = old_what; return result; } diff --git a/Python/frame.c b/Python/frame.c index 20b4f81425bc8..3396ed8d2aeb0 100644 --- a/Python/frame.c +++ b/Python/frame.c @@ -37,7 +37,8 @@ _PyFrame_MakeAndSetFrameObject(_PyInterpreterFrame *frame) Py_XDECREF(error_traceback); } else { - f->f_owns_frame = 0; + assert(frame->owner != FRAME_OWNED_BY_FRAME_OBJECT); + assert(frame->owner != FRAME_CLEARED); f->f_frame = frame; frame->frame_obj = f; PyErr_Restore(error_type, error_value, error_traceback); @@ -57,12 +58,13 @@ _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest) static void take_ownership(PyFrameObject *f, _PyInterpreterFrame *frame) { - assert(f->f_owns_frame == 0); + assert(frame->owner != FRAME_OWNED_BY_FRAME_OBJECT); + assert(frame->owner != FRAME_CLEARED); Py_ssize_t size = ((char*)&frame->localsplus[frame->stacktop]) - (char *)frame; memcpy((_PyInterpreterFrame *)f->_f_frame_data, frame, size); frame = (_PyInterpreterFrame *)f->_f_frame_data; - f->f_owns_frame = 1; f->f_frame = frame; + frame->owner = FRAME_OWNED_BY_FRAME_OBJECT; assert(f->f_back == NULL); if (frame->previous != NULL) { /* Link PyFrameObjects.f_back and remove link through _PyInterpreterFrame.previous */ @@ -88,7 +90,8 @@ _PyFrame_Clear(_PyInterpreterFrame *frame) { /* It is the responsibility of the owning generator/coroutine * to have cleared the enclosing generator, if any. */ - assert(!frame->is_generator); + assert(frame->owner != FRAME_OWNED_BY_GENERATOR || + _PyFrame_GetGenerator(frame)->gi_frame_state == FRAME_CLEARED); if (frame->frame_obj) { PyFrameObject *f = frame->frame_obj; frame->frame_obj = NULL; From webhook-mailer at python.org Tue Mar 22 10:00:35 2022 From: webhook-mailer at python.org (asvetlov) Date: Tue, 22 Mar 2022 14:00:35 -0000 Subject: [Python-checkins] bpo-47076: Make asyncio.Queue stable on slow test boxes (GH-32040) Message-ID: https://github.com/python/cpython/commit/673755bfbac46b3cd2c84d7e0d68c2c488e039c3 commit: 673755bfbac46b3cd2c84d7e0d68c2c488e039c3 branch: main author: Andrew Svetlov committer: asvetlov date: 2022-03-22T16:00:23+02:00 summary: bpo-47076: Make asyncio.Queue stable on slow test boxes (GH-32040) files: M Lib/test/test_asyncio/test_queues.py diff --git a/Lib/test/test_asyncio/test_queues.py b/Lib/test/test_asyncio/test_queues.py index 55588e8b729e1..2d058ccf6a8c7 100644 --- a/Lib/test/test_asyncio/test_queues.py +++ b/Lib/test/test_asyncio/test_queues.py @@ -28,7 +28,7 @@ async def _test_repr_or_str(self, fn, expect_id): # Start a task that waits to get. getter = tg.create_task(q.get()) # Let it start waiting. - await asyncio.sleep(0.1) + await asyncio.sleep(0) self.assertTrue('_getters[1]' in fn(q)) # resume q.get coroutine to finish generator q.put_nowait(0) @@ -42,7 +42,7 @@ async def _test_repr_or_str(self, fn, expect_id): # Start a task that waits to put. putter = tg.create_task(q.put(2)) # Let it start waiting. - await asyncio.sleep(0.1) + await asyncio.sleep(0) self.assertTrue('_putters[1]' in fn(q)) # resume q.put coroutine to finish generator q.get_nowait() @@ -100,14 +100,15 @@ async def putter(): return True t = asyncio.create_task(putter()) - await asyncio.sleep(0.01) + for i in range(2): + await asyncio.sleep(0) # The putter is blocked after putting two items. self.assertEqual([0, 1], have_been_put) self.assertEqual(0, await q.get()) # Let the putter resume and put last item. - await asyncio.sleep(0.01) + await asyncio.sleep(0) self.assertEqual([0, 1, 2], have_been_put) self.assertEqual(1, await q.get()) self.assertEqual(2, await q.get()) @@ -150,10 +151,10 @@ async def queue_get(): finished = True return res - loop.call_later(0.01, q.put_nowait, 1) queue_get_task = asyncio.create_task(queue_get()) await started.wait() self.assertFalse(finished) + loop.call_later(0.01, q.put_nowait, 1) res = await queue_get_task self.assertTrue(finished) self.assertEqual(1, res) @@ -167,17 +168,6 @@ def test_nonblocking_get_exception(self): q = asyncio.Queue() self.assertRaises(asyncio.QueueEmpty, q.get_nowait) - async def test_get_cancelled(self): - q = asyncio.Queue() - - async def queue_get(): - return await asyncio.wait_for(q.get(), 0.051) - - get_task = asyncio.create_task(queue_get()) - await asyncio.sleep(0.01) # let the task start - q.put_nowait(1) - self.assertEqual(1, await get_task) - async def test_get_cancelled_race(self): q = asyncio.Queue() @@ -263,7 +253,7 @@ async def test_get_cancel_drop_one_pending_reader(self): reader = asyncio.create_task(q.get()) - await asyncio.sleep(0.01) + await asyncio.sleep(0) q.put_nowait(1) q.put_nowait(2) @@ -288,7 +278,7 @@ async def test_get_cancel_drop_many_pending_readers(self): reader2 = tg.create_task(q.get()) reader3 = tg.create_task(q.get()) - await asyncio.sleep(0.01) + await asyncio.sleep(0) q.put_nowait(1) q.put_nowait(2) @@ -309,7 +299,7 @@ async def test_put_cancel_drop(self): # putting a second item in the queue has to block (qsize=1) writer = asyncio.create_task(q.put(2)) - await asyncio.sleep(0.01) + await asyncio.sleep(0) value1 = q.get_nowait() self.assertEqual(value1, 1) @@ -410,7 +400,7 @@ async def test_cancelled_puts_not_being_held_in_self_putters(self): # Task waiting for space to put an item in the queue. put_task = asyncio.create_task(queue.put(1)) - await asyncio.sleep(0.01) + await asyncio.sleep(0) # Check that the putter is correctly removed from queue._putters when # the task is canceled. @@ -427,7 +417,7 @@ async def test_cancelled_put_silence_value_error_exception(self): # Task waiting for space to put a item in the queue. put_task = asyncio.create_task(queue.put(1)) - await asyncio.sleep(0.01) + await asyncio.sleep(0) # get_nowait() remove the future of put_task from queue._putters. queue.get_nowait() From webhook-mailer at python.org Tue Mar 22 10:03:01 2022 From: webhook-mailer at python.org (asvetlov) Date: Tue, 22 Mar 2022 14:03:01 -0000 Subject: [Python-checkins] bpo-45997: Fix asyncio.Semaphore re-acquiring order (GH-31910) Message-ID: https://github.com/python/cpython/commit/32e77154ddfc514a3144d5912bffdd957246fd6c commit: 32e77154ddfc514a3144d5912bffdd957246fd6c branch: main author: Andrew Svetlov committer: asvetlov date: 2022-03-22T16:02:51+02:00 summary: bpo-45997: Fix asyncio.Semaphore re-acquiring order (GH-31910) Co-authored-by: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> files: A Misc/NEWS.d/next/Library/2022-03-15-18-32-12.bpo-45997.4n2aVU.rst M Lib/asyncio/locks.py M Lib/test/test_asyncio/test_locks.py diff --git a/Lib/asyncio/locks.py b/Lib/asyncio/locks.py index 0fbccfab7604f..9b4612197de1d 100644 --- a/Lib/asyncio/locks.py +++ b/Lib/asyncio/locks.py @@ -6,6 +6,7 @@ from . import exceptions from . import mixins +from . import tasks class _ContextManagerMixin: @@ -346,6 +347,7 @@ def __init__(self, value=1): raise ValueError("Semaphore initial value must be >= 0") self._value = value self._waiters = collections.deque() + self._wakeup_scheduled = False def __repr__(self): res = super().__repr__() @@ -359,6 +361,7 @@ def _wake_up_next(self): waiter = self._waiters.popleft() if not waiter.done(): waiter.set_result(None) + self._wakeup_scheduled = True return def locked(self): @@ -374,16 +377,17 @@ async def acquire(self): called release() to make it larger than 0, and then return True. """ - while self._value <= 0: + # _wakeup_scheduled is set if *another* task is scheduled to wakeup + # but its acquire() is not resumed yet + while self._wakeup_scheduled or self._value <= 0: fut = self._get_loop().create_future() self._waiters.append(fut) try: await fut - except: - # See the similar code in Queue.get. - fut.cancel() - if self._value > 0 and not fut.cancelled(): - self._wake_up_next() + # reset _wakeup_scheduled *after* waiting for a future + self._wakeup_scheduled = False + except exceptions.CancelledError: + self._wake_up_next() raise self._value -= 1 return True diff --git a/Lib/test/test_asyncio/test_locks.py b/Lib/test/test_asyncio/test_locks.py index d8b164a20ead4..920b3b5717a2c 100644 --- a/Lib/test/test_asyncio/test_locks.py +++ b/Lib/test/test_asyncio/test_locks.py @@ -917,6 +917,31 @@ async def test_release_no_waiters(self): sem.release() self.assertFalse(sem.locked()) + async def test_acquire_fifo_order(self): + sem = asyncio.Semaphore(1) + result = [] + + async def coro(tag): + await sem.acquire() + result.append(f'{tag}_1') + await asyncio.sleep(0.01) + sem.release() + + await sem.acquire() + result.append(f'{tag}_2') + await asyncio.sleep(0.01) + sem.release() + + async with asyncio.TaskGroup() as tg: + tg.create_task(coro('c1')) + tg.create_task(coro('c2')) + tg.create_task(coro('c3')) + + self.assertEqual( + ['c1_1', 'c2_1', 'c3_1', 'c1_2', 'c2_2', 'c3_2'], + result + ) + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2022-03-15-18-32-12.bpo-45997.4n2aVU.rst b/Misc/NEWS.d/next/Library/2022-03-15-18-32-12.bpo-45997.4n2aVU.rst new file mode 100644 index 0000000000000..40d8504e5a946 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-15-18-32-12.bpo-45997.4n2aVU.rst @@ -0,0 +1 @@ +Fix :class:`asyncio.Semaphore` re-aquiring FIFO order. From webhook-mailer at python.org Tue Mar 22 11:15:59 2022 From: webhook-mailer at python.org (asvetlov) Date: Tue, 22 Mar 2022 15:15:59 -0000 Subject: [Python-checkins] [3.10] bpo-45997: Fix asyncio.Semaphore re-acquiring order (GH-31910) (#32047) Message-ID: https://github.com/python/cpython/commit/9d59381a5d20157930bae34e5f5a7bc5ef09fa89 commit: 9d59381a5d20157930bae34e5f5a7bc5ef09fa89 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: asvetlov date: 2022-03-22T17:15:24+02:00 summary: [3.10] bpo-45997: Fix asyncio.Semaphore re-acquiring order (GH-31910) (#32047) Co-authored-by: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> (cherry picked from commit 32e77154ddfc514a3144d5912bffdd957246fd6c) Co-authored-by: Andrew Svetlov files: A Misc/NEWS.d/next/Library/2022-03-15-18-32-12.bpo-45997.4n2aVU.rst M Lib/asyncio/locks.py M Lib/test/test_asyncio/test_locks.py diff --git a/Lib/asyncio/locks.py b/Lib/asyncio/locks.py index 4fef64e3921e1..7b81c25b2d9e7 100644 --- a/Lib/asyncio/locks.py +++ b/Lib/asyncio/locks.py @@ -6,6 +6,7 @@ from . import exceptions from . import mixins +from . import tasks class _ContextManagerMixin: @@ -350,6 +351,7 @@ def __init__(self, value=1, *, loop=mixins._marker): raise ValueError("Semaphore initial value must be >= 0") self._value = value self._waiters = collections.deque() + self._wakeup_scheduled = False def __repr__(self): res = super().__repr__() @@ -363,6 +365,7 @@ def _wake_up_next(self): waiter = self._waiters.popleft() if not waiter.done(): waiter.set_result(None) + self._wakeup_scheduled = True return def locked(self): @@ -378,16 +381,17 @@ async def acquire(self): called release() to make it larger than 0, and then return True. """ - while self._value <= 0: + # _wakeup_scheduled is set if *another* task is scheduled to wakeup + # but its acquire() is not resumed yet + while self._wakeup_scheduled or self._value <= 0: fut = self._get_loop().create_future() self._waiters.append(fut) try: await fut - except: - # See the similar code in Queue.get. - fut.cancel() - if self._value > 0 and not fut.cancelled(): - self._wake_up_next() + # reset _wakeup_scheduled *after* waiting for a future + self._wakeup_scheduled = False + except exceptions.CancelledError: + self._wake_up_next() raise self._value -= 1 return True diff --git a/Lib/test/test_asyncio/test_locks.py b/Lib/test/test_asyncio/test_locks.py index e2cd2ba0365fd..c5e3fdcbc955a 100644 --- a/Lib/test/test_asyncio/test_locks.py +++ b/Lib/test/test_asyncio/test_locks.py @@ -933,6 +933,32 @@ async def test_release_no_waiters(self): sem.release() self.assertFalse(sem.locked()) + async def test_acquire_fifo_order(self): + sem = asyncio.Semaphore(1) + result = [] + + async def coro(tag): + await sem.acquire() + result.append(f'{tag}_1') + await asyncio.sleep(0.01) + sem.release() + + await sem.acquire() + result.append(f'{tag}_2') + await asyncio.sleep(0.01) + sem.release() + + t1 = asyncio.create_task(coro('c1')) + t2 = asyncio.create_task(coro('c2')) + t3 = asyncio.create_task(coro('c3')) + + await asyncio.gather(t1, t2, t3) + + self.assertEqual( + ['c1_1', 'c2_1', 'c3_1', 'c1_2', 'c2_2', 'c3_2'], + result + ) + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2022-03-15-18-32-12.bpo-45997.4n2aVU.rst b/Misc/NEWS.d/next/Library/2022-03-15-18-32-12.bpo-45997.4n2aVU.rst new file mode 100644 index 0000000000000..40d8504e5a946 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-15-18-32-12.bpo-45997.4n2aVU.rst @@ -0,0 +1 @@ +Fix :class:`asyncio.Semaphore` re-aquiring FIFO order. From webhook-mailer at python.org Tue Mar 22 11:16:40 2022 From: webhook-mailer at python.org (asvetlov) Date: Tue, 22 Mar 2022 15:16:40 -0000 Subject: [Python-checkins] [3.9] bpo-45997: Fix asyncio.Semaphore re-acquiring order (GH-31910) (GH-32049) Message-ID: https://github.com/python/cpython/commit/f47984b560f1dafe4d907cef4edadfb1746bf027 commit: f47984b560f1dafe4d907cef4edadfb1746bf027 branch: 3.9 author: Andrew Svetlov committer: asvetlov date: 2022-03-22T17:16:27+02:00 summary: [3.9] bpo-45997: Fix asyncio.Semaphore re-acquiring order (GH-31910) (GH-32049) Co-authored-by: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com>. (cherry picked from commit 32e77154ddfc514a3144d5912bffdd957246fd6c) Co-authored-by: Andrew Svetlov files: A Misc/NEWS.d/next/Library/2022-03-15-18-32-12.bpo-45997.4n2aVU.rst M Lib/asyncio/locks.py M Lib/test/test_asyncio/test_locks.py diff --git a/Lib/asyncio/locks.py b/Lib/asyncio/locks.py index f1ce7324785ba..d17d7ccd813d2 100644 --- a/Lib/asyncio/locks.py +++ b/Lib/asyncio/locks.py @@ -378,6 +378,7 @@ def __init__(self, value=1, *, loop=None): warnings.warn("The loop argument is deprecated since Python 3.8, " "and scheduled for removal in Python 3.10.", DeprecationWarning, stacklevel=2) + self._wakeup_scheduled = False def __repr__(self): res = super().__repr__() @@ -391,6 +392,7 @@ def _wake_up_next(self): waiter = self._waiters.popleft() if not waiter.done(): waiter.set_result(None) + self._wakeup_scheduled = True return def locked(self): @@ -406,16 +408,17 @@ async def acquire(self): called release() to make it larger than 0, and then return True. """ - while self._value <= 0: + # _wakeup_scheduled is set if *another* task is scheduled to wakeup + # but its acquire() is not resumed yet + while self._wakeup_scheduled or self._value <= 0: fut = self._loop.create_future() self._waiters.append(fut) try: await fut - except: - # See the similar code in Queue.get. - fut.cancel() - if self._value > 0 and not fut.cancelled(): - self._wake_up_next() + # reset _wakeup_scheduled *after* waiting for a future + self._wakeup_scheduled = False + except exceptions.CancelledError: + self._wake_up_next() raise self._value -= 1 return True diff --git a/Lib/test/test_asyncio/test_locks.py b/Lib/test/test_asyncio/test_locks.py index b9aae360384ea..79ebbd26804a5 100644 --- a/Lib/test/test_asyncio/test_locks.py +++ b/Lib/test/test_asyncio/test_locks.py @@ -961,6 +961,32 @@ async def test_release_no_waiters(self): sem.release() self.assertFalse(sem.locked()) + async def test_acquire_fifo_order(self): + sem = asyncio.Semaphore(1) + result = [] + + async def coro(tag): + await sem.acquire() + result.append(f'{tag}_1') + await asyncio.sleep(0.01) + sem.release() + + await sem.acquire() + result.append(f'{tag}_2') + await asyncio.sleep(0.01) + sem.release() + + t1 = asyncio.create_task(coro('c1')) + t2 = asyncio.create_task(coro('c2')) + t3 = asyncio.create_task(coro('c3')) + + await asyncio.gather(t1, t2, t3) + + self.assertEqual( + ['c1_1', 'c2_1', 'c3_1', 'c1_2', 'c2_2', 'c3_2'], + result + ) + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2022-03-15-18-32-12.bpo-45997.4n2aVU.rst b/Misc/NEWS.d/next/Library/2022-03-15-18-32-12.bpo-45997.4n2aVU.rst new file mode 100644 index 0000000000000..40d8504e5a946 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-15-18-32-12.bpo-45997.4n2aVU.rst @@ -0,0 +1 @@ +Fix :class:`asyncio.Semaphore` re-aquiring FIFO order. From webhook-mailer at python.org Tue Mar 22 11:28:06 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Tue, 22 Mar 2022 15:28:06 -0000 Subject: [Python-checkins] bpo-42885: Optimize search for regular expressions starting with "\A" or "^" (GH-32021) Message-ID: https://github.com/python/cpython/commit/492d4109f4d953c478cb48f17aa32adbb912623b commit: 492d4109f4d953c478cb48f17aa32adbb912623b branch: main author: Serhiy Storchaka committer: serhiy-storchaka date: 2022-03-22T17:27:55+02:00 summary: bpo-42885: Optimize search for regular expressions starting with "\A" or "^" (GH-32021) Affected functions are re.search(), re.split(), re.findall(), re.finditer() and re.sub(). files: A Misc/NEWS.d/next/Library/2022-03-21-08-32-19.bpo-42885.LCnTTp.rst M Lib/test/test_re.py M Modules/sre_lib.h diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index da827ca7c4e92..fd6db6a300d03 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -5,6 +5,7 @@ import re import sre_compile import string +import time import unittest import warnings from re import Scanner @@ -2038,6 +2039,20 @@ def test_bug_40736(self): with self.assertRaisesRegex(TypeError, "got 'type'"): re.search("x*", type) + def test_search_anchor_at_beginning(self): + s = 'x'*10**7 + start = time.perf_counter() + for p in r'\Ay', r'^y': + self.assertIsNone(re.search(p, s)) + self.assertEqual(re.split(p, s), [s]) + self.assertEqual(re.findall(p, s), []) + self.assertEqual(list(re.finditer(p, s)), []) + self.assertEqual(re.sub(p, '', s), s) + t = time.perf_counter() - start + # Without optimization it takes 1 second on my computer. + # With optimization -- 0.0003 seconds. + self.assertLess(t, 0.1) + def test_possessive_quantifiers(self): """Test Possessive Quantifiers Test quantifiers of the form @+ for some repetition operator @, diff --git a/Misc/NEWS.d/next/Library/2022-03-21-08-32-19.bpo-42885.LCnTTp.rst b/Misc/NEWS.d/next/Library/2022-03-21-08-32-19.bpo-42885.LCnTTp.rst new file mode 100644 index 0000000000000..5f9c1a19de221 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-21-08-32-19.bpo-42885.LCnTTp.rst @@ -0,0 +1,3 @@ +Optimize :func:`re.search`, :func:`re.split`, :func:`re.findall`, +:func:`re.finditer` and :func:`re.sub` for regular expressions starting with +``\A`` or ``^``. diff --git a/Modules/sre_lib.h b/Modules/sre_lib.h index 956fd3fad9164..a82210ff94a0f 100644 --- a/Modules/sre_lib.h +++ b/Modules/sre_lib.h @@ -1693,6 +1693,13 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern) state->start = state->ptr = ptr; status = SRE(match)(state, pattern, 1); state->must_advance = 0; + if (status == 0 && pattern[0] == SRE_OP_AT && + (pattern[1] == SRE_AT_BEGINNING || + pattern[1] == SRE_AT_BEGINNING_STRING)) + { + state->start = state->ptr = ptr = end; + return 0; + } while (status == 0 && ptr < end) { ptr++; RESET_CAPTURE_GROUP(); From webhook-mailer at python.org Tue Mar 22 11:41:05 2022 From: webhook-mailer at python.org (tiran) Date: Tue, 22 Mar 2022 15:41:05 -0000 Subject: [Python-checkins] bpo-45150: Fix testing under FIPS mode (GH-32046) Message-ID: https://github.com/python/cpython/commit/e03db6d5be7cf2e6b7b55284985c404de98a9420 commit: e03db6d5be7cf2e6b7b55284985c404de98a9420 branch: main author: Christian Heimes committer: tiran date: 2022-03-22T16:40:43+01:00 summary: bpo-45150: Fix testing under FIPS mode (GH-32046) files: M Lib/test/test_hashlib.py diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py index daf6e3862a24f..369bbde6e78b6 100644 --- a/Lib/test/test_hashlib.py +++ b/Lib/test/test_hashlib.py @@ -379,6 +379,11 @@ def check(self, name, data, hexdigest, shake=False, **kwargs): def check_file_digest(self, name, data, hexdigest): hexdigest = hexdigest.lower() + try: + hashlib.new(name) + except ValueError: + # skip, algorithm is blocked by security policy. + return digests = [name] digests.extend(self.constructors_to_test[name]) From webhook-mailer at python.org Tue Mar 22 13:21:33 2022 From: webhook-mailer at python.org (zooba) Date: Tue, 22 Mar 2022 17:21:33 -0000 Subject: [Python-checkins] bpo-44336: Prevent tests hanging on child process handles on Windows (GH-26578) Message-ID: https://github.com/python/cpython/commit/8146e6b636905d9872140c990d93308ac20d13f0 commit: 8146e6b636905d9872140c990d93308ac20d13f0 branch: 3.10 author: Jeremy Kloth committer: zooba date: 2022-03-22T17:21:24Z summary: bpo-44336: Prevent tests hanging on child process handles on Windows (GH-26578) Replace the child process `typeperf.exe` with a daemon thread that reads the performance counters directly. This prevents the issues that arise from inherited handles in grandchild processes (see issue37531 for discussion). We only use the load tracker when running tests in multiprocess mode. This prevents inadvertent interactions with tests expecting a single threaded environment. Displaying load is really only helpful for buildbots running in multiprocess mode anyway. Co-authored-by: Jeremy Kloth files: M Lib/test/libregrtest/main.py M Lib/test/libregrtest/win_utils.py diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py index 52cc065da115d..400a3db5de4d2 100644 --- a/Lib/test/libregrtest/main.py +++ b/Lib/test/libregrtest/main.py @@ -533,7 +533,24 @@ def run_tests(self): if self.ns.use_mp: from test.libregrtest.runtest_mp import run_tests_multiprocess - run_tests_multiprocess(self) + # If we're on windows and this is the parent runner (not a worker), + # track the load average. + if sys.platform == 'win32' and self.worker_test_name is None: + from test.libregrtest.win_utils import WindowsLoadTracker + + try: + self.win_load_tracker = WindowsLoadTracker() + except PermissionError as error: + # Standard accounts may not have access to the performance + # counters. + print(f'Failed to create WindowsLoadTracker: {error}') + + try: + run_tests_multiprocess(self) + finally: + if self.win_load_tracker is not None: + self.win_load_tracker.close() + self.win_load_tracker = None else: self.run_tests_sequential() @@ -695,28 +712,11 @@ def _main(self, tests, kwargs): self.list_cases() sys.exit(0) - # If we're on windows and this is the parent runner (not a worker), - # track the load average. - if sys.platform == 'win32' and self.worker_test_name is None: - from test.libregrtest.win_utils import WindowsLoadTracker - - try: - self.win_load_tracker = WindowsLoadTracker() - except FileNotFoundError as error: - # Windows IoT Core and Windows Nano Server do not provide - # typeperf.exe for x64, x86 or ARM - print(f'Failed to create WindowsLoadTracker: {error}') + self.run_tests() + self.display_result() - try: - self.run_tests() - self.display_result() - - if self.ns.verbose2 and self.bad: - self.rerun_failed_tests() - finally: - if self.win_load_tracker is not None: - self.win_load_tracker.close() - self.win_load_tracker = None + if self.ns.verbose2 and self.bad: + self.rerun_failed_tests() self.finalize() diff --git a/Lib/test/libregrtest/win_utils.py b/Lib/test/libregrtest/win_utils.py index a1cc2201147db..5736cdfd3c729 100644 --- a/Lib/test/libregrtest/win_utils.py +++ b/Lib/test/libregrtest/win_utils.py @@ -1,16 +1,11 @@ +import _overlapped +import _thread import _winapi import math -import msvcrt -import os -import subprocess -import uuid +import struct import winreg -from test.support import os_helper -from test.libregrtest.utils import print_warning -# Max size of asynchronous reads -BUFSIZE = 8192 # Seconds per measurement SAMPLING_INTERVAL = 1 # Exponential damping factor to compute exponentially weighted moving average @@ -19,174 +14,111 @@ # Initialize the load using the arithmetic mean of the first NVALUE values # of the Processor Queue Length NVALUE = 5 -# Windows registry subkey of HKEY_LOCAL_MACHINE where the counter names -# of typeperf are registered -COUNTER_REGISTRY_KEY = (r"SOFTWARE\Microsoft\Windows NT\CurrentVersion" - r"\Perflib\CurrentLanguage") class WindowsLoadTracker(): """ - This class asynchronously interacts with the `typeperf` command to read - the system load on Windows. Multiprocessing and threads can't be used - here because they interfere with the test suite's cases for those - modules. + This class asynchronously reads the performance counters to calculate + the system load on Windows. A "raw" thread is used here to prevent + interference with the test suite's cases for the threading module. """ def __init__(self): + # Pre-flight test for access to the performance data; + # `PermissionError` will be raised if not allowed + winreg.QueryInfoKey(winreg.HKEY_PERFORMANCE_DATA) + self._values = [] self._load = None - self._buffer = '' - self._popen = None - self.start() - - def start(self): - # Create a named pipe which allows for asynchronous IO in Windows - pipe_name = r'\\.\pipe\typeperf_output_' + str(uuid.uuid4()) - - open_mode = _winapi.PIPE_ACCESS_INBOUND - open_mode |= _winapi.FILE_FLAG_FIRST_PIPE_INSTANCE - open_mode |= _winapi.FILE_FLAG_OVERLAPPED - - # This is the read end of the pipe, where we will be grabbing output - self.pipe = _winapi.CreateNamedPipe( - pipe_name, open_mode, _winapi.PIPE_WAIT, - 1, BUFSIZE, BUFSIZE, _winapi.NMPWAIT_WAIT_FOREVER, _winapi.NULL - ) - # The write end of the pipe which is passed to the created process - pipe_write_end = _winapi.CreateFile( - pipe_name, _winapi.GENERIC_WRITE, 0, _winapi.NULL, - _winapi.OPEN_EXISTING, 0, _winapi.NULL - ) - # Open up the handle as a python file object so we can pass it to - # subprocess - command_stdout = msvcrt.open_osfhandle(pipe_write_end, 0) - - # Connect to the read end of the pipe in overlap/async mode - overlap = _winapi.ConnectNamedPipe(self.pipe, overlapped=True) - overlap.GetOverlappedResult(True) - - # Spawn off the load monitor - counter_name = self._get_counter_name() - command = ['typeperf', counter_name, '-si', str(SAMPLING_INTERVAL)] - self._popen = subprocess.Popen(' '.join(command), - stdout=command_stdout, - cwd=os_helper.SAVEDCWD) - - # Close our copy of the write end of the pipe - os.close(command_stdout) - - def _get_counter_name(self): - # accessing the registry to get the counter localization name - with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, COUNTER_REGISTRY_KEY) as perfkey: - counters = winreg.QueryValueEx(perfkey, 'Counter')[0] - - # Convert [key1, value1, key2, value2, ...] list - # to {key1: value1, key2: value2, ...} dict - counters = iter(counters) - counters_dict = dict(zip(counters, counters)) - - # System counter has key '2' and Processor Queue Length has key '44' - system = counters_dict['2'] - process_queue_length = counters_dict['44'] - return f'"\\{system}\\{process_queue_length}"' - - def close(self, kill=True): - if self._popen is None: + self._running = _overlapped.CreateEvent(None, True, False, None) + self._stopped = _overlapped.CreateEvent(None, True, False, None) + + _thread.start_new_thread(self._update_load, (), {}) + + def _update_load(self, + # localize module access to prevent shutdown errors + _wait=_winapi.WaitForSingleObject, + _signal=_overlapped.SetEvent): + # run until signaled to stop + while _wait(self._running, 1000): + self._calculate_load() + # notify stopped + _signal(self._stopped) + + def _calculate_load(self, + # localize module access to prevent shutdown errors + _query=winreg.QueryValueEx, + _hkey=winreg.HKEY_PERFORMANCE_DATA, + _unpack=struct.unpack_from): + # get the 'System' object + data, _ = _query(_hkey, '2') + # PERF_DATA_BLOCK { + # WCHAR Signature[4] 8 + + # DWOWD LittleEndian 4 + + # DWORD Version 4 + + # DWORD Revision 4 + + # DWORD TotalByteLength 4 + + # DWORD HeaderLength = 24 byte offset + # ... + # } + obj_start, = _unpack('L', data, 24) + # PERF_OBJECT_TYPE { + # DWORD TotalByteLength + # DWORD DefinitionLength + # DWORD HeaderLength + # ... + # } + data_start, defn_start = _unpack('4xLL', data, obj_start) + data_base = obj_start + data_start + defn_base = obj_start + defn_start + # find the 'Processor Queue Length' counter (index=44) + while defn_base < data_base: + # PERF_COUNTER_DEFINITION { + # DWORD ByteLength + # DWORD CounterNameTitleIndex + # ... [7 DWORDs/28 bytes] + # DWORD CounterOffset + # } + size, idx, offset = _unpack('LL28xL', data, defn_base) + defn_base += size + if idx == 44: + counter_offset = data_base + offset + # the counter is known to be PERF_COUNTER_RAWCOUNT (DWORD) + processor_queue_length, = _unpack('L', data, counter_offset) + break + else: return - self._load = None - - if kill: - self._popen.kill() - self._popen.wait() - self._popen = None - - def __del__(self): - self.close() - - def _parse_line(self, line): - # typeperf outputs in a CSV format like this: - # "07/19/2018 01:32:26.605","3.000000" - # (date, process queue length) - tokens = line.split(',') - if len(tokens) != 2: - raise ValueError - - value = tokens[1] - if not value.startswith('"') or not value.endswith('"'): - raise ValueError - value = value[1:-1] - return float(value) - - def _read_lines(self): - overlapped, _ = _winapi.ReadFile(self.pipe, BUFSIZE, True) - bytes_read, res = overlapped.GetOverlappedResult(False) - if res != 0: - return () - - output = overlapped.getbuffer() - output = output.decode('oem', 'replace') - output = self._buffer + output - lines = output.splitlines(True) - - # bpo-36670: typeperf only writes a newline *before* writing a value, - # not after. Sometimes, the written line in incomplete (ex: only - # timestamp, without the process queue length). Only pass the last line - # to the parser if it's a valid value, otherwise store it in - # self._buffer. - try: - self._parse_line(lines[-1]) - except ValueError: - self._buffer = lines.pop(-1) + # We use an exponentially weighted moving average, imitating the + # load calculation on Unix systems. + # https://en.wikipedia.org/wiki/Load_(computing)#Unix-style_load_calculation + # https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average + if self._load is not None: + self._load = (self._load * LOAD_FACTOR_1 + + processor_queue_length * (1.0 - LOAD_FACTOR_1)) + elif len(self._values) < NVALUE: + self._values.append(processor_queue_length) else: - self._buffer = '' + self._load = sum(self._values) / len(self._values) - return lines + def close(self, kill=True): + self.__del__() + return + + def __del__(self, + # localize module access to prevent shutdown errors + _wait=_winapi.WaitForSingleObject, + _close=_winapi.CloseHandle, + _signal=_overlapped.SetEvent): + if self._running is not None: + # tell the update thread to quit + _signal(self._running) + # wait for the update thread to signal done + _wait(self._stopped, -1) + # cleanup events + _close(self._running) + _close(self._stopped) + self._running = self._stopped = None def getloadavg(self): - if self._popen is None: - return None - - returncode = self._popen.poll() - if returncode is not None: - self.close(kill=False) - return None - - try: - lines = self._read_lines() - except BrokenPipeError: - self.close() - return None - - for line in lines: - line = line.rstrip() - - # Ignore the initial header: - # "(PDH-CSV 4.0)","\\\\WIN\\System\\Processor Queue Length" - if 'PDH-CSV' in line: - continue - - # Ignore blank lines - if not line: - continue - - try: - processor_queue_length = self._parse_line(line) - except ValueError: - print_warning("Failed to parse typeperf output: %a" % line) - continue - - # We use an exponentially weighted moving average, imitating the - # load calculation on Unix systems. - # https://en.wikipedia.org/wiki/Load_(computing)#Unix-style_load_calculation - # https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average - if self._load is not None: - self._load = (self._load * LOAD_FACTOR_1 - + processor_queue_length * (1.0 - LOAD_FACTOR_1)) - elif len(self._values) < NVALUE: - self._values.append(processor_queue_length) - else: - self._load = sum(self._values) / len(self._values) - return self._load From webhook-mailer at python.org Tue Mar 22 13:21:40 2022 From: webhook-mailer at python.org (zooba) Date: Tue, 22 Mar 2022 17:21:40 -0000 Subject: [Python-checkins] bpo-44336: Prevent tests hanging on child process handles on Windows (GH-26578) Message-ID: https://github.com/python/cpython/commit/8db7610d1a7b1f90631bac26261338f27bd20727 commit: 8db7610d1a7b1f90631bac26261338f27bd20727 branch: 3.9 author: Jeremy Kloth committer: zooba date: 2022-03-22T17:21:35Z summary: bpo-44336: Prevent tests hanging on child process handles on Windows (GH-26578) Replace the child process `typeperf.exe` with a daemon thread that reads the performance counters directly. This prevents the issues that arise from inherited handles in grandchild processes (see issue37531 for discussion). We only use the load tracker when running tests in multiprocess mode. This prevents inadvertent interactions with tests expecting a single threaded environment. Displaying load is really only helpful for buildbots running in multiprocess mode anyway.. Co-authored-by: Jeremy Kloth files: M Lib/test/libregrtest/main.py M Lib/test/libregrtest/win_utils.py diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py index 56458afd290bb..6e7abdc322d83 100644 --- a/Lib/test/libregrtest/main.py +++ b/Lib/test/libregrtest/main.py @@ -530,7 +530,24 @@ def run_tests(self): if self.ns.use_mp: from test.libregrtest.runtest_mp import run_tests_multiprocess - run_tests_multiprocess(self) + # If we're on windows and this is the parent runner (not a worker), + # track the load average. + if sys.platform == 'win32' and self.worker_test_name is None: + from test.libregrtest.win_utils import WindowsLoadTracker + + try: + self.win_load_tracker = WindowsLoadTracker() + except PermissionError as error: + # Standard accounts may not have access to the performance + # counters. + print(f'Failed to create WindowsLoadTracker: {error}') + + try: + run_tests_multiprocess(self) + finally: + if self.win_load_tracker is not None: + self.win_load_tracker.close() + self.win_load_tracker = None else: self.run_tests_sequential() @@ -692,28 +709,11 @@ def _main(self, tests, kwargs): self.list_cases() sys.exit(0) - # If we're on windows and this is the parent runner (not a worker), - # track the load average. - if sys.platform == 'win32' and self.worker_test_name is None: - from test.libregrtest.win_utils import WindowsLoadTracker - - try: - self.win_load_tracker = WindowsLoadTracker() - except FileNotFoundError as error: - # Windows IoT Core and Windows Nano Server do not provide - # typeperf.exe for x64, x86 or ARM - print(f'Failed to create WindowsLoadTracker: {error}') + self.run_tests() + self.display_result() - try: - self.run_tests() - self.display_result() - - if self.ns.verbose2 and self.bad: - self.rerun_failed_tests() - finally: - if self.win_load_tracker is not None: - self.win_load_tracker.close() - self.win_load_tracker = None + if self.ns.verbose2 and self.bad: + self.rerun_failed_tests() self.finalize() diff --git a/Lib/test/libregrtest/win_utils.py b/Lib/test/libregrtest/win_utils.py index 028c01106dee0..5736cdfd3c729 100644 --- a/Lib/test/libregrtest/win_utils.py +++ b/Lib/test/libregrtest/win_utils.py @@ -1,16 +1,11 @@ +import _overlapped +import _thread import _winapi import math -import msvcrt -import os -import subprocess -import uuid +import struct import winreg -from test import support -from test.libregrtest.utils import print_warning -# Max size of asynchronous reads -BUFSIZE = 8192 # Seconds per measurement SAMPLING_INTERVAL = 1 # Exponential damping factor to compute exponentially weighted moving average @@ -19,172 +14,111 @@ # Initialize the load using the arithmetic mean of the first NVALUE values # of the Processor Queue Length NVALUE = 5 -# Windows registry subkey of HKEY_LOCAL_MACHINE where the counter names -# of typeperf are registered -COUNTER_REGISTRY_KEY = (r"SOFTWARE\Microsoft\Windows NT\CurrentVersion" - r"\Perflib\CurrentLanguage") class WindowsLoadTracker(): """ - This class asynchronously interacts with the `typeperf` command to read - the system load on Windows. Multiprocessing and threads can't be used - here because they interfere with the test suite's cases for those - modules. + This class asynchronously reads the performance counters to calculate + the system load on Windows. A "raw" thread is used here to prevent + interference with the test suite's cases for the threading module. """ def __init__(self): + # Pre-flight test for access to the performance data; + # `PermissionError` will be raised if not allowed + winreg.QueryInfoKey(winreg.HKEY_PERFORMANCE_DATA) + self._values = [] self._load = None - self._buffer = '' - self._popen = None - self.start() - - def start(self): - # Create a named pipe which allows for asynchronous IO in Windows - pipe_name = r'\\.\pipe\typeperf_output_' + str(uuid.uuid4()) - - open_mode = _winapi.PIPE_ACCESS_INBOUND - open_mode |= _winapi.FILE_FLAG_FIRST_PIPE_INSTANCE - open_mode |= _winapi.FILE_FLAG_OVERLAPPED - - # This is the read end of the pipe, where we will be grabbing output - self.pipe = _winapi.CreateNamedPipe( - pipe_name, open_mode, _winapi.PIPE_WAIT, - 1, BUFSIZE, BUFSIZE, _winapi.NMPWAIT_WAIT_FOREVER, _winapi.NULL - ) - # The write end of the pipe which is passed to the created process - pipe_write_end = _winapi.CreateFile( - pipe_name, _winapi.GENERIC_WRITE, 0, _winapi.NULL, - _winapi.OPEN_EXISTING, 0, _winapi.NULL - ) - # Open up the handle as a python file object so we can pass it to - # subprocess - command_stdout = msvcrt.open_osfhandle(pipe_write_end, 0) - - # Connect to the read end of the pipe in overlap/async mode - overlap = _winapi.ConnectNamedPipe(self.pipe, overlapped=True) - overlap.GetOverlappedResult(True) - - # Spawn off the load monitor - counter_name = self._get_counter_name() - command = ['typeperf', counter_name, '-si', str(SAMPLING_INTERVAL)] - self._popen = subprocess.Popen(' '.join(command), stdout=command_stdout, cwd=support.SAVEDCWD) - - # Close our copy of the write end of the pipe - os.close(command_stdout) - - def _get_counter_name(self): - # accessing the registry to get the counter localization name - with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, COUNTER_REGISTRY_KEY) as perfkey: - counters = winreg.QueryValueEx(perfkey, 'Counter')[0] - - # Convert [key1, value1, key2, value2, ...] list - # to {key1: value1, key2: value2, ...} dict - counters = iter(counters) - counters_dict = dict(zip(counters, counters)) - - # System counter has key '2' and Processor Queue Length has key '44' - system = counters_dict['2'] - process_queue_length = counters_dict['44'] - return f'"\\{system}\\{process_queue_length}"' - - def close(self, kill=True): - if self._popen is None: + self._running = _overlapped.CreateEvent(None, True, False, None) + self._stopped = _overlapped.CreateEvent(None, True, False, None) + + _thread.start_new_thread(self._update_load, (), {}) + + def _update_load(self, + # localize module access to prevent shutdown errors + _wait=_winapi.WaitForSingleObject, + _signal=_overlapped.SetEvent): + # run until signaled to stop + while _wait(self._running, 1000): + self._calculate_load() + # notify stopped + _signal(self._stopped) + + def _calculate_load(self, + # localize module access to prevent shutdown errors + _query=winreg.QueryValueEx, + _hkey=winreg.HKEY_PERFORMANCE_DATA, + _unpack=struct.unpack_from): + # get the 'System' object + data, _ = _query(_hkey, '2') + # PERF_DATA_BLOCK { + # WCHAR Signature[4] 8 + + # DWOWD LittleEndian 4 + + # DWORD Version 4 + + # DWORD Revision 4 + + # DWORD TotalByteLength 4 + + # DWORD HeaderLength = 24 byte offset + # ... + # } + obj_start, = _unpack('L', data, 24) + # PERF_OBJECT_TYPE { + # DWORD TotalByteLength + # DWORD DefinitionLength + # DWORD HeaderLength + # ... + # } + data_start, defn_start = _unpack('4xLL', data, obj_start) + data_base = obj_start + data_start + defn_base = obj_start + defn_start + # find the 'Processor Queue Length' counter (index=44) + while defn_base < data_base: + # PERF_COUNTER_DEFINITION { + # DWORD ByteLength + # DWORD CounterNameTitleIndex + # ... [7 DWORDs/28 bytes] + # DWORD CounterOffset + # } + size, idx, offset = _unpack('LL28xL', data, defn_base) + defn_base += size + if idx == 44: + counter_offset = data_base + offset + # the counter is known to be PERF_COUNTER_RAWCOUNT (DWORD) + processor_queue_length, = _unpack('L', data, counter_offset) + break + else: return - self._load = None - - if kill: - self._popen.kill() - self._popen.wait() - self._popen = None - - def __del__(self): - self.close() - - def _parse_line(self, line): - # typeperf outputs in a CSV format like this: - # "07/19/2018 01:32:26.605","3.000000" - # (date, process queue length) - tokens = line.split(',') - if len(tokens) != 2: - raise ValueError - - value = tokens[1] - if not value.startswith('"') or not value.endswith('"'): - raise ValueError - value = value[1:-1] - return float(value) - - def _read_lines(self): - overlapped, _ = _winapi.ReadFile(self.pipe, BUFSIZE, True) - bytes_read, res = overlapped.GetOverlappedResult(False) - if res != 0: - return () - - output = overlapped.getbuffer() - output = output.decode('oem', 'replace') - output = self._buffer + output - lines = output.splitlines(True) - - # bpo-36670: typeperf only writes a newline *before* writing a value, - # not after. Sometimes, the written line in incomplete (ex: only - # timestamp, without the process queue length). Only pass the last line - # to the parser if it's a valid value, otherwise store it in - # self._buffer. - try: - self._parse_line(lines[-1]) - except ValueError: - self._buffer = lines.pop(-1) + # We use an exponentially weighted moving average, imitating the + # load calculation on Unix systems. + # https://en.wikipedia.org/wiki/Load_(computing)#Unix-style_load_calculation + # https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average + if self._load is not None: + self._load = (self._load * LOAD_FACTOR_1 + + processor_queue_length * (1.0 - LOAD_FACTOR_1)) + elif len(self._values) < NVALUE: + self._values.append(processor_queue_length) else: - self._buffer = '' + self._load = sum(self._values) / len(self._values) - return lines + def close(self, kill=True): + self.__del__() + return + + def __del__(self, + # localize module access to prevent shutdown errors + _wait=_winapi.WaitForSingleObject, + _close=_winapi.CloseHandle, + _signal=_overlapped.SetEvent): + if self._running is not None: + # tell the update thread to quit + _signal(self._running) + # wait for the update thread to signal done + _wait(self._stopped, -1) + # cleanup events + _close(self._running) + _close(self._stopped) + self._running = self._stopped = None def getloadavg(self): - if self._popen is None: - return None - - returncode = self._popen.poll() - if returncode is not None: - self.close(kill=False) - return None - - try: - lines = self._read_lines() - except BrokenPipeError: - self.close() - return None - - for line in lines: - line = line.rstrip() - - # Ignore the initial header: - # "(PDH-CSV 4.0)","\\\\WIN\\System\\Processor Queue Length" - if 'PDH-CSV' in line: - continue - - # Ignore blank lines - if not line: - continue - - try: - processor_queue_length = self._parse_line(line) - except ValueError: - print_warning("Failed to parse typeperf output: %a" % line) - continue - - # We use an exponentially weighted moving average, imitating the - # load calculation on Unix systems. - # https://en.wikipedia.org/wiki/Load_(computing)#Unix-style_load_calculation - # https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average - if self._load is not None: - self._load = (self._load * LOAD_FACTOR_1 - + processor_queue_length * (1.0 - LOAD_FACTOR_1)) - elif len(self._values) < NVALUE: - self._values.append(processor_queue_length) - else: - self._load = sum(self._values) / len(self._values) - return self._load From webhook-mailer at python.org Tue Mar 22 13:42:27 2022 From: webhook-mailer at python.org (tiran) Date: Tue, 22 Mar 2022 17:42:27 -0000 Subject: [Python-checkins] bpo-32033: Finalize WASI configure options (GH-32053) Message-ID: https://github.com/python/cpython/commit/4aea656d62860e78cd8384f2de375f0d4f1db579 commit: 4aea656d62860e78cd8384f2de375f0d4f1db579 branch: main author: Christian Heimes committer: tiran date: 2022-03-22T18:42:09+01:00 summary: bpo-32033: Finalize WASI configure options (GH-32053) files: M Tools/wasm/config.site-wasm32-wasi M configure M configure.ac M pyconfig.h.in diff --git a/Tools/wasm/config.site-wasm32-wasi b/Tools/wasm/config.site-wasm32-wasi index be26c46a148fe..255e99c279a0a 100644 --- a/Tools/wasm/config.site-wasm32-wasi +++ b/Tools/wasm/config.site-wasm32-wasi @@ -1,8 +1,6 @@ # config.site override for cross compiling to wasm32-wasi platform # # Written by Christian Heimes -# Partly based on pyodide's pyconfig.undefs.h file. - # cannot be detected in cross builds ac_cv_buggy_getaddrinfo=no @@ -14,4 +12,8 @@ ac_cv_file__dev_ptc=no # dummy readelf, WASI build does not need readelf. ac_cv_prog_ac_ct_READELF=true +# get/setrlimit are not supported +ac_cv_header_sys_resource_h=no + +# undefined symbols / unsupported features ac_cv_func_eventfd=no diff --git a/configure b/configure index 5ebcadd64239d..128e36a80062a 100755 --- a/configure +++ b/configure @@ -7758,7 +7758,13 @@ case $ac_sys_system/$ac_sys_emscripten_target in #( $as_echo "#define _WASI_EMULATED_SIGNAL 1" >>confdefs.h - LIBS="$LIBS -lwasi-emulated-signal" + +$as_echo "#define _WASI_EMULATED_GETPID 1" >>confdefs.h + + +$as_echo "#define _WASI_EMULATED_PROCESS_CLOCKS 1" >>confdefs.h + + LIBS="$LIBS -lwasi-emulated-signal -lwasi-emulated-getpid -lwasi-emulated-process-clocks" echo "#define _WASI_EMULATED_SIGNAL 1" >> confdefs.h ;; #( @@ -20549,6 +20555,8 @@ else case $ac_sys_system in #( Emscripten) : with_ensurepip=no ;; #( + WASI) : + with_ensurepip=no ;; #( *) : with_ensurepip=upgrade ;; @@ -21460,6 +21468,28 @@ case $ac_sys_system/$ac_sys_emscripten_target in #( py_cv_module_syslog=n/a py_cv_module_=n/a + ;; #( + WASI/*) : + + + + py_cv_module__ctypes=n/a + py_cv_module__ctypes_test=n/a + py_cv_module__curses=n/a + py_cv_module__curses_panel=n/a + py_cv_module__dbm=n/a + py_cv_module__gdbm=n/a + py_cv_module__scproxy=n/a + py_cv_module__tkinter=n/a + py_cv_module__xxsubinterpreters=n/a + py_cv_module_grp=n/a + py_cv_module_nis=n/a + py_cv_module_ossaudiodev=n/a + py_cv_module_pwd=n/a + py_cv_module_spwd=n/a + py_cv_module_syslog=n/a + py_cv_module_=n/a + ;; #( *) : diff --git a/configure.ac b/configure.ac index 4afc898e81d50..6fd95f7704ace 100644 --- a/configure.ac +++ b/configure.ac @@ -1898,7 +1898,9 @@ AS_CASE([$ac_sys_system/$ac_sys_emscripten_target], ], [WASI/*], [ AC_DEFINE([_WASI_EMULATED_SIGNAL], [1], [Define to 1 if you want to emulate signals on WASI]) - LIBS="$LIBS -lwasi-emulated-signal" + AC_DEFINE([_WASI_EMULATED_GETPID], [1], [Define to 1 if you want to emulate getpid() on WASI]) + AC_DEFINE([_WASI_EMULATED_PROCESS_CLOCKS], [1], [Define to 1 if you want to emulate process clocks on WASI]) + LIBS="$LIBS -lwasi-emulated-signal -lwasi-emulated-getpid -lwasi-emulated-process-clocks" echo "#define _WASI_EMULATED_SIGNAL 1" >> confdefs.h ] ) @@ -6078,6 +6080,7 @@ AC_ARG_WITH(ensurepip, [ AS_CASE([$ac_sys_system], [Emscripten], [with_ensurepip=no], + [WASI], [with_ensurepip=no], [with_ensurepip=upgrade] ) ]) @@ -6468,6 +6471,25 @@ AS_CASE([$ac_sys_system/$ac_sys_emscripten_target], [syslog], ) ], + [WASI/*], [ + PY_STDLIB_MOD_SET_NA( + [_ctypes], + [_ctypes_test], + [_curses], + [_curses_panel], + [_dbm], + [_gdbm], + [_scproxy], + [_tkinter], + [_xxsubinterpreters], + [grp], + [nis], + [ossaudiodev], + [pwd], + [spwd], + [syslog], + ) + ], [PY_STDLIB_MOD_SET_NA([_scproxy])] ) diff --git a/pyconfig.h.in b/pyconfig.h.in index 40952883853e3..ccbf90041d1c4 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -1728,6 +1728,12 @@ /* Define to force use of thread-safe errno, h_errno, and other functions */ #undef _REENTRANT +/* Define to 1 if you want to emulate getpid() on WASI */ +#undef _WASI_EMULATED_GETPID + +/* Define to 1 if you want to emulate process clocks on WASI */ +#undef _WASI_EMULATED_PROCESS_CLOCKS + /* Define to 1 if you want to emulate signals on WASI */ #undef _WASI_EMULATED_SIGNAL From webhook-mailer at python.org Tue Mar 22 14:13:04 2022 From: webhook-mailer at python.org (brettcannon) Date: Tue, 22 Mar 2022 18:13:04 -0000 Subject: [Python-checkins] [3.9] bpo-47022: Document asynchat, asyncore and smtpd removals in 3.12 (GH-31891) (#31998) Message-ID: https://github.com/python/cpython/commit/af341ebf00d9a45cadea4c07810564d8e8962b96 commit: af341ebf00d9a45cadea4c07810564d8e8962b96 branch: 3.9 author: Hugo van Kemenade committer: brettcannon date: 2022-03-22T11:12:39-07:00 summary: [3.9] bpo-47022: Document asynchat, asyncore and smtpd removals in 3.12 (GH-31891) (#31998) Document the deprecation of asyncore, asynchat, and smtpd with a slated removal in Python 3.12 thanks to PEP 594.. (cherry picked from commit 77473846439b8a3eae66de1a1cfe931619f38513) Co-authored-by: Hugo van Kemenade files: A Misc/NEWS.d/next/Library/2022-03-15-09-29-52.bpo-47022.uaEDcI.rst M Doc/library/asynchat.rst M Doc/library/asyncore.rst M Doc/library/smtpd.rst M Doc/library/superseded.rst diff --git a/Doc/library/asynchat.rst b/Doc/library/asynchat.rst index 9e51416b83a57..4354444a1d331 100644 --- a/Doc/library/asynchat.rst +++ b/Doc/library/asynchat.rst @@ -3,6 +3,7 @@ .. module:: asynchat :synopsis: Support for asynchronous command/response protocols. + :deprecated: .. moduleauthor:: Sam Rushing .. sectionauthor:: Steve Holden @@ -10,6 +11,7 @@ **Source code:** :source:`Lib/asynchat.py` .. deprecated:: 3.6 + :mod:`asynchat` will be removed in Python 3.12 (:pep:`594`). Please use :mod:`asyncio` instead. -------------- diff --git a/Doc/library/asyncore.rst b/Doc/library/asyncore.rst index a86518ebff277..e481e13db76f7 100644 --- a/Doc/library/asyncore.rst +++ b/Doc/library/asyncore.rst @@ -4,6 +4,7 @@ .. module:: asyncore :synopsis: A base class for developing asynchronous socket handling services. + :deprecated: .. moduleauthor:: Sam Rushing .. sectionauthor:: Christopher Petrilli @@ -13,6 +14,7 @@ **Source code:** :source:`Lib/asyncore.py` .. deprecated:: 3.6 + :mod:`asyncore` will be removed in Python 3.12 (:pep:`594`). Please use :mod:`asyncio` instead. -------------- diff --git a/Doc/library/smtpd.rst b/Doc/library/smtpd.rst index d84e74a8ceaaf..a39bc024047fd 100644 --- a/Doc/library/smtpd.rst +++ b/Doc/library/smtpd.rst @@ -3,6 +3,7 @@ .. module:: smtpd :synopsis: A SMTP server implementation in Python. + :deprecated: .. moduleauthor:: Barry Warsaw .. sectionauthor:: Moshe Zadka @@ -13,11 +14,11 @@ This module offers several classes to implement SMTP (email) servers. -.. seealso:: - - The `aiosmtpd `_ package is a recommended - replacement for this module. It is based on :mod:`asyncio` and provides a - more straightforward API. :mod:`smtpd` should be considered deprecated. +.. deprecated:: 3.6 + :mod:`smtpd` will be removed in Python 3.12 (:pep:`594`). + The `aiosmtpd `_ package is a recommended + replacement for this module. It is based on :mod:`asyncio` and provides a + more straightforward API. Several server implementations are present; one is a generic do-nothing implementation, which can be overridden, while the other two offer diff --git a/Doc/library/superseded.rst b/Doc/library/superseded.rst index 50a5983236e76..fd23e4d1536d3 100644 --- a/Doc/library/superseded.rst +++ b/Doc/library/superseded.rst @@ -10,5 +10,8 @@ backwards compatibility. They have been superseded by other modules. .. toctree:: - optparse.rst + asynchat.rst + asyncore.rst + smtpd.rst imp.rst + optparse.rst diff --git a/Misc/NEWS.d/next/Library/2022-03-15-09-29-52.bpo-47022.uaEDcI.rst b/Misc/NEWS.d/next/Library/2022-03-15-09-29-52.bpo-47022.uaEDcI.rst new file mode 100644 index 0000000000000..c35da6fb47b05 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-15-09-29-52.bpo-47022.uaEDcI.rst @@ -0,0 +1,3 @@ +The :mod:`asynchat`, :mod:`asyncore` and :mod:`smtpd` modules have been +deprecated since at least Python 3.6. Their documentation has now been +updated to note they will removed in Python 3.12 (:pep:`594`). From webhook-mailer at python.org Tue Mar 22 17:01:20 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Tue, 22 Mar 2022 21:01:20 -0000 Subject: [Python-checkins] bpo-2604: Make doctest.DocTestCase reset globs in teardown (GH-31932) Message-ID: https://github.com/python/cpython/commit/7ba7eae50803b11766421cb8aae1780058a57e2b commit: 7ba7eae50803b11766421cb8aae1780058a57e2b branch: main author: Dani?l van Noord <13665637+DanielNoord at users.noreply.github.com> committer: JelleZijlstra date: 2022-03-22T14:01:15-07:00 summary: bpo-2604: Make doctest.DocTestCase reset globs in teardown (GH-31932) Co-authored-by: Piet Delport Co-authored-by: Hugo Lopes Tavares Co-authored-by: Jelle Zijlstra files: A Misc/NEWS.d/next/Library/2022-03-16-18-25-19.bpo-2604.jeopdL.rst M Lib/doctest.py M Lib/test/test_doctest.py diff --git a/Lib/doctest.py b/Lib/doctest.py index 4735b59852685..ed94d15c0e2da 100644 --- a/Lib/doctest.py +++ b/Lib/doctest.py @@ -2171,6 +2171,7 @@ def __init__(self, test, optionflags=0, setUp=None, tearDown=None, unittest.TestCase.__init__(self) self._dt_optionflags = optionflags self._dt_checker = checker + self._dt_globs = test.globs.copy() self._dt_test = test self._dt_setUp = setUp self._dt_tearDown = tearDown @@ -2187,7 +2188,9 @@ def tearDown(self): if self._dt_tearDown is not None: self._dt_tearDown(test) + # restore the original globs test.globs.clear() + test.globs.update(self._dt_globs) def runTest(self): test = self._dt_test diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py index 8616aeddc1d5d..3e7f3782d89f4 100644 --- a/Lib/test/test_doctest.py +++ b/Lib/test/test_doctest.py @@ -3135,6 +3135,22 @@ def test_no_trailing_whitespace_stripping(): """ +def test_run_doctestsuite_multiple_times(): + """ + It was not possible to run the same DocTestSuite multiple times + http://bugs.python.org/issue2604 + http://bugs.python.org/issue9736 + + >>> import unittest + >>> import test.sample_doctest + >>> suite = doctest.DocTestSuite(test.sample_doctest) + >>> suite.run(unittest.TestResult()) + + >>> suite.run(unittest.TestResult()) + + """ + + def load_tests(loader, tests, pattern): tests.addTest(doctest.DocTestSuite(doctest)) tests.addTest(doctest.DocTestSuite()) diff --git a/Misc/NEWS.d/next/Library/2022-03-16-18-25-19.bpo-2604.jeopdL.rst b/Misc/NEWS.d/next/Library/2022-03-16-18-25-19.bpo-2604.jeopdL.rst new file mode 100644 index 0000000000000..c0fd000b2c660 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-16-18-25-19.bpo-2604.jeopdL.rst @@ -0,0 +1 @@ +Fix bug where doctests using globals would fail when run multiple times. From webhook-mailer at python.org Tue Mar 22 17:27:39 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 22 Mar 2022 21:27:39 -0000 Subject: [Python-checkins] bpo-2604: Make doctest.DocTestCase reset globs in teardown (GH-31932) Message-ID: https://github.com/python/cpython/commit/3c6019035f16b673cf0f0be6918f7d5493e5690e commit: 3c6019035f16b673cf0f0be6918f7d5493e5690e branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-22T14:27:26-07:00 summary: bpo-2604: Make doctest.DocTestCase reset globs in teardown (GH-31932) Co-authored-by: Piet Delport Co-authored-by: Hugo Lopes Tavares Co-authored-by: Jelle Zijlstra (cherry picked from commit 7ba7eae50803b11766421cb8aae1780058a57e2b) Co-authored-by: Dani?l van Noord <13665637+DanielNoord at users.noreply.github.com> files: A Misc/NEWS.d/next/Library/2022-03-16-18-25-19.bpo-2604.jeopdL.rst M Lib/doctest.py M Lib/test/test_doctest.py diff --git a/Lib/doctest.py b/Lib/doctest.py index d2c8828e5ed97..3caf4d9949e7b 100644 --- a/Lib/doctest.py +++ b/Lib/doctest.py @@ -2159,6 +2159,7 @@ def __init__(self, test, optionflags=0, setUp=None, tearDown=None, unittest.TestCase.__init__(self) self._dt_optionflags = optionflags self._dt_checker = checker + self._dt_globs = test.globs.copy() self._dt_test = test self._dt_setUp = setUp self._dt_tearDown = tearDown @@ -2175,7 +2176,9 @@ def tearDown(self): if self._dt_tearDown is not None: self._dt_tearDown(test) + # restore the original globs test.globs.clear() + test.globs.update(self._dt_globs) def runTest(self): test = self._dt_test diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py index 47b8575cec563..dba19103e80d1 100644 --- a/Lib/test/test_doctest.py +++ b/Lib/test/test_doctest.py @@ -3107,6 +3107,22 @@ def test_no_trailing_whitespace_stripping(): """ +def test_run_doctestsuite_multiple_times(): + """ + It was not possible to run the same DocTestSuite multiple times + http://bugs.python.org/issue2604 + http://bugs.python.org/issue9736 + + >>> import unittest + >>> import test.sample_doctest + >>> suite = doctest.DocTestSuite(test.sample_doctest) + >>> suite.run(unittest.TestResult()) + + >>> suite.run(unittest.TestResult()) + + """ + + def load_tests(loader, tests, pattern): tests.addTest(doctest.DocTestSuite(doctest)) tests.addTest(doctest.DocTestSuite()) diff --git a/Misc/NEWS.d/next/Library/2022-03-16-18-25-19.bpo-2604.jeopdL.rst b/Misc/NEWS.d/next/Library/2022-03-16-18-25-19.bpo-2604.jeopdL.rst new file mode 100644 index 0000000000000..c0fd000b2c660 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-16-18-25-19.bpo-2604.jeopdL.rst @@ -0,0 +1 @@ +Fix bug where doctests using globals would fail when run multiple times. From webhook-mailer at python.org Tue Mar 22 17:32:03 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 22 Mar 2022 21:32:03 -0000 Subject: [Python-checkins] bpo-2604: Make doctest.DocTestCase reset globs in teardown (GH-31932) Message-ID: https://github.com/python/cpython/commit/f163ad22d3321cb9bb4e6cbaac5a723444641565 commit: f163ad22d3321cb9bb4e6cbaac5a723444641565 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-22T14:31:44-07:00 summary: bpo-2604: Make doctest.DocTestCase reset globs in teardown (GH-31932) Co-authored-by: Piet Delport Co-authored-by: Hugo Lopes Tavares Co-authored-by: Jelle Zijlstra (cherry picked from commit 7ba7eae50803b11766421cb8aae1780058a57e2b) Co-authored-by: Dani?l van Noord <13665637+DanielNoord at users.noreply.github.com> files: A Misc/NEWS.d/next/Library/2022-03-16-18-25-19.bpo-2604.jeopdL.rst M Lib/doctest.py M Lib/test/test_doctest.py diff --git a/Lib/doctest.py b/Lib/doctest.py index b27cbdfed46ff..67cc34347bdf7 100644 --- a/Lib/doctest.py +++ b/Lib/doctest.py @@ -2171,6 +2171,7 @@ def __init__(self, test, optionflags=0, setUp=None, tearDown=None, unittest.TestCase.__init__(self) self._dt_optionflags = optionflags self._dt_checker = checker + self._dt_globs = test.globs.copy() self._dt_test = test self._dt_setUp = setUp self._dt_tearDown = tearDown @@ -2187,7 +2188,9 @@ def tearDown(self): if self._dt_tearDown is not None: self._dt_tearDown(test) + # restore the original globs test.globs.clear() + test.globs.update(self._dt_globs) def runTest(self): test = self._dt_test diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py index 9703f871ad640..1098a7b9f471f 100644 --- a/Lib/test/test_doctest.py +++ b/Lib/test/test_doctest.py @@ -3126,6 +3126,22 @@ def test_no_trailing_whitespace_stripping(): """ +def test_run_doctestsuite_multiple_times(): + """ + It was not possible to run the same DocTestSuite multiple times + http://bugs.python.org/issue2604 + http://bugs.python.org/issue9736 + + >>> import unittest + >>> import test.sample_doctest + >>> suite = doctest.DocTestSuite(test.sample_doctest) + >>> suite.run(unittest.TestResult()) + + >>> suite.run(unittest.TestResult()) + + """ + + def load_tests(loader, tests, pattern): tests.addTest(doctest.DocTestSuite(doctest)) tests.addTest(doctest.DocTestSuite()) diff --git a/Misc/NEWS.d/next/Library/2022-03-16-18-25-19.bpo-2604.jeopdL.rst b/Misc/NEWS.d/next/Library/2022-03-16-18-25-19.bpo-2604.jeopdL.rst new file mode 100644 index 0000000000000..c0fd000b2c660 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-16-18-25-19.bpo-2604.jeopdL.rst @@ -0,0 +1 @@ +Fix bug where doctests using globals would fail when run multiple times. From webhook-mailer at python.org Tue Mar 22 20:35:33 2022 From: webhook-mailer at python.org (zooba) Date: Wed, 23 Mar 2022 00:35:33 -0000 Subject: [Python-checkins] bpo-43166: Disable ceval.c optimizations for Windows debug builds (GH-32023) Message-ID: https://github.com/python/cpython/commit/cd05d0a423d97be69f9de4650f68f89e99ad68d1 commit: cd05d0a423d97be69f9de4650f68f89e99ad68d1 branch: main author: neonene <53406459+neonene at users.noreply.github.com> committer: zooba date: 2022-03-23T00:35:25Z summary: bpo-43166: Disable ceval.c optimizations for Windows debug builds (GH-32023) Also increases the stack allocation when run with `python_d.exe` to account for the extra stack checks that are added. files: M Include/pyport.h M PCbuild/python.vcxproj M Python/ceval.c diff --git a/Include/pyport.h b/Include/pyport.h index 62ac0989d3f15..855c382a61ee5 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -170,23 +170,12 @@ typedef Py_ssize_t Py_ssize_clean_t; * Py_LOCAL_INLINE does the same thing, and also explicitly requests inlining, * for platforms that support that. * - * If PY_LOCAL_AGGRESSIVE is defined before python.h is included, more - * "aggressive" inlining/optimization is enabled for the entire module. This - * may lead to code bloat, and may slow things down for those reasons. It may - * also lead to errors, if the code relies on pointer aliasing. Use with - * care. - * * NOTE: You can only use this for functions that are entirely local to a * module; functions that are exported via method tables, callbacks, etc, * should keep using static. */ #if defined(_MSC_VER) -# if defined(PY_LOCAL_AGGRESSIVE) - /* enable more aggressive optimization for MSVC */ - /* active in both release and debug builds - see bpo-43271 */ -# pragma optimize("gt", on) -#endif /* ignore warnings if the compiler decides not to inline a function */ # pragma warning(disable: 4710) /* fastest possible local call under MSVC */ diff --git a/PCbuild/python.vcxproj b/PCbuild/python.vcxproj index 77bccde69e3ba..11f835aecea7d 100644 --- a/PCbuild/python.vcxproj +++ b/PCbuild/python.vcxproj @@ -94,7 +94,8 @@ Console - 2000000 + 2000000 + 4000000 diff --git a/Python/ceval.c b/Python/ceval.c index 73179c810b7e5..42925b5b63048 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -5,10 +5,6 @@ XXX document it! */ -/* enable more aggressive intra-module optimizations, where available */ -/* affects both release and debug builds - see bpo-43271 */ -#define PY_LOCAL_AGGRESSIVE - #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_call.h" // _PyObject_FastCallDictTstate() From webhook-mailer at python.org Tue Mar 22 22:51:45 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Wed, 23 Mar 2022 02:51:45 -0000 Subject: [Python-checkins] Fix typo in Path.iterdir docs (GH-31822) Message-ID: https://github.com/python/cpython/commit/795b365e8a6dfbeaa75780ed7807f8116f4537ca commit: 795b365e8a6dfbeaa75780ed7807f8116f4537ca branch: main author: Matt Williams committer: JelleZijlstra date: 2022-03-22T19:51:41-07:00 summary: Fix typo in Path.iterdir docs (GH-31822) files: M Doc/library/pathlib.rst diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index 7ab603fd133b8..1e7bc315471e2 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -914,7 +914,7 @@ call fails (for example because the path doesn't exist). The children are yielded in arbitrary order, and the special entries ``'.'`` and ``'..'`` are not included. If a file is removed from or added - to the directory after creating the iterator, whether an path object for + to the directory after creating the iterator, whether a path object for that file be included is unspecified. .. method:: Path.lchmod(mode) From webhook-mailer at python.org Tue Mar 22 22:52:44 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Wed, 23 Mar 2022 02:52:44 -0000 Subject: [Python-checkins] [3.10] bpo-46769: Improve documentation for `typing.TypeVar` (GH-31712) (GH-31941) Message-ID: https://github.com/python/cpython/commit/d5ed8a8258eaf7a241978b1b0aeb971108d0f7e0 commit: d5ed8a8258eaf7a241978b1b0aeb971108d0f7e0 branch: 3.10 author: Alex Waygood committer: JelleZijlstra date: 2022-03-22T19:52:40-07:00 summary: [3.10] bpo-46769: Improve documentation for `typing.TypeVar` (GH-31712) (GH-31941) * [3.10] bpo-46769: Improve documentation for `typing.TypeVar` (GH-31712) Co-authored-by: Jelle Zijlstra (cherry picked from commit 81b425d4dc43b60dd11a3e9abc5c84a4b8b384db) * Remove references to `reveal_type`, add new section on `self` types files: M Doc/library/typing.rst M Doc/tools/susp-ignored.csv diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 6fa3eeeaf0119..ea0bcee81c50a 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -247,7 +247,7 @@ subscription to denote expected types for container elements. def notify_by_email(employees: Sequence[Employee], overrides: Mapping[str, str]) -> None: ... -Generics can be parameterized by using a new factory available in typing +Generics can be parameterized by using a factory available in typing called :class:`TypeVar`. :: @@ -304,16 +304,16 @@ that ``LoggedVar[t]`` is valid as a type:: for var in vars: var.set(0) -A generic type can have any number of type variables, and type variables may -be constrained:: +A generic type can have any number of type variables. All varieties of +:class:`TypeVar` are permissible as parameters for a generic type:: - from typing import TypeVar, Generic - ... + from typing import TypeVar, Generic, Sequence - T = TypeVar('T') + T = TypeVar('T', contravariant=True) + B = TypeVar('B', bound=Sequence[bytes], covariant=True) S = TypeVar('S', int, str) - class StrangePair(Generic[T, S]): + class WeirdTrio(Generic[T, B, S]): ... Each type variable argument to :class:`Generic` must be distinct. @@ -1084,7 +1084,8 @@ These are not used in annotations. They are building blocks for creating generic Usage:: T = TypeVar('T') # Can be anything - A = TypeVar('A', str, bytes) # Must be str or bytes + S = TypeVar('S', bound=str) # Can be any subtype of str + A = TypeVar('A', str, bytes) # Must be exactly str or bytes Type variables exist primarily for the benefit of static type checkers. They serve as the parameters for generic types as well @@ -1095,25 +1096,91 @@ These are not used in annotations. They are building blocks for creating generic """Return a list containing n references to x.""" return [x]*n - def longest(x: A, y: A) -> A: - """Return the longest of two strings.""" - return x if len(x) >= len(y) else y - The latter example's signature is essentially the overloading - of ``(str, str) -> str`` and ``(bytes, bytes) -> bytes``. Also note - that if the arguments are instances of some subclass of :class:`str`, - the return type is still plain :class:`str`. + def print_capitalized(x: S) -> S: + """Print x capitalized, and return x.""" + print(x.capitalize()) + return x + + + def concatenate(x: A, y: A) -> A: + """Add two strings or bytes objects together.""" + return x + y + + Note that type variables can be *bound*, *constrained*, or neither, but + cannot be both bound *and* constrained. + + Constrained type variables and bound type variables have different + semantics in several important ways. Using a *constrained* type variable + means that the ``TypeVar`` can only ever be solved as being exactly one of + the constraints given:: + + a = concatenate('one', 'two') # Ok, variable 'a' has type 'str' + b = concatenate(StringSubclass('one'), StringSubclass('two')) # Inferred type of variable 'b' is 'str', + # despite 'StringSubclass' being passed in + c = concatenate('one', b'two') # error: type variable 'A' can be either 'str' or 'bytes' in a function call, but not both + + Using a *bound* type variable, however, means that the ``TypeVar`` will be + solved using the most specific type possible:: + + print_capitalized('a string') # Ok, output has type 'str' + + class StringSubclass(str): + pass + + print_capitalized(StringSubclass('another string')) # Ok, output has type 'StringSubclass' + print_capitalized(45) # error: int is not a subtype of str + + Type variables can be bound to concrete types, abstract types (ABCs or + protocols), and even unions of types:: + + U = TypeVar('U', bound=str|bytes) # Can be any subtype of the union str|bytes + V = TypeVar('V', bound=SupportsAbs) # Can be anything with an __abs__ method + + Bound type variables are particularly useful for annotating + :func:`classmethods ` that serve as alternative constructors. + In the following example (? + `Raymond Hettinger `_), the + type variable ``C`` is bound to the ``Circle`` class through the use of a + forward reference. Using this type variable to annotate the + ``with_circumference`` classmethod, rather than hardcoding the return type + as ``Circle``, means that a type checker can correctly infer the return + type even if the method is called on a subclass:: + + import math + + C = TypeVar('C', bound='Circle') + + class Circle: + """An abstract circle""" + + def __init__(self, radius: float) -> None: + self.radius = radius + + # Use a type variable to show that the return type + # will always be an instance of whatever `cls` is + @classmethod + def with_circumference(cls: type[C], circumference: float) -> C: + """Create a circle with the specified circumference""" + radius = circumference / (math.pi * 2) + return cls(radius) + + + class Tire(Circle): + """A specialised circle (made out of rubber)""" + + MATERIAL = 'rubber' + + + c = Circle.with_circumference(3) # Ok, variable 'c' has type 'Circle' + t = Tire.with_circumference(4) # Ok, variable 't' has type 'Tire' (not 'Circle') At runtime, ``isinstance(x, T)`` will raise :exc:`TypeError`. In general, :func:`isinstance` and :func:`issubclass` should not be used with types. Type variables may be marked covariant or contravariant by passing ``covariant=True`` or ``contravariant=True``. See :pep:`484` for more - details. By default type variables are invariant. Alternatively, - a type variable may specify an upper bound using ``bound=``. - This means that an actual type substituted (explicitly or implicitly) - for the type variable must be a subclass of the boundary type, - see :pep:`484`. + details. By default, type variables are invariant. .. class:: ParamSpec(name, *, bound=None, covariant=False, contravariant=False) @@ -1215,7 +1282,7 @@ These are not used in annotations. They are building blocks for creating generic .. data:: AnyStr - ``AnyStr`` is a type variable defined as + ``AnyStr`` is a :class:`constrained type variable ` defined as ``AnyStr = TypeVar('AnyStr', str, bytes)``. It is meant to be used for functions that may accept any kind of string diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv index 9f4a44f1de64e..0a8d702f96bce 100644 --- a/Doc/tools/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -384,3 +384,4 @@ library/typing,,`,# Type of ``val`` is narrowed to ``str`` library/typing,,`,"# Else, type of ``val`` is narrowed to ``float``." library/typing,,`,# Type of ``val`` is narrowed to ``List[str]``. library/typing,,`,# Type of ``val`` remains as ``List[object]``. +library/typing,,`, # will always be an instance of whatever `cls` is From webhook-mailer at python.org Tue Mar 22 23:14:52 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 23 Mar 2022 03:14:52 -0000 Subject: [Python-checkins] Fix typo in Path.iterdir docs (GH-31822) Message-ID: https://github.com/python/cpython/commit/ca6acb8b31372efdbd7856f34a899104fd0c15b5 commit: ca6acb8b31372efdbd7856f34a899104fd0c15b5 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-22T20:14:30-07:00 summary: Fix typo in Path.iterdir docs (GH-31822) (cherry picked from commit 795b365e8a6dfbeaa75780ed7807f8116f4537ca) Co-authored-by: Matt Williams files: M Doc/library/pathlib.rst diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index b6507eb4d6fa2..fedea34bcd0c4 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -914,7 +914,7 @@ call fails (for example because the path doesn't exist). The children are yielded in arbitrary order, and the special entries ``'.'`` and ``'..'`` are not included. If a file is removed from or added - to the directory after creating the iterator, whether an path object for + to the directory after creating the iterator, whether a path object for that file be included is unspecified. .. method:: Path.lchmod(mode) From webhook-mailer at python.org Tue Mar 22 23:16:24 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 23 Mar 2022 03:16:24 -0000 Subject: [Python-checkins] Fix typo in Path.iterdir docs (GH-31822) Message-ID: https://github.com/python/cpython/commit/1e4044c74ec70d38331676d8fe8bc98c8edf31de commit: 1e4044c74ec70d38331676d8fe8bc98c8edf31de branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-22T20:16:18-07:00 summary: Fix typo in Path.iterdir docs (GH-31822) (cherry picked from commit 795b365e8a6dfbeaa75780ed7807f8116f4537ca) Co-authored-by: Matt Williams files: M Doc/library/pathlib.rst diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index 88e8756cf84a5..3a41b5454b864 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -900,7 +900,7 @@ call fails (for example because the path doesn't exist). The children are yielded in arbitrary order, and the special entries ``'.'`` and ``'..'`` are not included. If a file is removed from or added - to the directory after creating the iterator, whether an path object for + to the directory after creating the iterator, whether a path object for that file be included is unspecified. .. method:: Path.lchmod(mode) From webhook-mailer at python.org Wed Mar 23 04:11:31 2022 From: webhook-mailer at python.org (methane) Date: Wed, 23 Mar 2022 08:11:31 -0000 Subject: [Python-checkins] bpo-46864: Suppress deprecation warnings for ob_shash. (GH-32042) Message-ID: https://github.com/python/cpython/commit/894d0ea5afa822c23286e9e68ed80bb1122b402d commit: 894d0ea5afa822c23286e9e68ed80bb1122b402d branch: main author: Inada Naoki committer: methane date: 2022-03-23T17:11:22+09:00 summary: bpo-46864: Suppress deprecation warnings for ob_shash. (GH-32042) files: M Python/pystate.c diff --git a/Python/pystate.c b/Python/pystate.c index 1b4e31b95cd0b..3e28a6ab69a98 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -47,10 +47,13 @@ extern "C" { static PyThreadState *_PyGILState_GetThisThreadState(struct _gilstate_runtime_state *gilstate); static void _PyThreadState_Delete(PyThreadState *tstate, int check_current); - +/* Suppress deprecation warning for PyBytesObject.ob_shash */ +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS /* We use "initial" if the runtime gets re-used (e.g. Py_Finalize() followed by Py_Initialize(). */ static const _PyRuntimeState initial = _PyRuntimeState_INIT; +_Py_COMP_DIAG_POP static int alloc_for_runtime(PyThread_type_lock *plock1, PyThread_type_lock *plock2, From webhook-mailer at python.org Wed Mar 23 04:30:16 2022 From: webhook-mailer at python.org (sweeneyde) Date: Wed, 23 Mar 2022 08:30:16 -0000 Subject: [Python-checkins] bpo-47012: speed up iteration of bytes and bytearray (GH-31867) Message-ID: https://github.com/python/cpython/commit/bd1cf6ecee76bcdce87b4f69567b95756ecf5a4c commit: bd1cf6ecee76bcdce87b4f69567b95756ecf5a4c branch: main author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> committer: sweeneyde <36520290+sweeneyde at users.noreply.github.com> date: 2022-03-23T04:30:05-04:00 summary: bpo-47012: speed up iteration of bytes and bytearray (GH-31867) files: A Misc/NEWS.d/next/Core and Builtins/2022-03-14-11-15-11.bpo-47012.5L6NoE.rst M Include/internal/pycore_long.h M Objects/bytearrayobject.c M Objects/bytesobject.c diff --git a/Include/internal/pycore_long.h b/Include/internal/pycore_long.h index 436bf08468599..a33762402491b 100644 --- a/Include/internal/pycore_long.h +++ b/Include/internal/pycore_long.h @@ -23,8 +23,9 @@ extern void _PyLong_FiniTypes(PyInterpreterState *interp); #define _PyLong_SMALL_INTS _Py_SINGLETON(small_ints) // _PyLong_GetZero() and _PyLong_GetOne() must always be available -#if _PY_NSMALLPOSINTS < 2 -# error "_PY_NSMALLPOSINTS must be greater than 1" +// _PyLong_FromUnsignedChar must always be available +#if _PY_NSMALLPOSINTS < 257 +# error "_PY_NSMALLPOSINTS must be greater than or equal to 257" #endif // Return a borrowed reference to the zero singleton. @@ -37,6 +38,11 @@ static inline PyObject* _PyLong_GetZero(void) static inline PyObject* _PyLong_GetOne(void) { return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+1]; } +static inline PyObject* _PyLong_FromUnsignedChar(unsigned char i) +{ + return Py_NewRef((PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+i]); +} + PyObject *_PyLong_Add(PyLongObject *left, PyLongObject *right); PyObject *_PyLong_Multiply(PyLongObject *left, PyLongObject *right); PyObject *_PyLong_Subtract(PyLongObject *left, PyLongObject *right); diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-14-11-15-11.bpo-47012.5L6NoE.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-14-11-15-11.bpo-47012.5L6NoE.rst new file mode 100644 index 0000000000000..f85487f8d3ae7 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-14-11-15-11.bpo-47012.5L6NoE.rst @@ -0,0 +1 @@ +Speed up iteration of :class:`bytes` and :class:`bytearray` by 30%. Patch by Kumar Aditya. diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index ba2d347dbd7a8..cbe673acd0a3a 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -6,6 +6,7 @@ #include "pycore_bytes_methods.h" #include "pycore_object.h" // _PyObject_GC_UNTRACK() #include "pycore_strhex.h" // _Py_strhex_with_sep() +#include "pycore_long.h" // _PyLong_FromUnsignedChar() #include "bytesobject.h" /*[clinic input] @@ -2428,7 +2429,6 @@ static PyObject * bytearrayiter_next(bytesiterobject *it) { PyByteArrayObject *seq; - PyObject *item; assert(it != NULL); seq = it->it_seq; @@ -2437,11 +2437,8 @@ bytearrayiter_next(bytesiterobject *it) assert(PyByteArray_Check(seq)); if (it->it_index < PyByteArray_GET_SIZE(seq)) { - item = PyLong_FromLong( - (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index]); - if (item != NULL) - ++it->it_index; - return item; + return _PyLong_FromUnsignedChar( + (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index++]); } it->it_seq = NULL; diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index fd1c58c2f233e..003953244a885 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -3133,7 +3133,7 @@ striter_next(striterobject *it) assert(PyBytes_Check(seq)); if (it->it_index < PyBytes_GET_SIZE(seq)) { - return PyLong_FromLong( + return _PyLong_FromUnsignedChar( (unsigned char)seq->ob_sval[it->it_index++]); } From webhook-mailer at python.org Wed Mar 23 04:34:39 2022 From: webhook-mailer at python.org (JulienPalard) Date: Wed, 23 Mar 2022 08:34:39 -0000 Subject: [Python-checkins] bpo-42238: [doc] Some lines moved in rst, but had hardcoded lineno in susp-ignored.csv. (GH-32070) Message-ID: https://github.com/python/cpython/commit/ec8906fb5930b1f078e2a2170cdf445e6c6faf57 commit: ec8906fb5930b1f078e2a2170cdf445e6c6faf57 branch: main author: Julien Palard committer: JulienPalard date: 2022-03-23T09:34:30+01:00 summary: bpo-42238: [doc] Some lines moved in rst, but had hardcoded lineno in susp-ignored.csv. (GH-32070) files: M Doc/tools/susp-ignored.csv diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv index 43a36042059f7..a5ceff4be0196 100644 --- a/Doc/tools/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -382,12 +382,12 @@ library/tkinter,,::,"grid [ttk::button .frm.btn -text ""Quit"" -command ""destro library/tkinter,,::,ttk::frame library/tkinter,,::,ttk::button library/tkinter,,::,ttk::widget -reference/compound_stmts,324,:exc,subclass of :exc:`BaseExceptionGroup`. It is not possible to mix except -reference/compound_stmts,324,`,subclass of :exc:`BaseExceptionGroup`. It is not possible to mix except -reference/compound_stmts,324,:keyword,"and except* in the same :keyword:`try`. :keyword:`break`," -reference/compound_stmts,324,`,"and except* in the same :keyword:`try`. :keyword:`break`," -reference/compound_stmts,324,:keyword,:keyword:`continue` and :keyword:`return` cannot appear in an except* -reference/compound_stmts,324,`,:keyword:`continue` and :keyword:`return` cannot appear in an except* +reference/compound_stmts,,:exc,subclass of :exc:`BaseExceptionGroup`. It is not possible to mix except +reference/compound_stmts,,`,subclass of :exc:`BaseExceptionGroup`. It is not possible to mix except +reference/compound_stmts,,:keyword,"and except* in the same :keyword:`try`. :keyword:`break`," +reference/compound_stmts,,`,"and except* in the same :keyword:`try`. :keyword:`break`," +reference/compound_stmts,,:keyword,:keyword:`continue` and :keyword:`return` cannot appear in an except* +reference/compound_stmts,,`,:keyword:`continue` and :keyword:`return` cannot appear in an except* whatsnew/changelog,,:CON,": os.path.abspath(?C:CON?) is now fixed to return ?\.CON?, not" whatsnew/changelog,,::,Lib/email/mime/nonmultipart.py::MIMENonMultipart library/typing,,`,"assert_type(name, str) # OK, inferred type of `name` is `str`" From webhook-mailer at python.org Wed Mar 23 04:35:41 2022 From: webhook-mailer at python.org (JulienPalard) Date: Wed, 23 Mar 2022 08:35:41 -0000 Subject: [Python-checkins] [doc] configparser: avoid inline comments. (GH-31247) Message-ID: https://github.com/python/cpython/commit/3ac4e783e077ffd7b51c6acc1591002974644051 commit: 3ac4e783e077ffd7b51c6acc1591002974644051 branch: main author: Julien Palard committer: JulienPalard date: 2022-03-23T09:35:33+01:00 summary: [doc] configparser: avoid inline comments. (GH-31247) People are testing those blocs with the default inline_comment_prefixes of None, leading to a: configparser.InterpolationSyntaxError: '$' must be followed by '$' or '{', found: '$ sign ($ is the only character that needs to be escaped)' files: M Doc/library/configparser.rst diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst index 323dd2affc78f..72aa20d73d8bd 100644 --- a/Doc/library/configparser.rst +++ b/Doc/library/configparser.rst @@ -347,7 +347,8 @@ from ``get()`` calls. my_pictures: %(my_dir)s/Pictures [Escape] - gain: 80%% # use a %% to escape the % sign (% is the only character that needs to be escaped) + # use a %% to escape the % sign (% is the only character that needs to be escaped): + gain: 80%% In the example above, :class:`ConfigParser` with *interpolation* set to ``BasicInterpolation()`` would resolve ``%(home_dir)s`` to the value of @@ -382,7 +383,8 @@ from ``get()`` calls. my_pictures: ${my_dir}/Pictures [Escape] - cost: $$80 # use a $$ to escape the $ sign ($ is the only character that needs to be escaped) + # use a $$ to escape the $ sign ($ is the only character that needs to be escaped): + cost: $$80 Values from other sections can be fetched as well: From webhook-mailer at python.org Wed Mar 23 04:58:56 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 23 Mar 2022 08:58:56 -0000 Subject: [Python-checkins] [doc] configparser: avoid inline comments. (GH-31247) Message-ID: https://github.com/python/cpython/commit/832be8f1d4c5f62623e382dd0df8fe3f38079040 commit: 832be8f1d4c5f62623e382dd0df8fe3f38079040 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-23T01:58:49-07:00 summary: [doc] configparser: avoid inline comments. (GH-31247) People are testing those blocs with the default inline_comment_prefixes of None, leading to a: configparser.InterpolationSyntaxError: '$' must be followed by '$' or '{', found: '$ sign ($ is the only character that needs to be escaped)' (cherry picked from commit 3ac4e783e077ffd7b51c6acc1591002974644051) Co-authored-by: Julien Palard files: M Doc/library/configparser.rst diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst index 323dd2affc78f..72aa20d73d8bd 100644 --- a/Doc/library/configparser.rst +++ b/Doc/library/configparser.rst @@ -347,7 +347,8 @@ from ``get()`` calls. my_pictures: %(my_dir)s/Pictures [Escape] - gain: 80%% # use a %% to escape the % sign (% is the only character that needs to be escaped) + # use a %% to escape the % sign (% is the only character that needs to be escaped): + gain: 80%% In the example above, :class:`ConfigParser` with *interpolation* set to ``BasicInterpolation()`` would resolve ``%(home_dir)s`` to the value of @@ -382,7 +383,8 @@ from ``get()`` calls. my_pictures: ${my_dir}/Pictures [Escape] - cost: $$80 # use a $$ to escape the $ sign ($ is the only character that needs to be escaped) + # use a $$ to escape the $ sign ($ is the only character that needs to be escaped): + cost: $$80 Values from other sections can be fetched as well: From webhook-mailer at python.org Wed Mar 23 05:01:30 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 23 Mar 2022 09:01:30 -0000 Subject: [Python-checkins] [doc] configparser: avoid inline comments. (GH-31247) Message-ID: https://github.com/python/cpython/commit/f5af1677c06bb4cc006e7f9b30106212e1a00f81 commit: f5af1677c06bb4cc006e7f9b30106212e1a00f81 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-23T02:01:24-07:00 summary: [doc] configparser: avoid inline comments. (GH-31247) People are testing those blocs with the default inline_comment_prefixes of None, leading to a: configparser.InterpolationSyntaxError: '$' must be followed by '$' or '{', found: '$ sign ($ is the only character that needs to be escaped)' (cherry picked from commit 3ac4e783e077ffd7b51c6acc1591002974644051) Co-authored-by: Julien Palard files: M Doc/library/configparser.rst diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst index e5c78246881f1..c98ffe718e50a 100644 --- a/Doc/library/configparser.rst +++ b/Doc/library/configparser.rst @@ -323,7 +323,8 @@ from ``get()`` calls. my_pictures: %(my_dir)s/Pictures [Escape] - gain: 80%% # use a %% to escape the % sign (% is the only character that needs to be escaped) + # use a %% to escape the % sign (% is the only character that needs to be escaped): + gain: 80%% In the example above, :class:`ConfigParser` with *interpolation* set to ``BasicInterpolation()`` would resolve ``%(home_dir)s`` to the value of @@ -358,7 +359,8 @@ from ``get()`` calls. my_pictures: ${my_dir}/Pictures [Escape] - cost: $$80 # use a $$ to escape the $ sign ($ is the only character that needs to be escaped) + # use a $$ to escape the $ sign ($ is the only character that needs to be escaped): + cost: $$80 Values from other sections can be fetched as well: From webhook-mailer at python.org Wed Mar 23 08:19:19 2022 From: webhook-mailer at python.org (vstinner) Date: Wed, 23 Mar 2022 12:19:19 -0000 Subject: [Python-checkins] bpo-46836: Add Doc/c-api/frame.rst (GH-32051) Message-ID: https://github.com/python/cpython/commit/b0f886d1bca499db1118a60b707923fa8e157073 commit: b0f886d1bca499db1118a60b707923fa8e157073 branch: main author: Victor Stinner committer: vstinner date: 2022-03-23T13:19:13+01:00 summary: bpo-46836: Add Doc/c-api/frame.rst (GH-32051) Reorganize the documentation of the PyFrameObject C API. files: A Doc/c-api/frame.rst M Doc/c-api/concrete.rst M Doc/c-api/reflection.rst M Doc/c-api/veryhigh.rst M Doc/whatsnew/3.11.rst diff --git a/Doc/c-api/concrete.rst b/Doc/c-api/concrete.rst index 84224dcca523b9..8d3124a12fa9d2 100644 --- a/Doc/c-api/concrete.rst +++ b/Doc/c-api/concrete.rst @@ -111,6 +111,7 @@ Other Objects memoryview.rst weakref.rst capsule.rst + frame.rst gen.rst coro.rst contextvars.rst diff --git a/Doc/c-api/frame.rst b/Doc/c-api/frame.rst new file mode 100644 index 00000000000000..0e36e6e1fd706f --- /dev/null +++ b/Doc/c-api/frame.rst @@ -0,0 +1,48 @@ +.. highlight:: c + +Frame Objects +------------- + +.. c:type:: PyFrameObject + + The C structure of the objects used to describe frame objects. + + The structure is not part of the C API. + + .. versionchanged:: 3.11 + The structure moved to the internal C API headers. + +The :c:func:`PyEval_GetFrame` and :c:func:`PyThreadState_GetFrame` functions +can be used to get a frame object. + +See also :ref:`Reflection `. + + +.. c:function:: PyFrameObject* PyFrame_GetBack(PyFrameObject *frame) + + Get the *frame* next outer frame. + + Return a :term:`strong reference`, or ``NULL`` if *frame* has no outer + frame. + + *frame* must not be ``NULL``. + + .. versionadded:: 3.9 + + +.. c:function:: PyCodeObject* PyFrame_GetCode(PyFrameObject *frame) + + Get the *frame* code. + + Return a :term:`strong reference`. + + *frame* must not be ``NULL``. The result (frame code) cannot be ``NULL``. + + .. versionadded:: 3.9 + + +.. c:function:: int PyFrame_GetLineNumber(PyFrameObject *frame) + + Return the line number that *frame* is currently executing. + + *frame* must not be ``NULL``. diff --git a/Doc/c-api/reflection.rst b/Doc/c-api/reflection.rst index fe7741a2d7a9fb..4b1c4770848a30 100644 --- a/Doc/c-api/reflection.rst +++ b/Doc/c-api/reflection.rst @@ -31,35 +31,6 @@ Reflection See also :c:func:`PyThreadState_GetFrame`. -.. c:function:: PyFrameObject* PyFrame_GetBack(PyFrameObject *frame) - - Get the *frame* next outer frame. - - Return a :term:`strong reference`, or ``NULL`` if *frame* has no outer frame. - - *frame* must not be ``NULL``. - - .. versionadded:: 3.9 - - -.. c:function:: PyCodeObject* PyFrame_GetCode(PyFrameObject *frame) - - Get the *frame* code. - - Return a :term:`strong reference`. - - *frame* must not be ``NULL``. The result (frame code) cannot be ``NULL``. - - .. versionadded:: 3.9 - - -.. c:function:: int PyFrame_GetLineNumber(PyFrameObject *frame) - - Return the line number that *frame* is currently executing. - - *frame* must not be ``NULL``. - - .. c:function:: const char* PyEval_GetFuncName(PyObject *func) Return the name of *func* if it is a function, class or instance object, else the diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst index 2f5720d493d798..7bd47bb9c660a6 100644 --- a/Doc/c-api/veryhigh.rst +++ b/Doc/c-api/veryhigh.rst @@ -286,20 +286,6 @@ the same library that the Python runtime is using. ` arguments and a closure tuple of cells. -.. c:type:: PyFrameObject - - The C structure of the objects used to describe frame objects. - - The structure is only part of the internal C API: fields should not be - access directly. Use getter functions like :c:func:`PyFrame_GetCode` and - :c:func:`PyFrame_GetBack`. - - Debuggers and profilers can use the limited C API to access this structure. - - .. versionchanged:: 3.11 - The structure moved to the internal C API headers. - - .. c:function:: PyObject* PyEval_EvalFrame(PyFrameObject *f) Evaluate an execution frame. This is a simplified interface to diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 938a573d595744..fe6c2e24c3d241 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -968,10 +968,8 @@ Porting to Python 3.11 * ``f_stackdepth``: removed. * ``f_state``: no public API (renamed to ``f_frame.f_state``). * ``f_trace``: no public API. - * ``f_trace_lines``: use ``PyObject_GetAttrString((PyObject*)frame, "f_trace_lines")`` - (it also be modified). - * ``f_trace_opcodes``: use ``PyObject_GetAttrString((PyObject*)frame, "f_trace_opcodes")`` - (it also be modified). + * ``f_trace_lines``: use ``PyObject_GetAttrString((PyObject*)frame, "f_trace_lines")``. + * ``f_trace_opcodes``: use ``PyObject_GetAttrString((PyObject*)frame, "f_trace_opcodes")``. * ``f_localsplus``: no public API (renamed to ``f_frame.localsplus``). * ``f_valuestack``: removed. From webhook-mailer at python.org Wed Mar 23 10:39:32 2022 From: webhook-mailer at python.org (iritkatriel) Date: Wed, 23 Mar 2022 14:39:32 -0000 Subject: [Python-checkins] Correctly document class instead of function (GH-32016) Message-ID: https://github.com/python/cpython/commit/624e3986fbf8467772e4863b7ec004e65adff619 commit: 624e3986fbf8467772e4863b7ec004e65adff619 branch: main author: slateny <46876382+slateny at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-03-23T14:39:07Z summary: Correctly document class instead of function (GH-32016) files: M Doc/library/tempfile.rst diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst index 3184e50488427..c97d119fb8b5e 100644 --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -99,9 +99,9 @@ The module defines the following user-callable items: Added *errors* parameter. -.. function:: SpooledTemporaryFile(max_size=0, mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None) +.. class:: SpooledTemporaryFile(max_size=0, mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None) - This function operates exactly as :func:`TemporaryFile` does, except that + This class operates exactly as :func:`TemporaryFile` does, except that data is spooled in memory until the file size exceeds *max_size*, or until the file's :func:`fileno` method is called, at which point the contents are written to disk and operation proceeds as with @@ -124,9 +124,9 @@ The module defines the following user-callable items: Added *errors* parameter. -.. function:: TemporaryDirectory(suffix=None, prefix=None, dir=None, ignore_cleanup_errors=False) +.. class:: TemporaryDirectory(suffix=None, prefix=None, dir=None, ignore_cleanup_errors=False) - This function securely creates a temporary directory using the same rules as :func:`mkdtemp`. + This class securely creates a temporary directory using the same rules as :func:`mkdtemp`. The resulting object can be used as a context manager (see :ref:`tempfile-examples`). On completion of the context or destruction of the temporary directory object, the newly created temporary directory From webhook-mailer at python.org Wed Mar 23 11:43:16 2022 From: webhook-mailer at python.org (gvanrossum) Date: Wed, 23 Mar 2022 15:43:16 -0000 Subject: [Python-checkins] bpo-46829: Deprecate passing a message into Future.cancel() and Task.cancel() (GH-31840) Message-ID: https://github.com/python/cpython/commit/0360e9f34659e7d7f3dae021b82f78452db8c714 commit: 0360e9f34659e7d7f3dae021b82f78452db8c714 branch: main author: Andrew Svetlov committer: gvanrossum date: 2022-03-23T08:43:05-07:00 summary: bpo-46829: Deprecate passing a message into Future.cancel() and Task.cancel() (GH-31840) After a long deliberation we ended up feeling that the message argument for Future.cancel(), added in 3.9, was a bad idea, so we're deprecating it in 3.11 and plan to remove it in 3.13. files: A Misc/NEWS.d/next/Core and Builtins/2022-03-12-21-07-21.bpo-46829.cpGoPV.rst M Doc/library/asyncio-future.rst M Doc/library/asyncio-task.rst M Lib/asyncio/futures.py M Lib/asyncio/tasks.py M Lib/test/test_asyncio/test_futures.py M Lib/test/test_asyncio/test_taskgroups.py M Lib/test/test_asyncio/test_tasks.py M Modules/_asynciomodule.c diff --git a/Doc/library/asyncio-future.rst b/Doc/library/asyncio-future.rst index 7426e8291e142..f74f2e6f8935e 100644 --- a/Doc/library/asyncio-future.rst +++ b/Doc/library/asyncio-future.rst @@ -196,6 +196,11 @@ Future Object .. versionchanged:: 3.9 Added the *msg* parameter. + .. deprecated-removed:: 3.11 3.14 + *msg* parameter is ambiguous when multiple :meth:`cancel` + are called with different cancellation messages. + The argument will be removed. + .. method:: exception() Return the exception that was set on this Future. @@ -276,3 +281,8 @@ the Future has a result:: - :meth:`asyncio.Future.cancel` accepts an optional ``msg`` argument, but :func:`concurrent.futures.cancel` does not. + + .. deprecated-removed:: 3.11 3.14 + *msg* parameter is ambiguous when multiple :meth:`cancel` + are called with different cancellation messages. + The argument will be removed. diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index 294f5ab2b22f9..21a4cb5820bd1 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -810,8 +810,10 @@ Task Object .. versionchanged:: 3.9 Added the *msg* parameter. - .. versionchanged:: 3.11 - The ``msg`` parameter is propagated from cancelled task to its awaiter. + .. deprecated-removed:: 3.11 3.14 + *msg* parameter is ambiguous when multiple :meth:`cancel` + are called with different cancellation messages. + The argument will be removed. .. _asyncio_example_task_cancel: diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py index bfd4ee926f028..08c79e7b5109b 100644 --- a/Lib/asyncio/futures.py +++ b/Lib/asyncio/futures.py @@ -8,6 +8,7 @@ import contextvars import logging import sys +import warnings from types import GenericAlias from . import base_futures @@ -150,6 +151,11 @@ def cancel(self, msg=None): change the future's state to cancelled, schedule the callbacks and return True. """ + if msg is not None: + warnings.warn("Passing 'msg' argument to Future.cancel() " + "is deprecated since Python 3.11, and " + "scheduled for removal in Python 3.14.", + DeprecationWarning, stacklevel=2) self.__log_traceback = False if self._state != _PENDING: return False diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index e876f8d002ce4..27fe58da15136 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -207,6 +207,11 @@ def cancel(self, msg=None): This also increases the task's count of cancellation requests. """ + if msg is not None: + warnings.warn("Passing 'msg' argument to Task.cancel() " + "is deprecated since Python 3.11, and " + "scheduled for removal in Python 3.14.", + DeprecationWarning, stacklevel=2) self._log_traceback = False if self.done(): return False diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py index 84d7d45af949e..cf677f6a95115 100644 --- a/Lib/test/test_asyncio/test_futures.py +++ b/Lib/test/test_asyncio/test_futures.py @@ -228,14 +228,22 @@ def test_future_cancel_message_getter(self): self.assertTrue(hasattr(f, '_cancel_message')) self.assertEqual(f._cancel_message, None) - f.cancel('my message') + with self.assertWarnsRegex( + DeprecationWarning, + "Passing 'msg' argument" + ): + f.cancel('my message') with self.assertRaises(asyncio.CancelledError): self.loop.run_until_complete(f) self.assertEqual(f._cancel_message, 'my message') def test_future_cancel_message_setter(self): f = self._new_future(loop=self.loop) - f.cancel('my message') + with self.assertWarnsRegex( + DeprecationWarning, + "Passing 'msg' argument" + ): + f.cancel('my message') f._cancel_message = 'my new message' self.assertEqual(f._cancel_message, 'my new message') diff --git a/Lib/test/test_asyncio/test_taskgroups.py b/Lib/test/test_asyncio/test_taskgroups.py index dea5d6de52420..69369a6100a8f 100644 --- a/Lib/test/test_asyncio/test_taskgroups.py +++ b/Lib/test/test_asyncio/test_taskgroups.py @@ -191,12 +191,10 @@ async def runner(): await asyncio.sleep(0.1) self.assertFalse(r.done()) - r.cancel("test") + r.cancel() with self.assertRaises(asyncio.CancelledError) as cm: await r - self.assertEqual(cm.exception.args, ('test',)) - self.assertEqual(NUM, 5) async def test_taskgroup_07(self): @@ -253,12 +251,10 @@ async def runner(): await asyncio.sleep(0.1) self.assertFalse(r.done()) - r.cancel("test") + r.cancel() with self.assertRaises(asyncio.CancelledError) as cm: await r - self.assertEqual(cm.exception.args, ('test',)) - async def test_taskgroup_09(self): t1 = t2 = None diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index b86646ee398ae..8df1957bbe9e7 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -113,7 +113,11 @@ async def coro(): self.assertTrue(hasattr(t, '_cancel_message')) self.assertEqual(t._cancel_message, None) - t.cancel('my message') + with self.assertWarnsRegex( + DeprecationWarning, + "Passing 'msg' argument" + ): + t.cancel('my message') self.assertEqual(t._cancel_message, 'my message') with self.assertRaises(asyncio.CancelledError) as cm: @@ -125,7 +129,11 @@ def test_task_cancel_message_setter(self): async def coro(): pass t = self.new_task(self.loop, coro()) - t.cancel('my message') + with self.assertWarnsRegex( + DeprecationWarning, + "Passing 'msg' argument" + ): + t.cancel('my message') t._cancel_message = 'my new message' self.assertEqual(t._cancel_message, 'my new message') @@ -582,7 +590,14 @@ async def sleep(): async def coro(): task = self.new_task(loop, sleep()) await asyncio.sleep(0) - task.cancel(*cancel_args) + if cancel_args not in ((), (None,)): + with self.assertWarnsRegex( + DeprecationWarning, + "Passing 'msg' argument" + ): + task.cancel(*cancel_args) + else: + task.cancel(*cancel_args) done, pending = await asyncio.wait([task]) task.result() @@ -616,7 +631,14 @@ async def sleep(): async def coro(): task = self.new_task(loop, sleep()) await asyncio.sleep(0) - task.cancel(*cancel_args) + if cancel_args not in ((), (None,)): + with self.assertWarnsRegex( + DeprecationWarning, + "Passing 'msg' argument" + ): + task.cancel(*cancel_args) + else: + task.cancel(*cancel_args) done, pending = await asyncio.wait([task]) task.exception() @@ -639,10 +661,17 @@ async def sleep(): fut.set_result(None) await asyncio.sleep(10) + def cancel(task, msg): + with self.assertWarnsRegex( + DeprecationWarning, + "Passing 'msg' argument" + ): + task.cancel(msg) + async def coro(): inner_task = self.new_task(loop, sleep()) await fut - loop.call_soon(inner_task.cancel, 'msg') + loop.call_soon(cancel, inner_task, 'msg') try: await inner_task except asyncio.CancelledError as ex: @@ -668,7 +697,11 @@ async def sleep(): async def coro(): task = self.new_task(loop, sleep()) # We deliberately leave out the sleep here. - task.cancel('my message') + with self.assertWarnsRegex( + DeprecationWarning, + "Passing 'msg' argument" + ): + task.cancel('my message') done, pending = await asyncio.wait([task]) task.exception() @@ -2029,7 +2062,14 @@ async def test(): async def main(): qwe = self.new_task(loop, test()) await asyncio.sleep(0.2) - qwe.cancel(*cancel_args) + if cancel_args not in ((), (None,)): + with self.assertWarnsRegex( + DeprecationWarning, + "Passing 'msg' argument" + ): + qwe.cancel(*cancel_args) + else: + qwe.cancel(*cancel_args) await qwe try: diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-12-21-07-21.bpo-46829.cpGoPV.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-12-21-07-21.bpo-46829.cpGoPV.rst new file mode 100644 index 0000000000000..9d260f5b1dddb --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-12-21-07-21.bpo-46829.cpGoPV.rst @@ -0,0 +1,2 @@ +Deprecate passing a message into :meth:`asyncio.Future.cancel` and +:meth:`asyncio.Task.cancel` diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index c3e9cb2fa2a30..5b8555e74b375 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -1096,6 +1096,16 @@ static PyObject * _asyncio_Future_cancel_impl(FutureObj *self, PyObject *msg) /*[clinic end generated code: output=3edebbc668e5aba3 input=925eb545251f2c5a]*/ { + if (msg != Py_None) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing 'msg' argument to Future.cancel() " + "is deprecated since Python 3.11, and " + "scheduled for removal in Python 3.14.", + 2)) + { + return NULL; + } + } ENSURE_FUTURE_ALIVE(self) return future_cancel(self, msg); } @@ -2176,6 +2186,16 @@ static PyObject * _asyncio_Task_cancel_impl(TaskObj *self, PyObject *msg) /*[clinic end generated code: output=c66b60d41c74f9f1 input=7bb51bf25974c783]*/ { + if (msg != Py_None) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Passing 'msg' argument to Task.cancel() " + "is deprecated since Python 3.11, and " + "scheduled for removal in Python 3.14.", + 2)) + { + return NULL; + } + } self->task_log_tb = 0; if (self->task_state != STATE_PENDING) { From webhook-mailer at python.org Wed Mar 23 11:52:59 2022 From: webhook-mailer at python.org (ericsnowcurrently) Date: Wed, 23 Mar 2022 15:52:59 -0000 Subject: [Python-checkins] bpo-46541: Add a Comment About When to Use _Py_DECLARE_STR(). (gh-32063) Message-ID: https://github.com/python/cpython/commit/21412d037b07c08266e96dfd0c0e44a1b7693bc1 commit: 21412d037b07c08266e96dfd0c0e44a1b7693bc1 branch: main author: Eric Snow committer: ericsnowcurrently date: 2022-03-23T09:52:50-06:00 summary: bpo-46541: Add a Comment About When to Use _Py_DECLARE_STR(). (gh-32063) In a gh-32003 comment, I realized it wasn't very clear how _Py_DECLARE_STR() should be used. This changes adds a comment to clarify. https://bugs.python.org/issue46541 files: M Include/internal/pycore_global_strings.h diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h index 1d83bf2cfad4c..3e533fd16509f 100644 --- a/Include/internal/pycore_global_strings.h +++ b/Include/internal/pycore_global_strings.h @@ -372,6 +372,16 @@ struct _Py_global_strings { #define _Py_STR(NAME) \ (_Py_SINGLETON(strings.literals._ ## NAME._ascii.ob_base)) +/* _Py_DECLARE_STR() should precede all uses of _Py_STR() in a function. + + This is true even if the same string has already been declared + elsewhere, even in the same file. Mismatched duplicates are detected + by Tools/scripts/generate-global-objects.py. + + Pairing _Py_DECLARE_STR() with every use of _Py_STR() makes sure the + string keeps working even if the declaration is removed somewhere + else. It also makes it clear what the actual string is at every + place it is being used. */ #define _Py_DECLARE_STR(name, str) #ifdef __cplusplus From webhook-mailer at python.org Wed Mar 23 11:56:01 2022 From: webhook-mailer at python.org (ericsnowcurrently) Date: Wed, 23 Mar 2022 15:56:01 -0000 Subject: [Python-checkins] bpo-46712: Do not Regen Deep-Frozen Modules before Generating Global Objects (gh-32061) Message-ID: https://github.com/python/cpython/commit/febf54bcf3fdc45ad84b4073e24bbaaee0ac8b2a commit: febf54bcf3fdc45ad84b4073e24bbaaee0ac8b2a branch: main author: Eric Snow committer: ericsnowcurrently date: 2022-03-23T09:55:52-06:00 summary: bpo-46712: Do not Regen Deep-Frozen Modules before Generating Global Objects (gh-32061) We have to run "make regen-deepfreeze" before running Tools/scripts/generate-global-objects.py; otherwise we will miss any changes to global objects in deep-frozen modules (which aren't committed in the repo). However, building $(PYTHON_FOR_FREEZE) fails if one of its source files had a global object (e.g. via _Py_ID(...)) added or removed, without generate-global-objects.py running first. So "make regen-global-objects" would sometimes fail. We solve this by running generate-global-objects.py before *and* after "make regen-deepfreeze". To speed things up and cut down on noise, we also avoid updating the global objects files if there are no changes to them. https://bugs.python.org/issue46712 files: M Makefile.pre.in M Tools/scripts/generate_global_objects.py diff --git a/Makefile.pre.in b/Makefile.pre.in index 4b9aab0a284ce..8eab27ccf9dc3 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1179,7 +1179,12 @@ regen-importlib: regen-frozen # Global objects .PHONY: regen-global-objects -regen-global-objects: regen-deepfreeze $(srcdir)/Tools/scripts/generate_global_objects.py +regen-global-objects: $(srcdir)/Tools/scripts/generate_global_objects.py + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_global_objects.py + @# Run one more time after deepfreezing, to catch any globals added + @# there. This is necessary because the deep-frozen code isn't + @# commited to the repo. + $(MAKE) regen-deepfreeze $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_global_objects.py ############################################################################ diff --git a/Tools/scripts/generate_global_objects.py b/Tools/scripts/generate_global_objects.py index 17ddb8b324a0b..f7653604e822b 100644 --- a/Tools/scripts/generate_global_objects.py +++ b/Tools/scripts/generate_global_objects.py @@ -1,5 +1,6 @@ import contextlib import glob +import io import os.path import re import sys @@ -123,6 +124,7 @@ def iter_global_strings(): varname, string = m.groups() yield varname, string, filename, lno, line + def iter_to_marker(lines, marker): for line in lines: if line.rstrip() == marker: @@ -165,6 +167,19 @@ def block(self, prefix, suffix="", *, continuation=None): self.write("}" + suffix) + at contextlib.contextmanager +def open_for_changes(filename, orig): + """Like open() but only write to the file if it changed.""" + outfile = io.StringIO() + yield outfile + text = outfile.getvalue() + if text != orig: + with open(filename, 'w', encoding='utf-8') as outfile: + outfile.write(text) + else: + print(f'# not changed: {filename}') + + ####################################### # the global objects @@ -177,13 +192,15 @@ def generate_global_strings(identifiers, strings): # Read the non-generated part of the file. with open(filename) as infile: - before = ''.join(iter_to_marker(infile, START))[:-1] - for _ in iter_to_marker(infile, END): - pass - after = infile.read()[:-1] + orig = infile.read() + lines = iter(orig.rstrip().splitlines()) + before = '\n'.join(iter_to_marker(lines, START)) + for _ in iter_to_marker(lines, END): + pass + after = '\n'.join(lines) # Generate the file. - with open(filename, 'w', encoding='utf-8') as outfile: + with open_for_changes(filename, orig) as outfile: printer = Printer(outfile) printer.write(before) printer.write(START) @@ -202,7 +219,6 @@ def generate_global_strings(identifiers, strings): with printer.block('struct', ' latin1[128];'): printer.write("PyCompactUnicodeObject _latin1;") printer.write("uint8_t _data[2];") - printer.write(END) printer.write(after) @@ -227,13 +243,15 @@ def generate_runtime_init(identifiers, strings): # Read the non-generated part of the file. with open(filename) as infile: - before = ''.join(iter_to_marker(infile, START))[:-1] - for _ in iter_to_marker(infile, END): - pass - after = infile.read()[:-1] + orig = infile.read() + lines = iter(orig.rstrip().splitlines()) + before = '\n'.join(iter_to_marker(lines, START)) + for _ in iter_to_marker(lines, END): + pass + after = '\n'.join(lines) # Generate the file. - with open(filename, 'w', encoding='utf-8') as outfile: + with open_for_changes(filename, orig) as outfile: printer = Printer(outfile) printer.write(before) printer.write(START) @@ -286,6 +304,7 @@ def get_identifiers_and_strings() -> 'tuple[set[str], dict[str, str]]': raise ValueError(f'string mismatch for {name!r} ({string!r} != {strings[name]!r}') return identifiers, strings + ####################################### # the script From webhook-mailer at python.org Wed Mar 23 12:14:18 2022 From: webhook-mailer at python.org (zooba) Date: Wed, 23 Mar 2022 16:14:18 -0000 Subject: [Python-checkins] bpo-47086: Remove dead link to old CHM documentation (GH-32075) Message-ID: https://github.com/python/cpython/commit/fe010605f87f988ef1053e372d1c3898d2633d96 commit: fe010605f87f988ef1053e372d1c3898d2633d96 branch: main author: Steve Dower committer: zooba date: 2022-03-23T16:13:55Z summary: bpo-47086: Remove dead link to old CHM documentation (GH-32075) files: M Doc/tools/templates/download.html diff --git a/Doc/tools/templates/download.html b/Doc/tools/templates/download.html index 987c63a7f3575..2456625043416 100644 --- a/Doc/tools/templates/download.html +++ b/Doc/tools/templates/download.html @@ -40,10 +40,6 @@

Download Python {{ release }} Documentation

These archives contain all the content in the documentation.

-

HTML Help (.chm) files are made available in the "Windows" section -on the Python -download page.

-

Unpacking

From webhook-mailer at python.org Wed Mar 23 12:18:05 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 23 Mar 2022 16:18:05 -0000 Subject: [Python-checkins] Correctly document class instead of function (GH-32016) Message-ID: https://github.com/python/cpython/commit/4298114e1d6ff2063a0d4b8a6cf191b59b418975 commit: 4298114e1d6ff2063a0d4b8a6cf191b59b418975 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-23T09:17:53-07:00 summary: Correctly document class instead of function (GH-32016) (cherry picked from commit 624e3986fbf8467772e4863b7ec004e65adff619) Co-authored-by: slateny <46876382+slateny at users.noreply.github.com> files: M Doc/library/tempfile.rst diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst index 6b23a1bcd630b..30491d48e10ef 100644 --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -96,9 +96,9 @@ The module defines the following user-callable items: Added *errors* parameter. -.. function:: SpooledTemporaryFile(max_size=0, mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None) +.. class:: SpooledTemporaryFile(max_size=0, mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None) - This function operates exactly as :func:`TemporaryFile` does, except that + This class operates exactly as :func:`TemporaryFile` does, except that data is spooled in memory until the file size exceeds *max_size*, or until the file's :func:`fileno` method is called, at which point the contents are written to disk and operation proceeds as with @@ -121,9 +121,9 @@ The module defines the following user-callable items: Added *errors* parameter. -.. function:: TemporaryDirectory(suffix=None, prefix=None, dir=None, ignore_cleanup_errors=False) +.. class:: TemporaryDirectory(suffix=None, prefix=None, dir=None, ignore_cleanup_errors=False) - This function securely creates a temporary directory using the same rules as :func:`mkdtemp`. + This class securely creates a temporary directory using the same rules as :func:`mkdtemp`. The resulting object can be used as a context manager (see :ref:`tempfile-examples`). On completion of the context or destruction of the temporary directory object, the newly created temporary directory From webhook-mailer at python.org Wed Mar 23 13:29:55 2022 From: webhook-mailer at python.org (zooba) Date: Wed, 23 Mar 2022 17:29:55 -0000 Subject: [Python-checkins] bpo-31582: Created a new documentation section describing sys.path initialization (GH-31082) Message-ID: https://github.com/python/cpython/commit/c62b944dfc98911a5050389fa6ac753e283fee1f commit: c62b944dfc98911a5050389fa6ac753e283fee1f branch: main author: Russel Webber <24542073+RusselWebber at users.noreply.github.com> committer: zooba date: 2022-03-23T17:29:40Z summary: bpo-31582: Created a new documentation section describing sys.path initialization (GH-31082) files: A Doc/library/sys_path_init.rst M Doc/library/importlib.rst M Doc/library/modules.rst M Doc/library/site.rst M Doc/library/sys.rst M Doc/tutorial/modules.rst M Doc/using/windows.rst M Doc/whatsnew/3.6.rst M Doc/whatsnew/3.7.rst M Misc/ACKS diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index 23d908196669f..783653831b507 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -51,6 +51,9 @@ managing aspects of Python packages: The :func:`.__import__` function The :keyword:`import` statement is syntactic sugar for this function. + :ref:`sys-path-init` + The initialization of :data:`sys.path`. + :pep:`235` Import on Case-Insensitive Platforms diff --git a/Doc/library/modules.rst b/Doc/library/modules.rst index 131dfca9576a3..6cf6eb28a1e05 100644 --- a/Doc/library/modules.rst +++ b/Doc/library/modules.rst @@ -19,3 +19,4 @@ The full list of modules described in this chapter is: importlib.rst importlib.resources.rst importlib.metadata.rst + sys_path_init.rst diff --git a/Doc/library/site.rst b/Doc/library/site.rst index e2ad3c48f9754..5941739ee6942 100644 --- a/Doc/library/site.rst +++ b/Doc/library/site.rst @@ -276,4 +276,6 @@ value greater than 2 if there is an error. .. seealso:: - :pep:`370` -- Per user site-packages directory + * :pep:`370` -- Per user site-packages directory + * :ref:`sys-path-init` -- The initialization of :data:`sys.path`. + diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index b83b1167e8aad..3b09a4cdf8b98 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -1124,15 +1124,16 @@ always available. current directory first. Notice that the script directory is inserted *before* the entries inserted as a result of :envvar:`PYTHONPATH`. + The initialization of :data:`sys.path` is documented at :ref:`sys-path-init`. + A program is free to modify this list for its own purposes. Only strings and bytes should be added to :data:`sys.path`; all other data types are ignored during import. .. seealso:: - Module :mod:`site` This describes how to use .pth files to extend - :data:`sys.path`. - + * Module :mod:`site` This describes how to use .pth files to + extend :data:`sys.path`. .. data:: path_hooks diff --git a/Doc/library/sys_path_init.rst b/Doc/library/sys_path_init.rst new file mode 100644 index 0000000000000..72c1387344c2a --- /dev/null +++ b/Doc/library/sys_path_init.rst @@ -0,0 +1,108 @@ +.. _sys-path-init: + +The initialization of the :data:`sys.path` module search path +============================================================= + +A module search path is initialized when Python starts. This module search path +may be accessed at :data:`sys.path`. + +The first entry in the module search path is the directory that contains the +input script, if there is one. Otherwise, the first entry is the current +directory, which is the case when executing the interactive shell, a :option:`-c` +command, or :option:`-m` module. + +The :envvar:`PYTHONPATH` environment variable is often used to add directories +to the search path. If this environment variable is found then the contents are +added to the module search path. + +.. note:: + + :envvar:`PYTHONPATH` will affect all installed Python versions/environments. + Be wary of setting this in your shell profile or global environment variables. + The :mod:`site` module offers more nuanced techniques as mentioned below. + +The next items added are the directories containing standard Python modules as +well as any :term:`extension module`\s that these modules depend on. Extension +modules are ``.pyd`` files on Windows and ``.so`` files on other platforms. The +directory with the platform-independent Python modules is called ``prefix``. +The directory with the extension modules is called ``exec_prefix``. + +The :envvar:`PYTHONHOME` environment variable may be used to set the ``prefix`` +and ``exec_prefix`` locations. Otherwise these directories are found by using +the Python executable as a starting point and then looking for various 'landmark' +files and directories. Note that any symbolic links are followed so the real +Python executable location is used as the search starting point. The Python +executable location is called ``home``. + +Once ``home`` is determined, the ``prefix`` directory is found by first looking +for :file:`python{majorversion}{minorversion}.zip` (``python311.zip``). On Windows +the zip archive is searched for in ``home`` and on Unix the archive is expected +to be in :file:`lib`. Note that the expected zip archive location is added to the +module search path even if the archive does not exist. If no archive was found, +Python on Windows will continue the search for ``prefix`` by looking for :file:`Lib\\os.py`. +Python on Unix will look for :file:`lib/python{majorversion}.{minorversion}/os.py` +(``lib/python3.11/os.py``). On Windows ``prefix`` and ``exec_prefix`` are the same, +however on other platforms :file:`lib/python{majorversion}.{minorversion}/lib-dynload` +(``lib/python3.11/lib-dynload``) is searched for and used as an anchor for +``exec_prefix``. On some platforms :file:`lib` may be :file:`lib64` or another value, +see :data:`sys.platlibdir` and :envvar:`PYTHONPLATLIBDIR`. + +Once found, ``prefix`` and ``exec_prefix`` are available at :data:`sys.prefix` and +:data:`sys.exec_prefix` respectively. + +Finally, the :mod:`site` module is processed and :file:`site-packages` directories +are added to the module search path. A common way to customize the search path is +to create :mod:`sitecustomize` or :mod:`usercustomize` modules as described in +the :mod:`site` module documentation. + +.. note:: + + Certain command line options may further affect path calculations. + See :option:`-E`, :option:`-I`, :option:`-s` and :option:`-S` for further details. + +Virtual environments +-------------------- + +If Python is run in a virtual environment (as described at :ref:`tut-venv`) +then ``prefix`` and ``exec_prefix`` are specific to the virtual environment. + +If a ``pyvenv.cfg`` file is found alongside the main executable, or in the +directory one level above the executable, the following variations apply: + +* If ``home`` is an absolute path and :envvar:`PYTHONHOME` is not set, this + path is used instead of the path to the main executable when deducing ``prefix`` + and ``exec_prefix``. + +_pth files +---------- + +To completely override :data:`sys.path` create a ``._pth`` file with the same +name as the shared library or executable (``python._pth`` or ``python311._pth``). +The shared library path is always known on Windows, however it may not be +available on other platforms. In the ``._pth`` file specify one line for each path +to add to :data:`sys.path`. The file based on the shared library name overrides +the one based on the executable, which allows paths to be restricted for any +program loading the runtime if desired. + +When the file exists, all registry and environment variables are ignored, +isolated mode is enabled, and :mod:`site` is not imported unless one line in the +file specifies ``import site``. Blank paths and lines starting with ``#`` are +ignored. Each path may be absolute or relative to the location of the file. +Import statements other than to ``site`` are not permitted, and arbitrary code +cannot be specified. + +Note that ``.pth`` files (without leading underscore) will be processed normally +by the :mod:`site` module when ``import site`` has been specified. + +Embedded Python +--------------- + +If Python is embedded within another application :c:func:`Py_InitializeFromConfig` and +the :c:type:`PyConfig` structure can be used to initialize Python. The path specific +details are described at :ref:`init-path-config`. Alternatively the older :c:func:`Py_SetPath` +can be used to bypass the initialization of the module search path. + +.. seealso:: + + * :ref:`windows_finding_modules` for detailed Windows notes. + * :ref:`using-on-unix` for Unix details. diff --git a/Doc/tutorial/modules.rst b/Doc/tutorial/modules.rst index f1d4957e37eb1..a4e1cefb26b71 100644 --- a/Doc/tutorial/modules.rst +++ b/Doc/tutorial/modules.rst @@ -194,6 +194,8 @@ named :file:`spam.py` in a list of directories given by the variable * The installation-dependent default (by convention including a ``site-packages`` directory, handled by the :mod:`site` module). +More details are at :ref:`sys-path-init`. + .. note:: On file systems which support symlinks, the directory containing the input script is calculated after the symlink is followed. In other words the diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index 26c19ddbbce78..618dfeac0a765 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -946,32 +946,13 @@ target Python. -.. _finding_modules: +.. _windows_finding_modules: Finding modules =============== -Python usually stores its library (and thereby your site-packages folder) in the -installation directory. So, if you had installed Python to -:file:`C:\\Python\\`, the default library would reside in -:file:`C:\\Python\\Lib\\` and third-party modules should be stored in -:file:`C:\\Python\\Lib\\site-packages\\`. - -To completely override :data:`sys.path`, create a ``._pth`` file with the same -name as the DLL (``python37._pth``) or the executable (``python._pth``) and -specify one line for each path to add to :data:`sys.path`. The file based on the -DLL name overrides the one based on the executable, which allows paths to be -restricted for any program loading the runtime if desired. - -When the file exists, all registry and environment variables are ignored, -isolated mode is enabled, and :mod:`site` is not imported unless one line in the -file specifies ``import site``. Blank paths and lines starting with ``#`` are -ignored. Each path may be absolute or relative to the location of the file. -Import statements other than to ``site`` are not permitted, and arbitrary code -cannot be specified. - -Note that ``.pth`` files (without leading underscore) will be processed normally -by the :mod:`site` module when ``import site`` has been specified. +These notes supplement the description at :ref:`sys-path-init` with +detailed Windows notes. When no ``._pth`` file is found, this is how :data:`sys.path` is populated on Windows: diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst index a56d7a592305f..d35a0fd9d9da3 100644 --- a/Doc/whatsnew/3.6.rst +++ b/Doc/whatsnew/3.6.rst @@ -162,10 +162,10 @@ Windows improvements: * A ``._pth`` file can be added to force isolated mode and fully specify all search paths to avoid registry and environment lookup. See - :ref:`the documentation ` for more information. + :ref:`the documentation ` for more information. * A ``python36.zip`` file now works as a landmark to infer - :envvar:`PYTHONHOME`. See :ref:`the documentation ` for + :envvar:`PYTHONHOME`. See :ref:`the documentation ` for more information. diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index dcbd0926bcada..5ce637a6c12c1 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -2474,7 +2474,7 @@ Windows-only Changes The file used to override :data:`sys.path` is now called ``._pth`` instead of ``'sys.path'``. -See :ref:`finding_modules` for more information. +See :ref:`windows_finding_modules` for more information. (Contributed by Steve Dower in :issue:`28137`.) diff --git a/Misc/ACKS b/Misc/ACKS index cfc15be2c9748..efa2474c3cfdb 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1897,6 +1897,7 @@ Colin Watson David Watson Aaron Watters Alex Waygood +Russel Webber Henrik Weber Leon Weber Steve Weber From webhook-mailer at python.org Wed Mar 23 14:19:47 2022 From: webhook-mailer at python.org (ambv) Date: Wed, 23 Mar 2022 18:19:47 -0000 Subject: [Python-checkins] [3.9] bpo-46769: Improve documentation for `typing.TypeVar` (GH-31712) (GH-31941) (GH-32067) Message-ID: https://github.com/python/cpython/commit/0bbb6956f83ef457872b8f04242bb02b6898350d commit: 0bbb6956f83ef457872b8f04242bb02b6898350d branch: 3.9 author: Jelle Zijlstra committer: ambv date: 2022-03-23T19:19:23+01:00 summary: [3.9] bpo-46769: Improve documentation for `typing.TypeVar` (GH-31712) (GH-31941) (GH-32067) * [3.9] [3.10] bpo-46769: Improve documentation for `typing.TypeVar` (GH-31712) (GH-31941) * [3.10] bpo-46769: Improve documentation for `typing.TypeVar` (GH-31712) Co-authored-by: Jelle Zijlstra (cherry picked from commit 81b425d4dc43b60dd11a3e9abc5c84a4b8b384db) * Remove references to `reveal_type`, add new section on `self` types. (cherry picked from commit d5ed8a8258eaf7a241978b1b0aeb971108d0f7e0) Co-authored-by: Alex Waygood * remove unused susp allowlist Co-authored-by: Alex Waygood files: M Doc/library/typing.rst M Doc/tools/susp-ignored.csv diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 13fc418e9274b..2689c7f293871 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -214,7 +214,7 @@ subscription to denote expected types for container elements. def notify_by_email(employees: Sequence[Employee], overrides: Mapping[str, str]) -> None: ... -Generics can be parameterized by using a new factory available in typing +Generics can be parameterized by using a factory available in typing called :class:`TypeVar`. :: @@ -271,16 +271,16 @@ that ``LoggedVar[t]`` is valid as a type:: for var in vars: var.set(0) -A generic type can have any number of type variables, and type variables may -be constrained:: +A generic type can have any number of type variables. All varieties of +:class:`TypeVar` are permissible as parameters for a generic type:: - from typing import TypeVar, Generic - ... + from typing import TypeVar, Generic, Sequence - T = TypeVar('T') + T = TypeVar('T', contravariant=True) + B = TypeVar('B', bound=Sequence[bytes], covariant=True) S = TypeVar('S', int, str) - class StrangePair(Generic[T, S]): + class WeirdTrio(Generic[T, B, S]): ... Each type variable argument to :class:`Generic` must be distinct. @@ -856,7 +856,8 @@ These are not used in annotations. They are building blocks for creating generic Usage:: T = TypeVar('T') # Can be anything - A = TypeVar('A', str, bytes) # Must be str or bytes + S = TypeVar('S', bound=str) # Can be any subtype of str + A = TypeVar('A', str, bytes) # Must be exactly str or bytes Type variables exist primarily for the benefit of static type checkers. They serve as the parameters for generic types as well @@ -867,29 +868,95 @@ These are not used in annotations. They are building blocks for creating generic """Return a list containing n references to x.""" return [x]*n - def longest(x: A, y: A) -> A: - """Return the longest of two strings.""" - return x if len(x) >= len(y) else y - The latter example's signature is essentially the overloading - of ``(str, str) -> str`` and ``(bytes, bytes) -> bytes``. Also note - that if the arguments are instances of some subclass of :class:`str`, - the return type is still plain :class:`str`. + def print_capitalized(x: S) -> S: + """Print x capitalized, and return x.""" + print(x.capitalize()) + return x + + + def concatenate(x: A, y: A) -> A: + """Add two strings or bytes objects together.""" + return x + y + + Note that type variables can be *bound*, *constrained*, or neither, but + cannot be both bound *and* constrained. + + Constrained type variables and bound type variables have different + semantics in several important ways. Using a *constrained* type variable + means that the ``TypeVar`` can only ever be solved as being exactly one of + the constraints given:: + + a = concatenate('one', 'two') # Ok, variable 'a' has type 'str' + b = concatenate(StringSubclass('one'), StringSubclass('two')) # Inferred type of variable 'b' is 'str', + # despite 'StringSubclass' being passed in + c = concatenate('one', b'two') # error: type variable 'A' can be either 'str' or 'bytes' in a function call, but not both + + Using a *bound* type variable, however, means that the ``TypeVar`` will be + solved using the most specific type possible:: + + print_capitalized('a string') # Ok, output has type 'str' + + class StringSubclass(str): + pass + + print_capitalized(StringSubclass('another string')) # Ok, output has type 'StringSubclass' + print_capitalized(45) # error: int is not a subtype of str + + Type variables can be bound to concrete types, abstract types (ABCs or + protocols), and even unions of types:: + + U = TypeVar('U', bound=str|bytes) # Can be any subtype of the union str|bytes + V = TypeVar('V', bound=SupportsAbs) # Can be anything with an __abs__ method + + Bound type variables are particularly useful for annotating + :func:`classmethods ` that serve as alternative constructors. + In the following example (? + `Raymond Hettinger `_), the + type variable ``C`` is bound to the ``Circle`` class through the use of a + forward reference. Using this type variable to annotate the + ``with_circumference`` classmethod, rather than hardcoding the return type + as ``Circle``, means that a type checker can correctly infer the return + type even if the method is called on a subclass:: + + import math + + C = TypeVar('C', bound='Circle') + + class Circle: + """An abstract circle""" + + def __init__(self, radius: float) -> None: + self.radius = radius + + # Use a type variable to show that the return type + # will always be an instance of whatever `cls` is + @classmethod + def with_circumference(cls: type[C], circumference: float) -> C: + """Create a circle with the specified circumference""" + radius = circumference / (math.pi * 2) + return cls(radius) + + + class Tire(Circle): + """A specialised circle (made out of rubber)""" + + MATERIAL = 'rubber' + + + c = Circle.with_circumference(3) # Ok, variable 'c' has type 'Circle' + t = Tire.with_circumference(4) # Ok, variable 't' has type 'Tire' (not 'Circle') At runtime, ``isinstance(x, T)`` will raise :exc:`TypeError`. In general, :func:`isinstance` and :func:`issubclass` should not be used with types. Type variables may be marked covariant or contravariant by passing ``covariant=True`` or ``contravariant=True``. See :pep:`484` for more - details. By default type variables are invariant. Alternatively, - a type variable may specify an upper bound using ``bound=``. - This means that an actual type substituted (explicitly or implicitly) - for the type variable must be a subclass of the boundary type, - see :pep:`484`. + details. By default, type variables are invariant. .. data:: AnyStr - ``AnyStr`` is a type variable defined as + ``AnyStr`` is a :class:`constrained type variable ` defined as ``AnyStr = TypeVar('AnyStr', str, bytes)``. It is meant to be used for functions that may accept any kind of string diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv index 48480ed567713..67e449316e4a2 100644 --- a/Doc/tools/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -370,3 +370,4 @@ whatsnew/changelog,,::,default::DeprecationWarning library/importlib.metadata,,:main,"EntryPoint(name='wheel', value='wheel.cli:main', group='console_scripts')" library/importlib.metadata,,`,loading the metadata for packages for the indicated ``context``. library/re,,`,"`" +library/typing,,`, # will always be an instance of whatever `cls` is From webhook-mailer at python.org Wed Mar 23 16:13:18 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 23 Mar 2022 20:13:18 -0000 Subject: [Python-checkins] [3.9] bpo-47061: document module deprecations due to PEP 594 (GH-31984) (GH-32082) Message-ID: https://github.com/python/cpython/commit/e513b8188af4d2f43ab2b96b51bc45bd4f6fd5b6 commit: e513b8188af4d2f43ab2b96b51bc45bd4f6fd5b6 branch: 3.9 author: Hugo van Kemenade committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-23T13:13:08-07:00 summary: [3.9] bpo-47061: document module deprecations due to PEP 594 (GH-31984) (GH-32082) Also removed asynchat, asyncore, and smtpd from their respective toctree entries so they are only in the superceded subtree. (cherry picked from commit 9ac2de922a0f783bd43b8e026e4fb70fd1888572) Co-authored-by: Brett Cannon Automerge-Triggered-By: GH:brettcannon files: A Misc/NEWS.d/next/Library/2022-03-18-13-30-40.bpo-47061.etLHK5.rst M Doc/library/aifc.rst M Doc/library/audioop.rst M Doc/library/cgi.rst M Doc/library/cgitb.rst M Doc/library/chunk.rst M Doc/library/crypt.rst M Doc/library/fileformats.rst M Doc/library/imghdr.rst M Doc/library/internet.rst M Doc/library/ipc.rst M Doc/library/mm.rst M Doc/library/msilib.rst M Doc/library/netdata.rst M Doc/library/nis.rst M Doc/library/nntplib.rst M Doc/library/ossaudiodev.rst M Doc/library/pipes.rst M Doc/library/sndhdr.rst M Doc/library/spwd.rst M Doc/library/sunau.rst M Doc/library/superseded.rst M Doc/library/telnetlib.rst M Doc/library/unix.rst M Doc/library/uu.rst M Doc/library/windows.rst M Doc/library/xdrlib.rst diff --git a/Doc/library/aifc.rst b/Doc/library/aifc.rst index 2e917cf7321b8..edb4bf86e5a0a 100644 --- a/Doc/library/aifc.rst +++ b/Doc/library/aifc.rst @@ -3,6 +3,7 @@ .. module:: aifc :synopsis: Read and write audio files in AIFF or AIFC format. + :deprecated: **Source code:** :source:`Lib/aifc.py` @@ -11,6 +12,10 @@ single: AIFF single: AIFF-C + +.. deprecated:: 3.11 + The :mod:`aifc` module is deprecated (see :pep:`594` for details). + -------------- This module provides support for reading and writing AIFF and AIFF-C files. diff --git a/Doc/library/audioop.rst b/Doc/library/audioop.rst index bad9da2ec62e5..eae206084f090 100644 --- a/Doc/library/audioop.rst +++ b/Doc/library/audioop.rst @@ -3,6 +3,10 @@ .. module:: audioop :synopsis: Manipulate raw audio data. + :deprecated: + +.. deprecated:: 3.11 + The :mod:`audioop` module is deprecated (see :pep:`594` for details). -------------- diff --git a/Doc/library/cgi.rst b/Doc/library/cgi.rst index 3ec919e9ccd00..80c4d8033130c 100644 --- a/Doc/library/cgi.rst +++ b/Doc/library/cgi.rst @@ -3,6 +3,7 @@ .. module:: cgi :synopsis: Helpers for running Python scripts via the Common Gateway Interface. + :deprecated: **Source code:** :source:`Lib/cgi.py` @@ -14,6 +15,9 @@ single: URL single: Common Gateway Interface +.. deprecated:: 3.11 + The :mod:`cgi` module is deprecated (see :pep:`594` for details). + -------------- Support module for Common Gateway Interface (CGI) scripts. diff --git a/Doc/library/cgitb.rst b/Doc/library/cgitb.rst index 5f3a6476dd8cd..349414610bd40 100644 --- a/Doc/library/cgitb.rst +++ b/Doc/library/cgitb.rst @@ -3,6 +3,7 @@ .. module:: cgitb :synopsis: Configurable traceback handler for CGI scripts. + :deprecated: .. moduleauthor:: Ka-Ping Yee .. sectionauthor:: Fred L. Drake, Jr. @@ -15,6 +16,9 @@ single: exceptions; in CGI scripts single: tracebacks; in CGI scripts +.. deprecated:: 3.11 + The :mod:`cgitb` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`cgitb` module provides a special exception handler for Python scripts. diff --git a/Doc/library/chunk.rst b/Doc/library/chunk.rst index 5e24df923ed21..7999420f536d7 100644 --- a/Doc/library/chunk.rst +++ b/Doc/library/chunk.rst @@ -3,6 +3,7 @@ .. module:: chunk :synopsis: Module to read IFF chunks. + :deprecated: .. moduleauthor:: Sjoerd Mullender .. sectionauthor:: Sjoerd Mullender @@ -16,6 +17,9 @@ single: Real Media File Format single: RMFF +.. deprecated:: 3.11 + The :mod:`chunk` module is deprecated (see :pep:`594` for details). + -------------- This module provides an interface for reading files that use EA IFF 85 chunks. diff --git a/Doc/library/crypt.rst b/Doc/library/crypt.rst index d25c626a17585..73df87ca0db8d 100644 --- a/Doc/library/crypt.rst +++ b/Doc/library/crypt.rst @@ -4,6 +4,7 @@ .. module:: crypt :platform: Unix :synopsis: The crypt() function used to check Unix passwords. + :deprecated: .. moduleauthor:: Steven D. Majewski .. sectionauthor:: Steven D. Majewski @@ -15,6 +16,9 @@ single: crypt(3) pair: cipher; DES +.. deprecated:: 3.11 + The :mod:`crypt` module is deprecated (see :pep:`594` for details). + -------------- This module implements an interface to the :manpage:`crypt(3)` routine, which is diff --git a/Doc/library/fileformats.rst b/Doc/library/fileformats.rst index e9c2e1fbbdf3e..7b33b3364572d 100644 --- a/Doc/library/fileformats.rst +++ b/Doc/library/fileformats.rst @@ -13,5 +13,4 @@ that aren't markup languages and are not related to e-mail. csv.rst configparser.rst netrc.rst - xdrlib.rst plistlib.rst diff --git a/Doc/library/imghdr.rst b/Doc/library/imghdr.rst index 800e919599d9c..f63a0fa56fd26 100644 --- a/Doc/library/imghdr.rst +++ b/Doc/library/imghdr.rst @@ -3,9 +3,13 @@ .. module:: imghdr :synopsis: Determine the type of image contained in a file or byte stream. + :deprecated: **Source code:** :source:`Lib/imghdr.py` +.. deprecated:: 3.11 + The :mod:`imghdr` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`imghdr` module determines the type of image contained in a file or diff --git a/Doc/library/internet.rst b/Doc/library/internet.rst index b8950bb6cb8c2..c8bab2a5836ad 100644 --- a/Doc/library/internet.rst +++ b/Doc/library/internet.rst @@ -20,8 +20,6 @@ is currently supported on most popular platforms. Here is an overview: .. toctree:: webbrowser.rst - cgi.rst - cgitb.rst wsgiref.rst urllib.rst urllib.request.rst @@ -33,10 +31,7 @@ is currently supported on most popular platforms. Here is an overview: ftplib.rst poplib.rst imaplib.rst - nntplib.rst smtplib.rst - smtpd.rst - telnetlib.rst uuid.rst socketserver.rst http.server.rst diff --git a/Doc/library/ipc.rst b/Doc/library/ipc.rst index b88a174eb97f1..4849c82f317d9 100644 --- a/Doc/library/ipc.rst +++ b/Doc/library/ipc.rst @@ -22,7 +22,5 @@ The list of modules described in this chapter is: ssl.rst select.rst selectors.rst - asyncore.rst - asynchat.rst signal.rst mmap.rst diff --git a/Doc/library/mm.rst b/Doc/library/mm.rst index c8f79c4de1cdf..cd06e9385a261 100644 --- a/Doc/library/mm.rst +++ b/Doc/library/mm.rst @@ -11,12 +11,5 @@ discretion of the installation. Here's an overview: .. toctree:: - audioop.rst - aifc.rst - sunau.rst wave.rst - chunk.rst colorsys.rst - imghdr.rst - sndhdr.rst - ossaudiodev.rst diff --git a/Doc/library/msilib.rst b/Doc/library/msilib.rst index 83b3d4973bf0d..5ce18a1f75fc2 100644 --- a/Doc/library/msilib.rst +++ b/Doc/library/msilib.rst @@ -4,6 +4,7 @@ .. module:: msilib :platform: Windows :synopsis: Creation of Microsoft Installer files, and CAB files. + :deprecated: .. moduleauthor:: Martin v. L?wis .. sectionauthor:: Martin v. L?wis @@ -12,6 +13,9 @@ .. index:: single: msi +.. deprecated:: 3.11 + The :mod:`msilib` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`msilib` supports the creation of Microsoft Installer (``.msi``) files. diff --git a/Doc/library/netdata.rst b/Doc/library/netdata.rst index 491501665e3d7..8a3ad68753a53 100644 --- a/Doc/library/netdata.rst +++ b/Doc/library/netdata.rst @@ -20,4 +20,3 @@ on the Internet. binhex.rst binascii.rst quopri.rst - uu.rst diff --git a/Doc/library/nis.rst b/Doc/library/nis.rst index 10c67cbb81b2f..f6b6ea83946b0 100644 --- a/Doc/library/nis.rst +++ b/Doc/library/nis.rst @@ -5,10 +5,14 @@ .. module:: nis :platform: Unix :synopsis: Interface to Sun's NIS (Yellow Pages) library. + :deprecated: .. moduleauthor:: Fred Gansevles .. sectionauthor:: Moshe Zadka +.. deprecated:: 3.11 + The :mod:`nis` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`nis` module gives a thin wrapper around the NIS library, useful for diff --git a/Doc/library/nntplib.rst b/Doc/library/nntplib.rst index e7ec9047e015e..2a996e451bf7c 100644 --- a/Doc/library/nntplib.rst +++ b/Doc/library/nntplib.rst @@ -3,6 +3,7 @@ .. module:: nntplib :synopsis: NNTP protocol client (requires sockets). + :deprecated: **Source code:** :source:`Lib/nntplib.py` @@ -10,6 +11,9 @@ pair: NNTP; protocol single: Network News Transfer Protocol +.. deprecated:: 3.11 + The :mod:`nntplib` module is deprecated (see :pep:`594` for details). + -------------- This module defines the class :class:`NNTP` which implements the client side of diff --git a/Doc/library/ossaudiodev.rst b/Doc/library/ossaudiodev.rst index a7d3dac363cdf..e0f0a6b8259e4 100644 --- a/Doc/library/ossaudiodev.rst +++ b/Doc/library/ossaudiodev.rst @@ -4,6 +4,10 @@ .. module:: ossaudiodev :platform: Linux, FreeBSD :synopsis: Access to OSS-compatible audio devices. + :deprecated: + +.. deprecated:: 3.11 + The :mod:`ossaudiodev` module is deprecated (see :pep:`594` for details). -------------- diff --git a/Doc/library/pipes.rst b/Doc/library/pipes.rst index 0a22da1f555bc..25f808566ecf9 100644 --- a/Doc/library/pipes.rst +++ b/Doc/library/pipes.rst @@ -4,11 +4,15 @@ .. module:: pipes :platform: Unix :synopsis: A Python interface to Unix shell pipelines. + :deprecated: .. sectionauthor:: Moshe Zadka **Source code:** :source:`Lib/pipes.py` +.. deprecated:: 3.11 + The :mod:`pipes` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`pipes` module defines a class to abstract the concept of a *pipeline* diff --git a/Doc/library/sndhdr.rst b/Doc/library/sndhdr.rst index 6bfa9a9fd210b..41bce18b9cd84 100644 --- a/Doc/library/sndhdr.rst +++ b/Doc/library/sndhdr.rst @@ -3,6 +3,7 @@ .. module:: sndhdr :synopsis: Determine type of a sound file. + :deprecated: .. sectionauthor:: Fred L. Drake, Jr. .. Based on comments in the module source file. @@ -13,6 +14,9 @@ single: A-LAW single: u-LAW +.. deprecated:: 3.11 + The :mod:`sndhdr` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`sndhdr` provides utility functions which attempt to determine the type diff --git a/Doc/library/spwd.rst b/Doc/library/spwd.rst index c6cad2a3c3284..cb31a10a52e00 100644 --- a/Doc/library/spwd.rst +++ b/Doc/library/spwd.rst @@ -4,6 +4,10 @@ .. module:: spwd :platform: Unix :synopsis: The shadow password database (getspnam() and friends). + :deprecated: + +.. deprecated:: 3.11 + The :mod:`spwd` module is deprecated (see :pep:`594` for details). -------------- diff --git a/Doc/library/sunau.rst b/Doc/library/sunau.rst index aad6f93b6bff1..cfb1257f58548 100644 --- a/Doc/library/sunau.rst +++ b/Doc/library/sunau.rst @@ -3,11 +3,15 @@ .. module:: sunau :synopsis: Provide an interface to the Sun AU sound format. + :deprecated: .. sectionauthor:: Moshe Zadka **Source code:** :source:`Lib/sunau.py` +.. deprecated:: 3.11 + The :mod:`sunau` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`sunau` module provides a convenient interface to the Sun AU sound diff --git a/Doc/library/superseded.rst b/Doc/library/superseded.rst index fd23e4d1536d3..e3f9b0d37fe10 100644 --- a/Doc/library/superseded.rst +++ b/Doc/library/superseded.rst @@ -10,8 +10,26 @@ backwards compatibility. They have been superseded by other modules. .. toctree:: + aifc.rst asynchat.rst asyncore.rst - smtpd.rst + audioop.rst + cgi.rst + cgitb.rst + chunk.rst + crypt.rst + imghdr.rst imp.rst + msilib.rst + nntplib.rst + nis.rst optparse.rst + ossaudiodev.rst + pipes.rst + smtpd.rst + sndhdr.rst + spwd.rst + sunau.rst + telnetlib.rst + uu.rst + xdrlib.rst diff --git a/Doc/library/telnetlib.rst b/Doc/library/telnetlib.rst index 48a9aea50dddd..97b0a713e4422 100644 --- a/Doc/library/telnetlib.rst +++ b/Doc/library/telnetlib.rst @@ -3,6 +3,7 @@ .. module:: telnetlib :synopsis: Telnet client class. + :deprecated: .. sectionauthor:: Skip Montanaro @@ -10,6 +11,9 @@ .. index:: single: protocol; Telnet +.. deprecated:: 3.11 + The :mod:`telnetlib` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`telnetlib` module provides a :class:`Telnet` class that implements the diff --git a/Doc/library/unix.rst b/Doc/library/unix.rst index 04d4081f4a073..4553a104d15a2 100644 --- a/Doc/library/unix.rst +++ b/Doc/library/unix.rst @@ -13,14 +13,10 @@ of it. Here's an overview: posix.rst pwd.rst - spwd.rst grp.rst - crypt.rst termios.rst tty.rst pty.rst fcntl.rst - pipes.rst resource.rst - nis.rst syslog.rst diff --git a/Doc/library/uu.rst b/Doc/library/uu.rst index 0bc8021e1bdfc..c341bc83dcfed 100644 --- a/Doc/library/uu.rst +++ b/Doc/library/uu.rst @@ -3,11 +3,15 @@ .. module:: uu :synopsis: Encode and decode files in uuencode format. + :deprecated: .. moduleauthor:: Lance Ellinghouse **Source code:** :source:`Lib/uu.py` +.. deprecated:: 3.11 + The :mod:`uu` module is deprecated (see :pep:`594` for details). + -------------- This module encodes and decodes files in uuencode format, allowing arbitrary diff --git a/Doc/library/windows.rst b/Doc/library/windows.rst index b60d4e4ccf51d..4d72ead12aadc 100644 --- a/Doc/library/windows.rst +++ b/Doc/library/windows.rst @@ -9,7 +9,6 @@ This chapter describes modules that are only available on MS Windows platforms. .. toctree:: - msilib.rst msvcrt.rst winreg.rst winsound.rst diff --git a/Doc/library/xdrlib.rst b/Doc/library/xdrlib.rst index 42a03a46754d0..060b2e2c60df6 100644 --- a/Doc/library/xdrlib.rst +++ b/Doc/library/xdrlib.rst @@ -3,6 +3,7 @@ .. module:: xdrlib :synopsis: Encoders and decoders for the External Data Representation (XDR). + :deprecated: **Source code:** :source:`Lib/xdrlib.py` @@ -10,6 +11,9 @@ single: XDR single: External Data Representation +.. deprecated:: 3.11 + The :mod:`xdrlib` module is deprecated (see :pep:`594` for details). + -------------- The :mod:`xdrlib` module supports the External Data Representation Standard as diff --git a/Misc/NEWS.d/next/Library/2022-03-18-13-30-40.bpo-47061.etLHK5.rst b/Misc/NEWS.d/next/Library/2022-03-18-13-30-40.bpo-47061.etLHK5.rst new file mode 100644 index 0000000000000..5445089e53c39 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-18-13-30-40.bpo-47061.etLHK5.rst @@ -0,0 +1,5 @@ +Deprecate the various modules listed by :pep:`594`: + +aifc, asynchat, asyncore, audioop, cgi, cgitb, chunk, crypt, +imghdr, msilib, nntplib, nis, ossaudiodev, pipes, smtpd, +sndhdr, spwd, sunau, telnetlib, uu, xdrlib From webhook-mailer at python.org Wed Mar 23 16:30:18 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 23 Mar 2022 20:30:18 -0000 Subject: [Python-checkins] bpo-47101: list only activated algorithms in hashlib.algorithms_available (GH-32076) Message-ID: https://github.com/python/cpython/commit/48e2010d92076b472922fa632fffc98ee150004f commit: 48e2010d92076b472922fa632fffc98ee150004f branch: main author: Christian Heimes committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-23T13:30:05-07:00 summary: bpo-47101: list only activated algorithms in hashlib.algorithms_available (GH-32076) files: A Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst M Lib/test/test_hashlib.py M Modules/_hashopenssl.c diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py index 369bbde6e78b6..d2a92147d5f02 100644 --- a/Lib/test/test_hashlib.py +++ b/Lib/test/test_hashlib.py @@ -223,6 +223,10 @@ def test_algorithms_guaranteed(self): def test_algorithms_available(self): self.assertTrue(set(hashlib.algorithms_guaranteed). issubset(hashlib.algorithms_available)) + # all available algorithms must be loadable, bpo-47101 + self.assertNotIn("undefined", hashlib.algorithms_available) + for name in hashlib.algorithms_available: + digest = hashlib.new(name, usedforsecurity=False) def test_usedforsecurity_true(self): hashlib.new("sha256", usedforsecurity=True) diff --git a/Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst b/Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst new file mode 100644 index 0000000000000..1a65024e69fbd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst @@ -0,0 +1,4 @@ +:const:`hashlib.algorithms_available` now lists only algorithms that are +provided by activated crypto providers on OpenSSL 3.0. Legacy algorithms are +not listed unless the legacy provider has been loaded into the default +OSSL context. diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index bb9487204e741..203366e380d4e 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -1836,15 +1836,21 @@ typedef struct _internal_name_mapper_state { /* A callback function to pass to OpenSSL's OBJ_NAME_do_all(...) */ static void +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +_openssl_hash_name_mapper(EVP_MD *md, void *arg) +#else _openssl_hash_name_mapper(const EVP_MD *md, const char *from, const char *to, void *arg) +#endif { _InternalNameMapperState *state = (_InternalNameMapperState *)arg; PyObject *py_name; assert(state != NULL); - if (md == NULL) + // ignore all undefined providers + if ((md == NULL) || (EVP_MD_nid(md) == NID_undef)) { return; + } py_name = py_digest_name(md); if (py_name == NULL) { @@ -1870,7 +1876,12 @@ hashlib_md_meth_names(PyObject *module) return -1; } +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + // get algorithms from all activated providers in default context + EVP_MD_do_all_provided(NULL, &_openssl_hash_name_mapper, &state); +#else EVP_MD_do_all(&_openssl_hash_name_mapper, &state); +#endif if (state.error) { Py_DECREF(state.set); From webhook-mailer at python.org Wed Mar 23 16:58:07 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 23 Mar 2022 20:58:07 -0000 Subject: [Python-checkins] bpo-47101: list only activated algorithms in hashlib.algorithms_available (GH-32076) Message-ID: https://github.com/python/cpython/commit/ec3589f59d2c8456591f33656639bcc303eb7bd5 commit: ec3589f59d2c8456591f33656639bcc303eb7bd5 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-23T13:58:02-07:00 summary: bpo-47101: list only activated algorithms in hashlib.algorithms_available (GH-32076) (cherry picked from commit 48e2010d92076b472922fa632fffc98ee150004f) Co-authored-by: Christian Heimes files: A Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst M Lib/test/test_hashlib.py M Modules/_hashopenssl.c diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py index 214bc3cb2b187..f845c7a76e7cb 100644 --- a/Lib/test/test_hashlib.py +++ b/Lib/test/test_hashlib.py @@ -223,6 +223,10 @@ def test_algorithms_guaranteed(self): def test_algorithms_available(self): self.assertTrue(set(hashlib.algorithms_guaranteed). issubset(hashlib.algorithms_available)) + # all available algorithms must be loadable, bpo-47101 + self.assertNotIn("undefined", hashlib.algorithms_available) + for name in hashlib.algorithms_available: + digest = hashlib.new(name, usedforsecurity=False) def test_usedforsecurity_true(self): hashlib.new("sha256", usedforsecurity=True) diff --git a/Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst b/Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst new file mode 100644 index 0000000000000..1a65024e69fbd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst @@ -0,0 +1,4 @@ +:const:`hashlib.algorithms_available` now lists only algorithms that are +provided by activated crypto providers on OpenSSL 3.0. Legacy algorithms are +not listed unless the legacy provider has been loaded into the default +OSSL context. diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 4873bb11aa0cd..4db058c06275f 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -1860,15 +1860,21 @@ typedef struct _internal_name_mapper_state { /* A callback function to pass to OpenSSL's OBJ_NAME_do_all(...) */ static void +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +_openssl_hash_name_mapper(EVP_MD *md, void *arg) +#else _openssl_hash_name_mapper(const EVP_MD *md, const char *from, const char *to, void *arg) +#endif { _InternalNameMapperState *state = (_InternalNameMapperState *)arg; PyObject *py_name; assert(state != NULL); - if (md == NULL) + // ignore all undefined providers + if ((md == NULL) || (EVP_MD_nid(md) == NID_undef)) { return; + } py_name = py_digest_name(md); if (py_name == NULL) { @@ -1894,7 +1900,12 @@ hashlib_md_meth_names(PyObject *module) return -1; } +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + // get algorithms from all activated providers in default context + EVP_MD_do_all_provided(NULL, &_openssl_hash_name_mapper, &state); +#else EVP_MD_do_all(&_openssl_hash_name_mapper, &state); +#endif if (state.error) { Py_DECREF(state.set); From webhook-mailer at python.org Wed Mar 23 17:15:34 2022 From: webhook-mailer at python.org (tiran) Date: Wed, 23 Mar 2022 21:15:34 -0000 Subject: [Python-checkins] [3.10] bpo-47101: list only activated algorithms in hashlib.algorithms_available (GH-32076) (GH-32085) Message-ID: https://github.com/python/cpython/commit/1b6acaad9a18b2498386c60f24351ab749061e3a commit: 1b6acaad9a18b2498386c60f24351ab749061e3a branch: 3.10 author: Christian Heimes committer: tiran date: 2022-03-23T22:15:25+01:00 summary: [3.10] bpo-47101: list only activated algorithms in hashlib.algorithms_available (GH-32076) (GH-32085) Co-authored-by: Christian Heimes files: A Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst M Lib/test/test_hashlib.py M Modules/_hashopenssl.c diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py index ea31f8be2cb82..535f4aa3e04ca 100644 --- a/Lib/test/test_hashlib.py +++ b/Lib/test/test_hashlib.py @@ -221,6 +221,10 @@ def test_algorithms_guaranteed(self): def test_algorithms_available(self): self.assertTrue(set(hashlib.algorithms_guaranteed). issubset(hashlib.algorithms_available)) + # all available algorithms must be loadable, bpo-47101 + self.assertNotIn("undefined", hashlib.algorithms_available) + for name in hashlib.algorithms_available: + digest = hashlib.new(name, usedforsecurity=False) def test_usedforsecurity_true(self): hashlib.new("sha256", usedforsecurity=True) diff --git a/Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst b/Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst new file mode 100644 index 0000000000000..1a65024e69fbd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst @@ -0,0 +1,4 @@ +:const:`hashlib.algorithms_available` now lists only algorithms that are +provided by activated crypto providers on OpenSSL 3.0. Legacy algorithms are +not listed unless the legacy provider has been loaded into the default +OSSL context. diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 65538f63f7bf4..75063fa15369a 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -1836,15 +1836,21 @@ typedef struct _internal_name_mapper_state { /* A callback function to pass to OpenSSL's OBJ_NAME_do_all(...) */ static void +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +_openssl_hash_name_mapper(EVP_MD *md, void *arg) +#else _openssl_hash_name_mapper(const EVP_MD *md, const char *from, const char *to, void *arg) +#endif { _InternalNameMapperState *state = (_InternalNameMapperState *)arg; PyObject *py_name; assert(state != NULL); - if (md == NULL) + // ignore all undefined providers + if ((md == NULL) || (EVP_MD_nid(md) == NID_undef)) { return; + } py_name = py_digest_name(md); if (py_name == NULL) { @@ -1870,7 +1876,12 @@ hashlib_md_meth_names(PyObject *module) return -1; } +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + // get algorithms from all activated providers in default context + EVP_MD_do_all_provided(NULL, &_openssl_hash_name_mapper, &state); +#else EVP_MD_do_all(&_openssl_hash_name_mapper, &state); +#endif if (state.error) { Py_DECREF(state.set); From webhook-mailer at python.org Wed Mar 23 17:17:18 2022 From: webhook-mailer at python.org (asvetlov) Date: Wed, 23 Mar 2022 21:17:18 -0000 Subject: [Python-checkins] bpo-47104: Rewrite asyncio.to_thread tests to use IsolatedAsyncioTestCase (GH-32086) Message-ID: https://github.com/python/cpython/commit/ff619c7dfe8dcb0e4c8dc655abc3acc7dc586d0d commit: ff619c7dfe8dcb0e4c8dc655abc3acc7dc586d0d branch: main author: Andrew Svetlov committer: asvetlov date: 2022-03-23T23:17:07+02:00 summary: bpo-47104: Rewrite asyncio.to_thread tests to use IsolatedAsyncioTestCase (GH-32086) files: A Misc/NEWS.d/next/Tests/2022-03-23-22-45-51.bpo-47104._esUq8.rst M Lib/test/test_asyncio/test_threads.py diff --git a/Lib/test/test_asyncio/test_threads.py b/Lib/test/test_asyncio/test_threads.py index 2af322421dacf..1138a93e0f78e 100644 --- a/Lib/test/test_asyncio/test_threads.py +++ b/Lib/test/test_asyncio/test_threads.py @@ -5,87 +5,58 @@ from contextvars import ContextVar from unittest import mock -from test.test_asyncio import utils as test_utils def tearDownModule(): asyncio.set_event_loop_policy(None) -class ToThreadTests(test_utils.TestCase): - def setUp(self): - super().setUp() - self.loop = asyncio.new_event_loop() - asyncio.set_event_loop(self.loop) - - def tearDown(self): - self.loop.run_until_complete( - self.loop.shutdown_default_executor()) - self.loop.close() - asyncio.set_event_loop(None) - self.loop = None - super().tearDown() - - def test_to_thread(self): - async def main(): - return await asyncio.to_thread(sum, [40, 2]) - - result = self.loop.run_until_complete(main()) +class ToThreadTests(unittest.IsolatedAsyncioTestCase): + async def test_to_thread(self): + result = await asyncio.to_thread(sum, [40, 2]) self.assertEqual(result, 42) - def test_to_thread_exception(self): + async def test_to_thread_exception(self): def raise_runtime(): raise RuntimeError("test") - async def main(): - await asyncio.to_thread(raise_runtime) - with self.assertRaisesRegex(RuntimeError, "test"): - self.loop.run_until_complete(main()) + await asyncio.to_thread(raise_runtime) - def test_to_thread_once(self): + async def test_to_thread_once(self): func = mock.Mock() - async def main(): - await asyncio.to_thread(func) - - self.loop.run_until_complete(main()) + await asyncio.to_thread(func) func.assert_called_once() - def test_to_thread_concurrent(self): + async def test_to_thread_concurrent(self): func = mock.Mock() - async def main(): - futs = [] - for _ in range(10): - fut = asyncio.to_thread(func) - futs.append(fut) - await asyncio.gather(*futs) + futs = [] + for _ in range(10): + fut = asyncio.to_thread(func) + futs.append(fut) + await asyncio.gather(*futs) - self.loop.run_until_complete(main()) self.assertEqual(func.call_count, 10) - def test_to_thread_args_kwargs(self): + async def test_to_thread_args_kwargs(self): # Unlike run_in_executor(), to_thread() should directly accept kwargs. func = mock.Mock() - async def main(): - await asyncio.to_thread(func, 'test', something=True) + await asyncio.to_thread(func, 'test', something=True) - self.loop.run_until_complete(main()) func.assert_called_once_with('test', something=True) - def test_to_thread_contextvars(self): + async def test_to_thread_contextvars(self): test_ctx = ContextVar('test_ctx') def get_ctx(): return test_ctx.get() - async def main(): - test_ctx.set('parrot') - return await asyncio.to_thread(get_ctx) + test_ctx.set('parrot') + result = await asyncio.to_thread(get_ctx) - result = self.loop.run_until_complete(main()) self.assertEqual(result, 'parrot') diff --git a/Misc/NEWS.d/next/Tests/2022-03-23-22-45-51.bpo-47104._esUq8.rst b/Misc/NEWS.d/next/Tests/2022-03-23-22-45-51.bpo-47104._esUq8.rst new file mode 100644 index 0000000000000..1369bc227f5f2 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2022-03-23-22-45-51.bpo-47104._esUq8.rst @@ -0,0 +1,2 @@ +Rewrite :func:`asyncio.to_thread` tests to use +:class:`unittest.IsolatedAsyncioTestCase`. From webhook-mailer at python.org Wed Mar 23 17:43:58 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 23 Mar 2022 21:43:58 -0000 Subject: [Python-checkins] bpo-47104: Rewrite asyncio.to_thread tests to use IsolatedAsyncioTestCase (GH-32086) Message-ID: https://github.com/python/cpython/commit/9e1bfd8ce79b947dc0c1cfb4644e5afe337c2d07 commit: 9e1bfd8ce79b947dc0c1cfb4644e5afe337c2d07 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-23T14:43:32-07:00 summary: bpo-47104: Rewrite asyncio.to_thread tests to use IsolatedAsyncioTestCase (GH-32086) (cherry picked from commit ff619c7dfe8dcb0e4c8dc655abc3acc7dc586d0d) Co-authored-by: Andrew Svetlov files: A Misc/NEWS.d/next/Tests/2022-03-23-22-45-51.bpo-47104._esUq8.rst M Lib/test/test_asyncio/test_threads.py diff --git a/Lib/test/test_asyncio/test_threads.py b/Lib/test/test_asyncio/test_threads.py index 2af322421dacf..1138a93e0f78e 100644 --- a/Lib/test/test_asyncio/test_threads.py +++ b/Lib/test/test_asyncio/test_threads.py @@ -5,87 +5,58 @@ from contextvars import ContextVar from unittest import mock -from test.test_asyncio import utils as test_utils def tearDownModule(): asyncio.set_event_loop_policy(None) -class ToThreadTests(test_utils.TestCase): - def setUp(self): - super().setUp() - self.loop = asyncio.new_event_loop() - asyncio.set_event_loop(self.loop) - - def tearDown(self): - self.loop.run_until_complete( - self.loop.shutdown_default_executor()) - self.loop.close() - asyncio.set_event_loop(None) - self.loop = None - super().tearDown() - - def test_to_thread(self): - async def main(): - return await asyncio.to_thread(sum, [40, 2]) - - result = self.loop.run_until_complete(main()) +class ToThreadTests(unittest.IsolatedAsyncioTestCase): + async def test_to_thread(self): + result = await asyncio.to_thread(sum, [40, 2]) self.assertEqual(result, 42) - def test_to_thread_exception(self): + async def test_to_thread_exception(self): def raise_runtime(): raise RuntimeError("test") - async def main(): - await asyncio.to_thread(raise_runtime) - with self.assertRaisesRegex(RuntimeError, "test"): - self.loop.run_until_complete(main()) + await asyncio.to_thread(raise_runtime) - def test_to_thread_once(self): + async def test_to_thread_once(self): func = mock.Mock() - async def main(): - await asyncio.to_thread(func) - - self.loop.run_until_complete(main()) + await asyncio.to_thread(func) func.assert_called_once() - def test_to_thread_concurrent(self): + async def test_to_thread_concurrent(self): func = mock.Mock() - async def main(): - futs = [] - for _ in range(10): - fut = asyncio.to_thread(func) - futs.append(fut) - await asyncio.gather(*futs) + futs = [] + for _ in range(10): + fut = asyncio.to_thread(func) + futs.append(fut) + await asyncio.gather(*futs) - self.loop.run_until_complete(main()) self.assertEqual(func.call_count, 10) - def test_to_thread_args_kwargs(self): + async def test_to_thread_args_kwargs(self): # Unlike run_in_executor(), to_thread() should directly accept kwargs. func = mock.Mock() - async def main(): - await asyncio.to_thread(func, 'test', something=True) + await asyncio.to_thread(func, 'test', something=True) - self.loop.run_until_complete(main()) func.assert_called_once_with('test', something=True) - def test_to_thread_contextvars(self): + async def test_to_thread_contextvars(self): test_ctx = ContextVar('test_ctx') def get_ctx(): return test_ctx.get() - async def main(): - test_ctx.set('parrot') - return await asyncio.to_thread(get_ctx) + test_ctx.set('parrot') + result = await asyncio.to_thread(get_ctx) - result = self.loop.run_until_complete(main()) self.assertEqual(result, 'parrot') diff --git a/Misc/NEWS.d/next/Tests/2022-03-23-22-45-51.bpo-47104._esUq8.rst b/Misc/NEWS.d/next/Tests/2022-03-23-22-45-51.bpo-47104._esUq8.rst new file mode 100644 index 0000000000000..1369bc227f5f2 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2022-03-23-22-45-51.bpo-47104._esUq8.rst @@ -0,0 +1,2 @@ +Rewrite :func:`asyncio.to_thread` tests to use +:class:`unittest.IsolatedAsyncioTestCase`. From webhook-mailer at python.org Wed Mar 23 19:36:34 2022 From: webhook-mailer at python.org (zooba) Date: Wed, 23 Mar 2022 23:36:34 -0000 Subject: [Python-checkins] Fix GPG signing in Windows release build (GH-32089) Message-ID: https://github.com/python/cpython/commit/366c54633e7d6a4ce94c3f0f80c2abf82a869e15 commit: 366c54633e7d6a4ce94c3f0f80c2abf82a869e15 branch: main author: Steve Dower committer: zooba date: 2022-03-23T23:36:26Z summary: Fix GPG signing in Windows release build (GH-32089) files: D .azure-pipelines/windows-release/gpg-sign.yml M .azure-pipelines/windows-release/stage-publish-pythonorg.yml diff --git a/.azure-pipelines/windows-release/gpg-sign.yml b/.azure-pipelines/windows-release/gpg-sign.yml deleted file mode 100644 index 04206d23e4996..0000000000000 --- a/.azure-pipelines/windows-release/gpg-sign.yml +++ /dev/null @@ -1,31 +0,0 @@ -parameters: - GPGKeyFile: $(GPGKey) - GPGPassphrase: $(GPGPassphrase) - Files: '*' - WorkingDirectory: $(Build.BinariesDirectory) - Condition: succeeded() - -steps: -- task: DownloadSecureFile at 1 - name: gpgkey - inputs: - secureFile: ${{ parameters.GPGKeyFile }} - condition: ${{ parameters.Condition }} - displayName: 'Download GPG key' - -- powershell: | - git clone https://github.com/python/cpython-bin-deps --branch gpg --single-branch --depth 1 --progress -v "gpg" - gpg/gpg2.exe --import "$(gpgkey.secureFilePath)" - (gci -File ${{ parameters.Files }}).FullName | %{ - gpg/gpg2.exe -ba --batch --passphrase ${{ parameters.GPGPassphrase }} $_ - "Made signature for $_" - } - condition: ${{ parameters.Condition }} - displayName: 'Generate GPG signatures' - workingDirectory: ${{ parameters.WorkingDirectory }} - -- powershell: | - $p = gps "gpg-agent" -EA 0 - if ($p) { $p.Kill() } - displayName: 'Kill GPG agent' - condition: true diff --git a/.azure-pipelines/windows-release/stage-publish-pythonorg.yml b/.azure-pipelines/windows-release/stage-publish-pythonorg.yml index ee50e4e8aa0db..e8f12b64e5589 100644 --- a/.azure-pipelines/windows-release/stage-publish-pythonorg.yml +++ b/.azure-pipelines/windows-release/stage-publish-pythonorg.yml @@ -84,16 +84,32 @@ jobs: condition: and(succeeded(), ne(variables['PublishARM64'], 'true')) - - template: ./gpg-sign.yml - parameters: - GPGKeyFile: 'python-signing.key' - Files: 'msi\*\*, embed\*.zip' - - - template: ./gpg-sign.yml - parameters: - GPGKeyFile: 'python-signing.key' - Files: 'doc\htmlhelp\*.chm' - Condition: and(succeeded(), eq(variables['DoCHM'], 'true')) + - task: DownloadSecureFile at 1 + name: gpgkey + inputs: + secureFile: 'python-signing.key' + displayName: 'Download GPG key' + + - powershell: | + git clone https://github.com/python/cpython-bin-deps --branch gpg --single-branch --depth 1 --progress -v "gpg" + gpg/gpg2.exe --import "$(gpgkey.secureFilePath)" + $files = gci -File "msi\*\*", "embed\*.zip" + if ("$(DoCHM)" -ieq "true") { + $files = $files + (gci -File "doc\htmlhelp\*.chm") + } + $files.FullName | %{ + gpg/gpg2.exe -ba --batch --passphrase $(GPGPassphrase) $_ + "Made signature for $_" + } + displayName: 'Generate GPG signatures' + workingDirectory: $(Build.BinariesDirectory) + + - powershell: | + $p = gps "gpg-agent" -EA 0 + if ($p) { $p.Kill() } + displayName: 'Kill GPG agent' + condition: true + - powershell: > $(Build.SourcesDirectory)\Tools\msi\uploadrelease.ps1 From webhook-mailer at python.org Wed Mar 23 20:27:10 2022 From: webhook-mailer at python.org (ambv) Date: Thu, 24 Mar 2022 00:27:10 -0000 Subject: [Python-checkins] Python 3.9.12 Message-ID: https://github.com/python/cpython/commit/b28265d7e6a41a4a0e227b37f4fbbc4d03a0a707 commit: b28265d7e6a41a4a0e227b37f4fbbc4d03a0a707 branch: 3.9 author: ?ukasz Langa committer: ambv date: 2022-03-23T22:12:08+01:00 summary: Python 3.9.12 files: A Misc/NEWS.d/3.9.12.rst D Misc/NEWS.d/next/Core and Builtins/2022-03-17-14-22-23.bpo-46968.4gz4NA.rst D Misc/NEWS.d/next/Library/2019-05-07-14-25-45.bpo-14156.0FaHXE.rst D Misc/NEWS.d/next/Library/2021-12-25-14-13-14.bpo-40296.p0YVGB.rst D Misc/NEWS.d/next/Library/2022-01-18-01-29-38.bpo-46421.9LdmNr.rst D Misc/NEWS.d/next/Library/2022-03-15-09-29-52.bpo-47022.uaEDcI.rst D Misc/NEWS.d/next/Library/2022-03-15-18-32-12.bpo-45997.4n2aVU.rst D Misc/NEWS.d/next/Library/2022-03-16-18-25-19.bpo-2604.jeopdL.rst D Misc/NEWS.d/next/Library/2022-03-18-13-30-40.bpo-47061.etLHK5.rst D Misc/NEWS.d/next/Library/2022-03-19-13-38-29.bpo-39394.7j6WL6.rst D Misc/NEWS.d/next/Library/2022-03-19-15-54-41.bpo-38256.FoMbjE.rst D Misc/NEWS.d/next/Library/2022-03-19-19-56-04.bpo-42369.Ok828t.rst D Misc/NEWS.d/next/Library/2022-03-20-22-13-24.bpo-23691.Nc2TrW.rst D Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst M Include/patchlevel.h M Lib/pydoc_data/topics.py M README.rst diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 10792996992af..a4418b0a6c691 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -18,12 +18,12 @@ /*--start constants--*/ #define PY_MAJOR_VERSION 3 #define PY_MINOR_VERSION 9 -#define PY_MICRO_VERSION 11 +#define PY_MICRO_VERSION 12 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL #define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "3.9.11+" +#define PY_VERSION "3.9.12" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index 0e63c31f1b4fe..2546eb933bcbd 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Tue Mar 15 21:44:32 2022 +# Autogenerated by Sphinx on Wed Mar 23 22:08:02 2022 topics = {'assert': 'The "assert" statement\n' '**********************\n' '\n' @@ -2416,11 +2416,11 @@ 'resulting\n' 'object is ?compatible? with the exception. An object is ' 'compatible\n' - 'with an exception if it is the class or a base class of the ' - 'exception\n' - 'object, or a tuple containing an item that is the class or a ' + 'with an exception if the object is the class or a *non-virtual ' 'base\n' - 'class of the exception object.\n' + 'class* of the exception object, or a tuple containing an item ' + 'that is\n' + 'the class or a non-virtual base class of the exception object.\n' '\n' 'If no except clause matches the exception, the search for an ' 'exception\n' @@ -3567,15 +3567,17 @@ 'on members\n' ' of hashed collections including "set", "frozenset", and ' '"dict".\n' - ' "__hash__()" should return an integer. The only required ' - 'property\n' - ' is that objects which compare equal have the same hash ' - 'value; it is\n' - ' advised to mix together the hash values of the ' - 'components of the\n' - ' object that also play a part in comparison of objects by ' - 'packing\n' - ' them into a tuple and hashing the tuple. Example:\n' + ' The "__hash__()" method should return an integer. The ' + 'only required\n' + ' property is that objects which compare equal have the ' + 'same hash\n' + ' value; it is advised to mix together the hash values of ' + 'the\n' + ' components of the object that also play a part in ' + 'comparison of\n' + ' objects by packing them into a tuple and hashing the ' + 'tuple.\n' + ' Example:\n' '\n' ' def __hash__(self):\n' ' return hash((self.name, self.nick, self.color))\n' @@ -4559,11 +4561,11 @@ 'clause is\n' 'selected depending on the class of the instance: it must ' 'reference the\n' - 'class of the instance or a base class thereof. The instance ' - 'can be\n' - 'received by the handler and can carry additional information ' - 'about the\n' - 'exceptional condition.\n' + 'class of the instance or a *non-virtual base class* thereof. ' + 'The\n' + 'instance can be received by the handler and can carry ' + 'additional\n' + 'information about the exceptional condition.\n' '\n' 'Note:\n' '\n' @@ -4886,11 +4888,11 @@ 'clause is\n' 'selected depending on the class of the instance: it must ' 'reference the\n' - 'class of the instance or a base class thereof. The instance ' - 'can be\n' - 'received by the handler and can carry additional information ' - 'about the\n' - 'exceptional condition.\n' + 'class of the instance or a *non-virtual base class* thereof. ' + 'The\n' + 'instance can be received by the handler and can carry ' + 'additional\n' + 'information about the exceptional condition.\n' '\n' 'Note:\n' '\n' @@ -8440,15 +8442,17 @@ 'on members\n' ' of hashed collections including "set", "frozenset", and ' '"dict".\n' - ' "__hash__()" should return an integer. The only required ' - 'property\n' - ' is that objects which compare equal have the same hash ' - 'value; it is\n' - ' advised to mix together the hash values of the components ' - 'of the\n' - ' object that also play a part in comparison of objects by ' - 'packing\n' - ' them into a tuple and hashing the tuple. Example:\n' + ' The "__hash__()" method should return an integer. The ' + 'only required\n' + ' property is that objects which compare equal have the ' + 'same hash\n' + ' value; it is advised to mix together the hash values of ' + 'the\n' + ' components of the object that also play a part in ' + 'comparison of\n' + ' objects by packing them into a tuple and hashing the ' + 'tuple.\n' + ' Example:\n' '\n' ' def __hash__(self):\n' ' return hash((self.name, self.nick, self.color))\n' @@ -11531,10 +11535,10 @@ 'exception. For an except clause with an expression, that expression\n' 'is evaluated, and the clause matches the exception if the resulting\n' 'object is ?compatible? with the exception. An object is compatible\n' - 'with an exception if it is the class or a base class of the ' - 'exception\n' - 'object, or a tuple containing an item that is the class or a base\n' - 'class of the exception object.\n' + 'with an exception if the object is the class or a *non-virtual base\n' + 'class* of the exception object, or a tuple containing an item that ' + 'is\n' + 'the class or a non-virtual base class of the exception object.\n' '\n' 'If no except clause matches the exception, the search for an ' 'exception\n' diff --git a/Misc/NEWS.d/3.9.12.rst b/Misc/NEWS.d/3.9.12.rst new file mode 100644 index 0000000000000..7a38f30e1348e --- /dev/null +++ b/Misc/NEWS.d/3.9.12.rst @@ -0,0 +1,137 @@ +.. bpo: 46968 +.. date: 2022-03-17-14-22-23 +.. nonce: 4gz4NA +.. release date: 2022-03-23 +.. section: Core and Builtins + +Check for the existence of the "sys/auxv.h" header in :mod:`faulthandler` to +avoid compilation problems in systems where this header doesn't exist. Patch +by Pablo Galindo + +.. + +.. bpo: 47101 +.. date: 2022-03-23-15-31-02 +.. nonce: rVSld- +.. section: Library + +:const:`hashlib.algorithms_available` now lists only algorithms that are +provided by activated crypto providers on OpenSSL 3.0. Legacy algorithms are +not listed unless the legacy provider has been loaded into the default OSSL +context. + +.. + +.. bpo: 23691 +.. date: 2022-03-20-22-13-24 +.. nonce: Nc2TrW +.. section: Library + +Protect the :func:`re.finditer` iterator from re-entering. + +.. + +.. bpo: 42369 +.. date: 2022-03-19-19-56-04 +.. nonce: Ok828t +.. section: Library + +Fix thread safety of :meth:`zipfile._SharedFile.tell` to avoid a +"zipfile.BadZipFile: Bad CRC-32 for file" exception when reading a +:class:`ZipFile` from multiple threads. + +.. + +.. bpo: 38256 +.. date: 2022-03-19-15-54-41 +.. nonce: FoMbjE +.. section: Library + +Fix :func:`binascii.crc32` when it is compiled to use zlib'c crc32 to work +properly on inputs 4+GiB in length instead of returning the wrong result. +The workaround prior to this was to always feed the function data in +increments smaller than 4GiB or to just call the zlib module function. + +.. + +.. bpo: 39394 +.. date: 2022-03-19-13-38-29 +.. nonce: 7j6WL6 +.. section: Library + +A warning about inline flags not at the start of the regular expression now +contains the position of the flag. + +.. + +.. bpo: 47061 +.. date: 2022-03-18-13-30-40 +.. nonce: etLHK5 +.. section: Library + +Deprecate the various modules listed by :pep:`594`: + +aifc, asynchat, asyncore, audioop, cgi, cgitb, chunk, crypt, imghdr, msilib, +nntplib, nis, ossaudiodev, pipes, smtpd, sndhdr, spwd, sunau, telnetlib, uu, +xdrlib + +.. + +.. bpo: 2604 +.. date: 2022-03-16-18-25-19 +.. nonce: jeopdL +.. section: Library + +Fix bug where doctests using globals would fail when run multiple times. + +.. + +.. bpo: 45997 +.. date: 2022-03-15-18-32-12 +.. nonce: 4n2aVU +.. section: Library + +Fix :class:`asyncio.Semaphore` re-aquiring FIFO order. + +.. + +.. bpo: 47022 +.. date: 2022-03-15-09-29-52 +.. nonce: uaEDcI +.. section: Library + +The :mod:`asynchat`, :mod:`asyncore` and :mod:`smtpd` modules have been +deprecated since at least Python 3.6. Their documentation has now been +updated to note they will removed in Python 3.12 (:pep:`594`). + +.. + +.. bpo: 46421 +.. date: 2022-01-18-01-29-38 +.. nonce: 9LdmNr +.. section: Library + +Fix a unittest issue where if the command was invoked as ``python -m +unittest`` and the filename(s) began with a dot (.), a ``ValueError`` is +returned. + +.. + +.. bpo: 40296 +.. date: 2021-12-25-14-13-14 +.. nonce: p0YVGB +.. section: Library + +Fix supporting generic aliases in :mod:`pydoc`. + +.. + +.. bpo: 14156 +.. date: 2019-05-07-14-25-45 +.. nonce: 0FaHXE +.. section: Library + +argparse.FileType now supports an argument of '-' in binary mode, returning +the .buffer attribute of sys.stdin/sys.stdout as appropriate. Modes +including 'x' and 'a' are treated equivalently to 'w' when argument is '-'. +Patch contributed by Josh Rosenberg diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-17-14-22-23.bpo-46968.4gz4NA.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-17-14-22-23.bpo-46968.4gz4NA.rst deleted file mode 100644 index bef1d0532b098..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-03-17-14-22-23.bpo-46968.4gz4NA.rst +++ /dev/null @@ -1,3 +0,0 @@ -Check for the existence of the "sys/auxv.h" header in :mod:`faulthandler` to -avoid compilation problems in systems where this header doesn't exist. Patch -by Pablo Galindo diff --git a/Misc/NEWS.d/next/Library/2019-05-07-14-25-45.bpo-14156.0FaHXE.rst b/Misc/NEWS.d/next/Library/2019-05-07-14-25-45.bpo-14156.0FaHXE.rst deleted file mode 100644 index 7bfc917a2a750..0000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-07-14-25-45.bpo-14156.0FaHXE.rst +++ /dev/null @@ -1,4 +0,0 @@ -argparse.FileType now supports an argument of '-' in binary mode, returning -the .buffer attribute of sys.stdin/sys.stdout as appropriate. Modes -including 'x' and 'a' are treated equivalently to 'w' when argument is '-'. -Patch contributed by Josh Rosenberg diff --git a/Misc/NEWS.d/next/Library/2021-12-25-14-13-14.bpo-40296.p0YVGB.rst b/Misc/NEWS.d/next/Library/2021-12-25-14-13-14.bpo-40296.p0YVGB.rst deleted file mode 100644 index ea469c916b9db..0000000000000 --- a/Misc/NEWS.d/next/Library/2021-12-25-14-13-14.bpo-40296.p0YVGB.rst +++ /dev/null @@ -1 +0,0 @@ -Fix supporting generic aliases in :mod:`pydoc`. diff --git a/Misc/NEWS.d/next/Library/2022-01-18-01-29-38.bpo-46421.9LdmNr.rst b/Misc/NEWS.d/next/Library/2022-01-18-01-29-38.bpo-46421.9LdmNr.rst deleted file mode 100644 index 03ff27fd7d1a7..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-18-01-29-38.bpo-46421.9LdmNr.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix a unittest issue where if the command was invoked as ``python -m -unittest`` and the filename(s) began with a dot (.), a ``ValueError`` is -returned. diff --git a/Misc/NEWS.d/next/Library/2022-03-15-09-29-52.bpo-47022.uaEDcI.rst b/Misc/NEWS.d/next/Library/2022-03-15-09-29-52.bpo-47022.uaEDcI.rst deleted file mode 100644 index c35da6fb47b05..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-15-09-29-52.bpo-47022.uaEDcI.rst +++ /dev/null @@ -1,3 +0,0 @@ -The :mod:`asynchat`, :mod:`asyncore` and :mod:`smtpd` modules have been -deprecated since at least Python 3.6. Their documentation has now been -updated to note they will removed in Python 3.12 (:pep:`594`). diff --git a/Misc/NEWS.d/next/Library/2022-03-15-18-32-12.bpo-45997.4n2aVU.rst b/Misc/NEWS.d/next/Library/2022-03-15-18-32-12.bpo-45997.4n2aVU.rst deleted file mode 100644 index 40d8504e5a946..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-15-18-32-12.bpo-45997.4n2aVU.rst +++ /dev/null @@ -1 +0,0 @@ -Fix :class:`asyncio.Semaphore` re-aquiring FIFO order. diff --git a/Misc/NEWS.d/next/Library/2022-03-16-18-25-19.bpo-2604.jeopdL.rst b/Misc/NEWS.d/next/Library/2022-03-16-18-25-19.bpo-2604.jeopdL.rst deleted file mode 100644 index c0fd000b2c660..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-16-18-25-19.bpo-2604.jeopdL.rst +++ /dev/null @@ -1 +0,0 @@ -Fix bug where doctests using globals would fail when run multiple times. diff --git a/Misc/NEWS.d/next/Library/2022-03-18-13-30-40.bpo-47061.etLHK5.rst b/Misc/NEWS.d/next/Library/2022-03-18-13-30-40.bpo-47061.etLHK5.rst deleted file mode 100644 index 5445089e53c39..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-18-13-30-40.bpo-47061.etLHK5.rst +++ /dev/null @@ -1,5 +0,0 @@ -Deprecate the various modules listed by :pep:`594`: - -aifc, asynchat, asyncore, audioop, cgi, cgitb, chunk, crypt, -imghdr, msilib, nntplib, nis, ossaudiodev, pipes, smtpd, -sndhdr, spwd, sunau, telnetlib, uu, xdrlib diff --git a/Misc/NEWS.d/next/Library/2022-03-19-13-38-29.bpo-39394.7j6WL6.rst b/Misc/NEWS.d/next/Library/2022-03-19-13-38-29.bpo-39394.7j6WL6.rst deleted file mode 100644 index 9285179c9fdca..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-19-13-38-29.bpo-39394.7j6WL6.rst +++ /dev/null @@ -1,2 +0,0 @@ -A warning about inline flags not at the start of the regular expression now -contains the position of the flag. diff --git a/Misc/NEWS.d/next/Library/2022-03-19-15-54-41.bpo-38256.FoMbjE.rst b/Misc/NEWS.d/next/Library/2022-03-19-15-54-41.bpo-38256.FoMbjE.rst deleted file mode 100644 index d9b57513b0631..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-19-15-54-41.bpo-38256.FoMbjE.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fix :func:`binascii.crc32` when it is compiled to use zlib'c crc32 to -work properly on inputs 4+GiB in length instead of returning the wrong -result. The workaround prior to this was to always feed the function -data in increments smaller than 4GiB or to just call the zlib module -function. diff --git a/Misc/NEWS.d/next/Library/2022-03-19-19-56-04.bpo-42369.Ok828t.rst b/Misc/NEWS.d/next/Library/2022-03-19-19-56-04.bpo-42369.Ok828t.rst deleted file mode 100644 index 86dc3a0b81b9c..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-19-19-56-04.bpo-42369.Ok828t.rst +++ /dev/null @@ -1 +0,0 @@ -Fix thread safety of :meth:`zipfile._SharedFile.tell` to avoid a "zipfile.BadZipFile: Bad CRC-32 for file" exception when reading a :class:`ZipFile` from multiple threads. diff --git a/Misc/NEWS.d/next/Library/2022-03-20-22-13-24.bpo-23691.Nc2TrW.rst b/Misc/NEWS.d/next/Library/2022-03-20-22-13-24.bpo-23691.Nc2TrW.rst deleted file mode 100644 index 053a2b2709ee8..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-20-22-13-24.bpo-23691.Nc2TrW.rst +++ /dev/null @@ -1 +0,0 @@ -Protect the :func:`re.finditer` iterator from re-entering. diff --git a/Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst b/Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst deleted file mode 100644 index 1a65024e69fbd..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-23-15-31-02.bpo-47101.rVSld-.rst +++ /dev/null @@ -1,4 +0,0 @@ -:const:`hashlib.algorithms_available` now lists only algorithms that are -provided by activated crypto providers on OpenSSL 3.0. Legacy algorithms are -not listed unless the legacy provider has been loaded into the default -OSSL context. diff --git a/README.rst b/README.rst index 8856328f9d0bf..d3b2521a875a0 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -This is Python version 3.9.11 +This is Python version 3.9.12 ============================= .. image:: https://travis-ci.org/python/cpython.svg?branch=3.9 From webhook-mailer at python.org Wed Mar 23 22:15:14 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Thu, 24 Mar 2022 02:15:14 -0000 Subject: [Python-checkins] bpo-46480: rephrase typing.assert_type docs (GH-32069) Message-ID: https://github.com/python/cpython/commit/3354245daf89ca2c760c2c3e5b69a571f25073ed commit: 3354245daf89ca2c760c2c3e5b69a571f25073ed branch: main author: Shantanu <12621235+hauntsaninja at users.noreply.github.com> committer: JelleZijlstra date: 2022-03-23T19:15:06-07:00 summary: bpo-46480: rephrase typing.assert_type docs (GH-32069) The goal here is to reduce potential confusion between `assert_type(val, type)` and `assert isinstance(val, typ)`. The former is meant to ask a type checker to confirm a fact, the latter is meant to tell a type checker a fact. The behaviour of the latter more closely resembles what I'd expect from the prior phrasing of "assert [something] to the type checker". files: M Doc/library/typing.rst M Lib/typing.py diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 57979cbb08e69..4d833dc497f17 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -2150,7 +2150,7 @@ Functions and decorators .. function:: assert_type(val, typ, /) - Assert (to the type checker) that *val* has an inferred type of *typ*. + Ask a static type checker to confirm that *val* has an inferred type of *typ*. When the type checker encounters a call to ``assert_type()``, it emits an error if the value is not of the specified type:: diff --git a/Lib/typing.py b/Lib/typing.py index f0e84900d7f80..64b348e0b9d5c 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -2085,7 +2085,7 @@ def cast(typ, val): def assert_type(val, typ, /): - """Assert (to the type checker) that the value is of the given type. + """Ask a static type checker to confirm that the value is of the given type. When the type checker encounters a call to assert_type(), it emits an error if the value is not of the specified type:: From webhook-mailer at python.org Thu Mar 24 06:32:06 2022 From: webhook-mailer at python.org (pablogsal) Date: Thu, 24 Mar 2022 10:32:06 -0000 Subject: [Python-checkins] Python 3.10.4 Message-ID: https://github.com/python/cpython/commit/9d38120e335357a3b294277fd5eff0a10e46e043 commit: 9d38120e335357a3b294277fd5eff0a10e46e043 branch: 3.10 author: Pablo Galindo committer: pablogsal date: 2022-03-23T20:12:04Z summary: Python 3.10.4 files: A Misc/NEWS.d/3.10.4.rst D Misc/NEWS.d/next/Core and Builtins/2022-03-17-14-22-23.bpo-46968.4gz4NA.rst D Misc/NEWS.d/next/Library/2021-12-25-14-13-14.bpo-40296.p0YVGB.rst D Misc/NEWS.d/next/Library/2022-01-18-01-29-38.bpo-46421.9LdmNr.rst D Misc/NEWS.d/next/Library/2022-03-15-09-29-52.bpo-47022.uaEDcI.rst D Misc/NEWS.d/next/Library/2022-03-15-18-32-12.bpo-45997.4n2aVU.rst D Misc/NEWS.d/next/Library/2022-03-16-18-25-19.bpo-2604.jeopdL.rst D Misc/NEWS.d/next/Library/2022-03-18-13-30-40.bpo-47061.etLHK5.rst D Misc/NEWS.d/next/Library/2022-03-19-13-38-29.bpo-39394.7j6WL6.rst D Misc/NEWS.d/next/Library/2022-03-19-15-54-41.bpo-38256.FoMbjE.rst D Misc/NEWS.d/next/Library/2022-03-19-19-56-04.bpo-42369.Ok828t.rst D Misc/NEWS.d/next/Library/2022-03-20-22-13-24.bpo-23691.Nc2TrW.rst M Include/patchlevel.h M Lib/pydoc_data/topics.py M README.rst diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 3b1a7c549ff40..482069c791a91 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -18,12 +18,12 @@ /*--start constants--*/ #define PY_MAJOR_VERSION 3 #define PY_MINOR_VERSION 10 -#define PY_MICRO_VERSION 3 +#define PY_MICRO_VERSION 4 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL #define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "3.10.3+" +#define PY_VERSION "3.10.4" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index ac7d16c346fe3..76db0426df331 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Wed Mar 16 11:26:55 2022 +# Autogenerated by Sphinx on Wed Mar 23 20:11:40 2022 topics = {'assert': 'The "assert" statement\n' '**********************\n' '\n' @@ -2418,11 +2418,11 @@ 'resulting\n' 'object is ?compatible? with the exception. An object is ' 'compatible\n' - 'with an exception if it is the class or a base class of the ' - 'exception\n' - 'object, or a tuple containing an item that is the class or a ' + 'with an exception if the object is the class or a *non-virtual ' 'base\n' - 'class of the exception object.\n' + 'class* of the exception object, or a tuple containing an item ' + 'that is\n' + 'the class or a non-virtual base class of the exception object.\n' '\n' 'If no except clause matches the exception, the search for an ' 'exception\n' @@ -4399,15 +4399,17 @@ 'on members\n' ' of hashed collections including "set", "frozenset", and ' '"dict".\n' - ' "__hash__()" should return an integer. The only required ' - 'property\n' - ' is that objects which compare equal have the same hash ' - 'value; it is\n' - ' advised to mix together the hash values of the ' - 'components of the\n' - ' object that also play a part in comparison of objects by ' - 'packing\n' - ' them into a tuple and hashing the tuple. Example:\n' + ' The "__hash__()" method should return an integer. The ' + 'only required\n' + ' property is that objects which compare equal have the ' + 'same hash\n' + ' value; it is advised to mix together the hash values of ' + 'the\n' + ' components of the object that also play a part in ' + 'comparison of\n' + ' objects by packing them into a tuple and hashing the ' + 'tuple.\n' + ' Example:\n' '\n' ' def __hash__(self):\n' ' return hash((self.name, self.nick, self.color))\n' @@ -5391,11 +5393,11 @@ 'clause is\n' 'selected depending on the class of the instance: it must ' 'reference the\n' - 'class of the instance or a base class thereof. The instance ' - 'can be\n' - 'received by the handler and can carry additional information ' - 'about the\n' - 'exceptional condition.\n' + 'class of the instance or a *non-virtual base class* thereof. ' + 'The\n' + 'instance can be received by the handler and can carry ' + 'additional\n' + 'information about the exceptional condition.\n' '\n' 'Note:\n' '\n' @@ -5730,11 +5732,11 @@ 'clause is\n' 'selected depending on the class of the instance: it must ' 'reference the\n' - 'class of the instance or a base class thereof. The instance ' - 'can be\n' - 'received by the handler and can carry additional information ' - 'about the\n' - 'exceptional condition.\n' + 'class of the instance or a *non-virtual base class* thereof. ' + 'The\n' + 'instance can be received by the handler and can carry ' + 'additional\n' + 'information about the exceptional condition.\n' '\n' 'Note:\n' '\n' @@ -9303,15 +9305,17 @@ 'on members\n' ' of hashed collections including "set", "frozenset", and ' '"dict".\n' - ' "__hash__()" should return an integer. The only required ' - 'property\n' - ' is that objects which compare equal have the same hash ' - 'value; it is\n' - ' advised to mix together the hash values of the components ' - 'of the\n' - ' object that also play a part in comparison of objects by ' - 'packing\n' - ' them into a tuple and hashing the tuple. Example:\n' + ' The "__hash__()" method should return an integer. The ' + 'only required\n' + ' property is that objects which compare equal have the ' + 'same hash\n' + ' value; it is advised to mix together the hash values of ' + 'the\n' + ' components of the object that also play a part in ' + 'comparison of\n' + ' objects by packing them into a tuple and hashing the ' + 'tuple.\n' + ' Example:\n' '\n' ' def __hash__(self):\n' ' return hash((self.name, self.nick, self.color))\n' @@ -12428,10 +12432,10 @@ 'exception. For an except clause with an expression, that expression\n' 'is evaluated, and the clause matches the exception if the resulting\n' 'object is ?compatible? with the exception. An object is compatible\n' - 'with an exception if it is the class or a base class of the ' - 'exception\n' - 'object, or a tuple containing an item that is the class or a base\n' - 'class of the exception object.\n' + 'with an exception if the object is the class or a *non-virtual base\n' + 'class* of the exception object, or a tuple containing an item that ' + 'is\n' + 'the class or a non-virtual base class of the exception object.\n' '\n' 'If no except clause matches the exception, the search for an ' 'exception\n' diff --git a/Misc/NEWS.d/3.10.4.rst b/Misc/NEWS.d/3.10.4.rst new file mode 100644 index 0000000000000..ac6869a671f0e --- /dev/null +++ b/Misc/NEWS.d/3.10.4.rst @@ -0,0 +1,114 @@ +.. bpo: 46968 +.. date: 2022-03-17-14-22-23 +.. nonce: 4gz4NA +.. release date: 2022-03-23 +.. section: Core and Builtins + +Check for the existence of the "sys/auxv.h" header in :mod:`faulthandler` to +avoid compilation problems in systems where this header doesn't exist. Patch +by Pablo Galindo + +.. + +.. bpo: 23691 +.. date: 2022-03-20-22-13-24 +.. nonce: Nc2TrW +.. section: Library + +Protect the :func:`re.finditer` iterator from re-entering. + +.. + +.. bpo: 42369 +.. date: 2022-03-19-19-56-04 +.. nonce: Ok828t +.. section: Library + +Fix thread safety of :meth:`zipfile._SharedFile.tell` to avoid a +"zipfile.BadZipFile: Bad CRC-32 for file" exception when reading a +:class:`ZipFile` from multiple threads. + +.. + +.. bpo: 38256 +.. date: 2022-03-19-15-54-41 +.. nonce: FoMbjE +.. section: Library + +Fix :func:`binascii.crc32` when it is compiled to use zlib'c crc32 to work +properly on inputs 4+GiB in length instead of returning the wrong result. +The workaround prior to this was to always feed the function data in +increments smaller than 4GiB or to just call the zlib module function. + +.. + +.. bpo: 39394 +.. date: 2022-03-19-13-38-29 +.. nonce: 7j6WL6 +.. section: Library + +A warning about inline flags not at the start of the regular expression now +contains the position of the flag. + +.. + +.. bpo: 47061 +.. date: 2022-03-18-13-30-40 +.. nonce: etLHK5 +.. section: Library + +Deprecate the various modules listed by :pep:`594`: + +aifc, asynchat, asyncore, audioop, cgi, cgitb, chunk, crypt, imghdr, msilib, +nntplib, nis, ossaudiodev, pipes, smtpd, sndhdr, spwd, sunau, telnetlib, uu, +xdrlib + +.. + +.. bpo: 2604 +.. date: 2022-03-16-18-25-19 +.. nonce: jeopdL +.. section: Library + +Fix bug where doctests using globals would fail when run multiple times. + +.. + +.. bpo: 45997 +.. date: 2022-03-15-18-32-12 +.. nonce: 4n2aVU +.. section: Library + +Fix :class:`asyncio.Semaphore` re-aquiring FIFO order. + +.. + +.. bpo: 47022 +.. date: 2022-03-15-09-29-52 +.. nonce: uaEDcI +.. section: Library + +The :mod:`asynchat`, :mod:`asyncore` and :mod:`smtpd` modules have been +deprecated since at least Python 3.6. Their documentation and deprecation +warnings and have now been updated to note they will removed in Python 3.12 +(:pep:`594`). + +.. + +.. bpo: 46421 +.. date: 2022-01-18-01-29-38 +.. nonce: 9LdmNr +.. section: Library + +Fix a unittest issue where if the command was invoked as ``python -m +unittest`` and the filename(s) began with a dot (.), a ``ValueError`` is +returned. + +.. + +.. bpo: 40296 +.. date: 2021-12-25-14-13-14 +.. nonce: p0YVGB +.. section: Library + +Fix supporting generic aliases in :mod:`pydoc`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-17-14-22-23.bpo-46968.4gz4NA.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-17-14-22-23.bpo-46968.4gz4NA.rst deleted file mode 100644 index bef1d0532b098..0000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2022-03-17-14-22-23.bpo-46968.4gz4NA.rst +++ /dev/null @@ -1,3 +0,0 @@ -Check for the existence of the "sys/auxv.h" header in :mod:`faulthandler` to -avoid compilation problems in systems where this header doesn't exist. Patch -by Pablo Galindo diff --git a/Misc/NEWS.d/next/Library/2021-12-25-14-13-14.bpo-40296.p0YVGB.rst b/Misc/NEWS.d/next/Library/2021-12-25-14-13-14.bpo-40296.p0YVGB.rst deleted file mode 100644 index ea469c916b9db..0000000000000 --- a/Misc/NEWS.d/next/Library/2021-12-25-14-13-14.bpo-40296.p0YVGB.rst +++ /dev/null @@ -1 +0,0 @@ -Fix supporting generic aliases in :mod:`pydoc`. diff --git a/Misc/NEWS.d/next/Library/2022-01-18-01-29-38.bpo-46421.9LdmNr.rst b/Misc/NEWS.d/next/Library/2022-01-18-01-29-38.bpo-46421.9LdmNr.rst deleted file mode 100644 index 03ff27fd7d1a7..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-01-18-01-29-38.bpo-46421.9LdmNr.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix a unittest issue where if the command was invoked as ``python -m -unittest`` and the filename(s) began with a dot (.), a ``ValueError`` is -returned. diff --git a/Misc/NEWS.d/next/Library/2022-03-15-09-29-52.bpo-47022.uaEDcI.rst b/Misc/NEWS.d/next/Library/2022-03-15-09-29-52.bpo-47022.uaEDcI.rst deleted file mode 100644 index 0e867b9506484..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-15-09-29-52.bpo-47022.uaEDcI.rst +++ /dev/null @@ -1,4 +0,0 @@ -The :mod:`asynchat`, :mod:`asyncore` and :mod:`smtpd` modules have been -deprecated since at least Python 3.6. Their documentation and deprecation -warnings and have now been updated to note they will removed in Python 3.12 -(:pep:`594`). diff --git a/Misc/NEWS.d/next/Library/2022-03-15-18-32-12.bpo-45997.4n2aVU.rst b/Misc/NEWS.d/next/Library/2022-03-15-18-32-12.bpo-45997.4n2aVU.rst deleted file mode 100644 index 40d8504e5a946..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-15-18-32-12.bpo-45997.4n2aVU.rst +++ /dev/null @@ -1 +0,0 @@ -Fix :class:`asyncio.Semaphore` re-aquiring FIFO order. diff --git a/Misc/NEWS.d/next/Library/2022-03-16-18-25-19.bpo-2604.jeopdL.rst b/Misc/NEWS.d/next/Library/2022-03-16-18-25-19.bpo-2604.jeopdL.rst deleted file mode 100644 index c0fd000b2c660..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-16-18-25-19.bpo-2604.jeopdL.rst +++ /dev/null @@ -1 +0,0 @@ -Fix bug where doctests using globals would fail when run multiple times. diff --git a/Misc/NEWS.d/next/Library/2022-03-18-13-30-40.bpo-47061.etLHK5.rst b/Misc/NEWS.d/next/Library/2022-03-18-13-30-40.bpo-47061.etLHK5.rst deleted file mode 100644 index 5445089e53c39..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-18-13-30-40.bpo-47061.etLHK5.rst +++ /dev/null @@ -1,5 +0,0 @@ -Deprecate the various modules listed by :pep:`594`: - -aifc, asynchat, asyncore, audioop, cgi, cgitb, chunk, crypt, -imghdr, msilib, nntplib, nis, ossaudiodev, pipes, smtpd, -sndhdr, spwd, sunau, telnetlib, uu, xdrlib diff --git a/Misc/NEWS.d/next/Library/2022-03-19-13-38-29.bpo-39394.7j6WL6.rst b/Misc/NEWS.d/next/Library/2022-03-19-13-38-29.bpo-39394.7j6WL6.rst deleted file mode 100644 index 9285179c9fdca..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-19-13-38-29.bpo-39394.7j6WL6.rst +++ /dev/null @@ -1,2 +0,0 @@ -A warning about inline flags not at the start of the regular expression now -contains the position of the flag. diff --git a/Misc/NEWS.d/next/Library/2022-03-19-15-54-41.bpo-38256.FoMbjE.rst b/Misc/NEWS.d/next/Library/2022-03-19-15-54-41.bpo-38256.FoMbjE.rst deleted file mode 100644 index d9b57513b0631..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-19-15-54-41.bpo-38256.FoMbjE.rst +++ /dev/null @@ -1,5 +0,0 @@ -Fix :func:`binascii.crc32` when it is compiled to use zlib'c crc32 to -work properly on inputs 4+GiB in length instead of returning the wrong -result. The workaround prior to this was to always feed the function -data in increments smaller than 4GiB or to just call the zlib module -function. diff --git a/Misc/NEWS.d/next/Library/2022-03-19-19-56-04.bpo-42369.Ok828t.rst b/Misc/NEWS.d/next/Library/2022-03-19-19-56-04.bpo-42369.Ok828t.rst deleted file mode 100644 index 86dc3a0b81b9c..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-19-19-56-04.bpo-42369.Ok828t.rst +++ /dev/null @@ -1 +0,0 @@ -Fix thread safety of :meth:`zipfile._SharedFile.tell` to avoid a "zipfile.BadZipFile: Bad CRC-32 for file" exception when reading a :class:`ZipFile` from multiple threads. diff --git a/Misc/NEWS.d/next/Library/2022-03-20-22-13-24.bpo-23691.Nc2TrW.rst b/Misc/NEWS.d/next/Library/2022-03-20-22-13-24.bpo-23691.Nc2TrW.rst deleted file mode 100644 index 053a2b2709ee8..0000000000000 --- a/Misc/NEWS.d/next/Library/2022-03-20-22-13-24.bpo-23691.Nc2TrW.rst +++ /dev/null @@ -1 +0,0 @@ -Protect the :func:`re.finditer` iterator from re-entering. diff --git a/README.rst b/README.rst index 9b708f10a2f71..215ff1e5b94ce 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -This is Python version 3.10.3 +This is Python version 3.10.4 ============================= .. image:: https://travis-ci.com/python/cpython.svg?branch=master From webhook-mailer at python.org Thu Mar 24 09:23:24 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Thu, 24 Mar 2022 13:23:24 -0000 Subject: [Python-checkins] bpo-40465: Document random module changes in 3.11 What's new (#31818) Message-ID: https://github.com/python/cpython/commit/12c0012cf97d21bc637056983ede0eaf4c0d9c33 commit: 12c0012cf97d21bc637056983ede0eaf4c0d9c33 branch: main author: Tom?? Hrn?iar committer: serhiy-storchaka date: 2022-03-24T15:22:58+02:00 summary: bpo-40465: Document random module changes in 3.11 What's new (#31818) files: M Doc/library/random.rst M Doc/whatsnew/3.11.rst diff --git a/Doc/library/random.rst b/Doc/library/random.rst index 96c6300ea16f5..72881b56a4b18 100644 --- a/Doc/library/random.rst +++ b/Doc/library/random.rst @@ -257,7 +257,7 @@ Functions for sequences .. versionchanged:: 3.11 The *population* must be a sequence. Automatic conversion of sets - to lists is longer supported. + to lists is no longer supported. .. _real-valued-distributions: diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index fe6c2e24c3d24..b2fdb4852360d 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -705,6 +705,11 @@ Changes in the Python API deprecated since Python 3.6. (Contributed by Serhiy Storchaka in :issue:`47066`.) +* The *population* parameter of :func:`random.sample` must be a sequence. + Automatic conversion of sets to lists is no longer supported. If the sample size + is larger than the population size, a :exc:`ValueError` is raised. + (Contributed by Raymond Hettinger in :issue:`40465`.) + Build Changes ============= From webhook-mailer at python.org Thu Mar 24 14:54:45 2022 From: webhook-mailer at python.org (iritkatriel) Date: Thu, 24 Mar 2022 18:54:45 -0000 Subject: [Python-checkins] bpo-46841: remove no-longer-used macro UPDATE_PREV_INSTR_OPARG (GH-32100) Message-ID: https://github.com/python/cpython/commit/2f49b97cc5426087b46515254b9a97a22ee8c807 commit: 2f49b97cc5426087b46515254b9a97a22ee8c807 branch: main author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-03-24T18:54:35Z summary: bpo-46841: remove no-longer-used macro UPDATE_PREV_INSTR_OPARG (GH-32100) files: M Python/ceval.c diff --git a/Python/ceval.c b/Python/ceval.c index 42925b5b63048..e1d961fee6a83 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1433,8 +1433,6 @@ eval_frame_handle_pending(PyThreadState *tstate) #define DEOPT_IF(cond, instname) if (cond) { goto instname ## _miss; } -#define UPDATE_PREV_INSTR_OPARG(instr, oparg) ((uint8_t*)(instr))[-1] = (oparg) - #define GLOBALS() frame->f_globals #define BUILTINS() frame->f_builtins From webhook-mailer at python.org Thu Mar 24 15:51:27 2022 From: webhook-mailer at python.org (asvetlov) Date: Thu, 24 Mar 2022 19:51:27 -0000 Subject: [Python-checkins] bpo-47062: Implement asyncio.Runner context manager (GH-31799) Message-ID: https://github.com/python/cpython/commit/4119d2d7c9e25acd4f16994fb92d656f8b7816d7 commit: 4119d2d7c9e25acd4f16994fb92d656f8b7816d7 branch: main author: Andrew Svetlov committer: asvetlov date: 2022-03-24T21:51:16+02:00 summary: bpo-47062: Implement asyncio.Runner context manager (GH-31799) Co-authored-by: Zachary Ware files: A Doc/library/asyncio-runner.rst A Misc/NEWS.d/next/Library/2022-03-18-22-46-18.bpo-47062.RNc99_.rst M Doc/library/asyncio-task.rst M Doc/library/asyncio.rst M Lib/asyncio/runners.py M Lib/test/test_asyncio/test_runners.py M Lib/unittest/async_case.py diff --git a/Doc/library/asyncio-runner.rst b/Doc/library/asyncio-runner.rst new file mode 100644 index 0000000000000..2f4de9edaa400 --- /dev/null +++ b/Doc/library/asyncio-runner.rst @@ -0,0 +1,121 @@ +.. currentmodule:: asyncio + + +======= +Runners +======= + +**Source code:** :source:`Lib/asyncio/runners.py` + + +This section outlines high-level asyncio primitives to run asyncio code. + +They are built on top of an :ref:`event loop ` with the aim +to simplify async code usage for common wide-spread scenarios. + +.. contents:: + :depth: 1 + :local: + + + +Running an asyncio Program +========================== + +.. function:: run(coro, *, debug=None) + + Execute the :term:`coroutine` *coro* and return the result. + + This function runs the passed coroutine, taking care of + managing the asyncio event loop, *finalizing asynchronous + generators*, and closing the threadpool. + + This function cannot be called when another asyncio event loop is + running in the same thread. + + If *debug* is ``True``, the event loop will be run in debug mode. ``False`` disables + debug mode explicitly. ``None`` is used to respect the global + :ref:`asyncio-debug-mode` settings. + + This function always creates a new event loop and closes it at + the end. It should be used as a main entry point for asyncio + programs, and should ideally only be called once. + + Example:: + + async def main(): + await asyncio.sleep(1) + print('hello') + + asyncio.run(main()) + + .. versionadded:: 3.7 + + .. versionchanged:: 3.9 + Updated to use :meth:`loop.shutdown_default_executor`. + + .. versionchanged:: 3.10 + + *debug* is ``None`` by default to respect the global debug mode settings. + + +Runner context manager +====================== + +.. class:: Runner(*, debug=None, factory=None) + + A context manager that simplifies *multiple* async function calls in the same + context. + + Sometimes several top-level async functions should be called in the same :ref:`event + loop ` and :class:`contextvars.Context`. + + If *debug* is ``True``, the event loop will be run in debug mode. ``False`` disables + debug mode explicitly. ``None`` is used to respect the global + :ref:`asyncio-debug-mode` settings. + + *factory* could be used for overriding the loop creation. + :func:`asyncio.new_event_loop` is used if ``None``. + + Basically, :func:`asyncio.run()` example can be rewritten with the runner usage:: + + async def main(): + await asyncio.sleep(1) + print('hello') + + with asyncio.Runner() as runner: + runner.run(main()) + + .. versionadded:: 3.11 + + .. method:: run(coro, *, context=None) + + Run a :term:`coroutine ` *coro* in the embedded loop. + + Return the coroutine's result or raise its exception. + + An optional keyword-only *context* argument allows specifying a + custom :class:`contextvars.Context` for the *coro* to run in. + The runner's default context is used if ``None``. + + This function cannot be called when another asyncio event loop is + running in the same thread. + + .. method:: close() + + Close the runner. + + Finalize asynchronous generators, shutdown default executor, close the event loop + and release embedded :class:`contextvars.Context`. + + .. method:: get_loop() + + Return the event loop associated with the runner instance. + + .. note:: + + :class:`Runner` uses the lazy initialization strategy, its constructor doesn't + initialize underlying low-level structures. + + Embedded *loop* and *context* are created at the :keyword:`with` body entering + or the first call of :meth:`run` or :meth:`get_loop`. diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index 21a4cb5820bd1..c104ac5b9a3b8 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -204,43 +204,6 @@ A good example of a low-level function that returns a Future object is :meth:`loop.run_in_executor`. -Running an asyncio Program -========================== - -.. function:: run(coro, *, debug=False) - - Execute the :term:`coroutine` *coro* and return the result. - - This function runs the passed coroutine, taking care of - managing the asyncio event loop, *finalizing asynchronous - generators*, and closing the threadpool. - - This function cannot be called when another asyncio event loop is - running in the same thread. - - If *debug* is ``True``, the event loop will be run in debug mode. - - This function always creates a new event loop and closes it at - the end. It should be used as a main entry point for asyncio - programs, and should ideally only be called once. - - Example:: - - async def main(): - await asyncio.sleep(1) - print('hello') - - asyncio.run(main()) - - .. versionadded:: 3.7 - - .. versionchanged:: 3.9 - Updated to use :meth:`loop.shutdown_default_executor`. - - .. note:: - The source code for ``asyncio.run()`` can be found in - :source:`Lib/asyncio/runners.py`. - Creating Tasks ============== diff --git a/Doc/library/asyncio.rst b/Doc/library/asyncio.rst index 94a853259d348..8b3a060ffad52 100644 --- a/Doc/library/asyncio.rst +++ b/Doc/library/asyncio.rst @@ -67,6 +67,7 @@ Additionally, there are **low-level** APIs for :caption: High-level APIs :maxdepth: 1 + asyncio-runner.rst asyncio-task.rst asyncio-stream.rst asyncio-sync.rst diff --git a/Lib/asyncio/runners.py b/Lib/asyncio/runners.py index 9a5e9a48479ef..975509c7d645d 100644 --- a/Lib/asyncio/runners.py +++ b/Lib/asyncio/runners.py @@ -1,10 +1,112 @@ -__all__ = 'run', +__all__ = ('Runner', 'run') +import contextvars +import enum from . import coroutines from . import events from . import tasks +class _State(enum.Enum): + CREATED = "created" + INITIALIZED = "initialized" + CLOSED = "closed" + + +class Runner: + """A context manager that controls event loop life cycle. + + The context manager always creates a new event loop, + allows to run async functions inside it, + and properly finalizes the loop at the context manager exit. + + If debug is True, the event loop will be run in debug mode. + If factory is passed, it is used for new event loop creation. + + asyncio.run(main(), debug=True) + + is a shortcut for + + with asyncio.Runner(debug=True) as runner: + runner.run(main()) + + The run() method can be called multiple times within the runner's context. + + This can be useful for interactive console (e.g. IPython), + unittest runners, console tools, -- everywhere when async code + is called from existing sync framework and where the preferred single + asyncio.run() call doesn't work. + + """ + + # Note: the class is final, it is not intended for inheritance. + + def __init__(self, *, debug=None, factory=None): + self._state = _State.CREATED + self._debug = debug + self._factory = factory + self._loop = None + self._context = None + + def __enter__(self): + self._lazy_init() + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.close() + + def close(self): + """Shutdown and close event loop.""" + if self._state is not _State.INITIALIZED: + return + try: + loop = self._loop + _cancel_all_tasks(loop) + loop.run_until_complete(loop.shutdown_asyncgens()) + loop.run_until_complete(loop.shutdown_default_executor()) + finally: + loop.close() + self._loop = None + self._state = _State.CLOSED + + def get_loop(self): + """Return embedded event loop.""" + self._lazy_init() + return self._loop + + def run(self, coro, *, context=None): + """Run a coroutine inside the embedded event loop.""" + if not coroutines.iscoroutine(coro): + raise ValueError("a coroutine was expected, got {!r}".format(coro)) + + if events._get_running_loop() is not None: + # fail fast with short traceback + raise RuntimeError( + "Runner.run() cannot be called from a running event loop") + + self._lazy_init() + + if context is None: + context = self._context + task = self._loop.create_task(coro, context=context) + return self._loop.run_until_complete(task) + + def _lazy_init(self): + if self._state is _State.CLOSED: + raise RuntimeError("Runner is closed") + if self._state is _State.INITIALIZED: + return + if self._factory is None: + self._loop = events.new_event_loop() + else: + self._loop = self._factory() + if self._debug is not None: + self._loop.set_debug(self._debug) + self._context = contextvars.copy_context() + self._state = _State.INITIALIZED + + + def run(main, *, debug=None): """Execute the coroutine and return the result. @@ -30,26 +132,12 @@ async def main(): asyncio.run(main()) """ if events._get_running_loop() is not None: + # fail fast with short traceback raise RuntimeError( "asyncio.run() cannot be called from a running event loop") - if not coroutines.iscoroutine(main): - raise ValueError("a coroutine was expected, got {!r}".format(main)) - - loop = events.new_event_loop() - try: - events.set_event_loop(loop) - if debug is not None: - loop.set_debug(debug) - return loop.run_until_complete(main) - finally: - try: - _cancel_all_tasks(loop) - loop.run_until_complete(loop.shutdown_asyncgens()) - loop.run_until_complete(loop.shutdown_default_executor()) - finally: - events.set_event_loop(None) - loop.close() + with Runner(debug=debug) as runner: + return runner.run(main) def _cancel_all_tasks(loop): diff --git a/Lib/test/test_asyncio/test_runners.py b/Lib/test/test_asyncio/test_runners.py index 112273662b20b..2919412ab81db 100644 --- a/Lib/test/test_asyncio/test_runners.py +++ b/Lib/test/test_asyncio/test_runners.py @@ -1,4 +1,7 @@ import asyncio +import contextvars +import gc +import re import unittest from unittest import mock @@ -186,5 +189,135 @@ async def main(): self.assertFalse(spinner.ag_running) +class RunnerTests(BaseTest): + + def test_non_debug(self): + with asyncio.Runner(debug=False) as runner: + self.assertFalse(runner.get_loop().get_debug()) + + def test_debug(self): + with asyncio.Runner(debug=True) as runner: + self.assertTrue(runner.get_loop().get_debug()) + + def test_custom_factory(self): + loop = mock.Mock() + with asyncio.Runner(factory=lambda: loop) as runner: + self.assertIs(runner.get_loop(), loop) + + def test_run(self): + async def f(): + await asyncio.sleep(0) + return 'done' + + with asyncio.Runner() as runner: + self.assertEqual('done', runner.run(f())) + loop = runner.get_loop() + + with self.assertRaisesRegex( + RuntimeError, + "Runner is closed" + ): + runner.get_loop() + + self.assertTrue(loop.is_closed()) + + def test_run_non_coro(self): + with asyncio.Runner() as runner: + with self.assertRaisesRegex( + ValueError, + "a coroutine was expected" + ): + runner.run(123) + + def test_run_future(self): + with asyncio.Runner() as runner: + with self.assertRaisesRegex( + ValueError, + "a coroutine was expected" + ): + fut = runner.get_loop().create_future() + runner.run(fut) + + def test_explicit_close(self): + runner = asyncio.Runner() + loop = runner.get_loop() + runner.close() + with self.assertRaisesRegex( + RuntimeError, + "Runner is closed" + ): + runner.get_loop() + + self.assertTrue(loop.is_closed()) + + def test_double_close(self): + runner = asyncio.Runner() + loop = runner.get_loop() + + runner.close() + self.assertTrue(loop.is_closed()) + + # the second call is no-op + runner.close() + self.assertTrue(loop.is_closed()) + + def test_second_with_block_raises(self): + ret = [] + + async def f(arg): + ret.append(arg) + + runner = asyncio.Runner() + with runner: + runner.run(f(1)) + + with self.assertRaisesRegex( + RuntimeError, + "Runner is closed" + ): + with runner: + runner.run(f(2)) + + self.assertEqual([1], ret) + + def test_run_keeps_context(self): + cvar = contextvars.ContextVar("cvar", default=-1) + + async def f(val): + old = cvar.get() + await asyncio.sleep(0) + cvar.set(val) + return old + + async def get_context(): + return contextvars.copy_context() + + with asyncio.Runner() as runner: + self.assertEqual(-1, runner.run(f(1))) + self.assertEqual(1, runner.run(f(2))) + + self.assertEqual({cvar: 2}, dict(runner.run(get_context()))) + + def test_recursine_run(self): + async def g(): + pass + + async def f(): + runner.run(g()) + + with asyncio.Runner() as runner: + with self.assertWarnsRegex( + RuntimeWarning, + "coroutine .+ was never awaited", + ): + with self.assertRaisesRegex( + RuntimeError, + re.escape( + "Runner.run() cannot be called from a running event loop" + ), + ): + runner.run(f()) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/unittest/async_case.py b/Lib/unittest/async_case.py index 25adc3deff63d..85b938fb293af 100644 --- a/Lib/unittest/async_case.py +++ b/Lib/unittest/async_case.py @@ -34,7 +34,7 @@ class IsolatedAsyncioTestCase(TestCase): def __init__(self, methodName='runTest'): super().__init__(methodName) - self._asyncioTestLoop = None + self._asyncioRunner = None self._asyncioTestContext = contextvars.copy_context() async def asyncSetUp(self): @@ -75,76 +75,44 @@ def _callCleanup(self, function, *args, **kwargs): self._callMaybeAsync(function, *args, **kwargs) def _callAsync(self, func, /, *args, **kwargs): - assert self._asyncioTestLoop is not None, 'asyncio test loop is not initialized' + assert self._asyncioRunner is not None, 'asyncio runner is not initialized' assert inspect.iscoroutinefunction(func), f'{func!r} is not an async function' - task = self._asyncioTestLoop.create_task( + return self._asyncioRunner.run( func(*args, **kwargs), - context=self._asyncioTestContext, + context=self._asyncioTestContext ) - return self._asyncioTestLoop.run_until_complete(task) def _callMaybeAsync(self, func, /, *args, **kwargs): - assert self._asyncioTestLoop is not None, 'asyncio test loop is not initialized' + assert self._asyncioRunner is not None, 'asyncio runner is not initialized' if inspect.iscoroutinefunction(func): - task = self._asyncioTestLoop.create_task( + return self._asyncioRunner.run( func(*args, **kwargs), context=self._asyncioTestContext, ) - return self._asyncioTestLoop.run_until_complete(task) else: return self._asyncioTestContext.run(func, *args, **kwargs) - def _setupAsyncioLoop(self): - assert self._asyncioTestLoop is None, 'asyncio test loop already initialized' - loop = asyncio.new_event_loop() - asyncio.set_event_loop(loop) - loop.set_debug(True) - self._asyncioTestLoop = loop + def _setupAsyncioRunner(self): + assert self._asyncioRunner is None, 'asyncio runner is already initialized' + runner = asyncio.Runner(debug=True) + self._asyncioRunner = runner - def _tearDownAsyncioLoop(self): - assert self._asyncioTestLoop is not None, 'asyncio test loop is not initialized' - loop = self._asyncioTestLoop - self._asyncioTestLoop = None - - try: - # cancel all tasks - to_cancel = asyncio.all_tasks(loop) - if not to_cancel: - return - - for task in to_cancel: - task.cancel() - - loop.run_until_complete( - asyncio.gather(*to_cancel, return_exceptions=True)) - - for task in to_cancel: - if task.cancelled(): - continue - if task.exception() is not None: - loop.call_exception_handler({ - 'message': 'unhandled exception during test shutdown', - 'exception': task.exception(), - 'task': task, - }) - # shutdown asyncgens - loop.run_until_complete(loop.shutdown_asyncgens()) - finally: - asyncio.set_event_loop(None) - loop.close() + def _tearDownAsyncioRunner(self): + runner = self._asyncioRunner + runner.close() def run(self, result=None): - self._setupAsyncioLoop() + self._setupAsyncioRunner() try: return super().run(result) finally: - self._tearDownAsyncioLoop() + self._tearDownAsyncioRunner() def debug(self): - self._setupAsyncioLoop() + self._setupAsyncioRunner() super().debug() - self._tearDownAsyncioLoop() + self._tearDownAsyncioRunner() def __del__(self): - if self._asyncioTestLoop is not None: - self._tearDownAsyncioLoop() + if self._asyncioRunner is not None: + self._tearDownAsyncioRunner() diff --git a/Misc/NEWS.d/next/Library/2022-03-18-22-46-18.bpo-47062.RNc99_.rst b/Misc/NEWS.d/next/Library/2022-03-18-22-46-18.bpo-47062.RNc99_.rst new file mode 100644 index 0000000000000..7d5bfc114a8d1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-18-22-46-18.bpo-47062.RNc99_.rst @@ -0,0 +1 @@ +Implement :class:`asyncio.Runner` context manager. From webhook-mailer at python.org Thu Mar 24 17:09:47 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 24 Mar 2022 21:09:47 -0000 Subject: [Python-checkins] bpo-40280: Add wasm32-emscripten and wasm32-wasi SOABI (GH-32095) Message-ID: https://github.com/python/cpython/commit/8a0a9e5b1928fab7d9819c8d6498ef5c0b9383af commit: 8a0a9e5b1928fab7d9819c8d6498ef5c0b9383af branch: main author: Christian Heimes committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-24T14:09:42-07:00 summary: bpo-40280: Add wasm32-emscripten and wasm32-wasi SOABI (GH-32095) Shared extension on Emscripten now have suffix ``.cpython-311-wasm32-emscripten.so`` (JS loader) and ``.cpython-311-wasm32-emscripten.wasm`` (WebAssembly code). files: A Misc/NEWS.d/next/Build/2022-03-24-12-12-35.bpo-40280.eAQWrM.rst M configure M configure.ac diff --git a/Misc/NEWS.d/next/Build/2022-03-24-12-12-35.bpo-40280.eAQWrM.rst b/Misc/NEWS.d/next/Build/2022-03-24-12-12-35.bpo-40280.eAQWrM.rst new file mode 100644 index 0000000000000..7c7dc6d24fae4 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2022-03-24-12-12-35.bpo-40280.eAQWrM.rst @@ -0,0 +1,2 @@ +Add SOABI ``wasm32-emscripten`` for Emscripten and ``wasm32-wasi`` for WASI +on 32bit WASM as well as ``wasm64`` counter parts. diff --git a/configure b/configure index 128e36a80062a..00f5c7ba4cc72 100755 --- a/configure +++ b/configure @@ -6084,6 +6084,22 @@ cat > conftest.c < conftest.c < https://github.com/python/cpython/commit/b68431fadb3150134ac6ccbf501cdfeaf4c75678 commit: b68431fadb3150134ac6ccbf501cdfeaf4c75678 branch: main author: Ezio Melotti committer: ezio-melotti date: 2022-03-25T00:45:50+01:00 summary: Add an issue template config for the migration (GH-32101) files: A .github/ISSUE_TEMPLATE/config.yml diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000000..6a222c618aa37 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: ? GitHub Issues Migration in progress ? + url: https://discuss.python.org/t/github-issues-migration-status-update/14573 + about: Check status updates on the migration From webhook-mailer at python.org Fri Mar 25 08:57:59 2022 From: webhook-mailer at python.org (markshannon) Date: Fri, 25 Mar 2022 12:57:59 -0000 Subject: [Python-checkins] bpo-42197: Don't create `f_locals` dictionary unless we actually need it. (GH-32055) Message-ID: https://github.com/python/cpython/commit/d7163bb35d1ed46bde9affcd4eb267dfd0b703dd commit: d7163bb35d1ed46bde9affcd4eb267dfd0b703dd branch: main author: Mark Shannon committer: markshannon date: 2022-03-25T12:57:50Z summary: bpo-42197: Don't create `f_locals` dictionary unless we actually need it. (GH-32055) * `PyFrame_FastToLocalsWithError` and `PyFrame_LocalsToFast` are no longer called during profile and tracing. (Contributed by Fabio Zadrozny) * Make accesses to a frame's `f_locals` safe from C code, not relying on calls to `PyFrame_FastToLocals` or `PyFrame_LocalsToFast`. * Document new `PyFrame_GetLocals` C-API function. files: A Misc/NEWS.d/next/Core and Builtins/2022-03-22-15-12-28.bpo-42197.SwrrFO.rst M Doc/c-api/frame.rst M Doc/whatsnew/3.11.rst M Include/cpython/frameobject.h M Include/internal/pycore_frame.h M Objects/frameobject.c M Python/sysmodule.c diff --git a/Doc/c-api/frame.rst b/Doc/c-api/frame.rst index 0e36e6e1fd706..0c11bc163b417 100644 --- a/Doc/c-api/frame.rst +++ b/Doc/c-api/frame.rst @@ -41,6 +41,17 @@ See also :ref:`Reflection `. .. versionadded:: 3.9 +.. c:function:: PyObject* PyFrame_GetLocals(PyFrameObject *frame) + + Get the *frame*'s ``f_locals`` attribute (:class:`dict`). + + Return a :term:`strong reference`. + + *frame* must not be ``NULL``. + + .. versionadded:: 3.11 + + .. c:function:: int PyFrame_GetLineNumber(PyFrameObject *frame) Return the line number that *frame* is currently executing. diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index b2fdb4852360d..8c120ec45fe3f 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -969,7 +969,7 @@ Porting to Python 3.11 Code using ``f_lasti`` with ``PyCode_Addr2Line()`` must use :c:func:`PyFrame_GetLineNumber` instead. * ``f_lineno``: use :c:func:`PyFrame_GetLineNumber` - * ``f_locals``: use ``PyObject_GetAttrString((PyObject*)frame, "f_locals")``. + * ``f_locals``: use :c:func:`PyFrame_GetLocals`. * ``f_stackdepth``: removed. * ``f_state``: no public API (renamed to ``f_frame.f_state``). * ``f_trace``: no public API. @@ -983,6 +983,12 @@ Porting to Python 3.11 computed lazily. The :c:func:`PyFrame_GetBack` function must be called instead. + Debuggers that accessed the ``f_locals`` directly *must* call + `:c:func:`PyFrame_GetLocals` instead. They no longer need to call + `:c:func:`PyFrame_FastToLocalsWithError` or :c:func:`PyFrame_LocalsToFast`, + in fact they should not call those functions. The necessary updating of the + frame is now managed by the virtual machine. + Code defining ``PyFrame_GetCode()`` on Python 3.8 and older:: #if PY_VERSION_HEX < 0x030900B1 diff --git a/Include/cpython/frameobject.h b/Include/cpython/frameobject.h index 9b697fb3cbaf5..d54d3652a0dbc 100644 --- a/Include/cpython/frameobject.h +++ b/Include/cpython/frameobject.h @@ -23,3 +23,4 @@ PyAPI_FUNC(int) PyFrame_FastToLocalsWithError(PyFrameObject *f); PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *); PyAPI_FUNC(PyFrameObject *) PyFrame_GetBack(PyFrameObject *frame); +PyAPI_FUNC(PyObject *) PyFrame_GetLocals(PyFrameObject *frame); diff --git a/Include/internal/pycore_frame.h b/Include/internal/pycore_frame.h index 14fba8cd1f941..211831a6e497f 100644 --- a/Include/internal/pycore_frame.h +++ b/Include/internal/pycore_frame.h @@ -15,6 +15,7 @@ struct _frame { int f_lineno; /* Current line number. Only valid if non-zero */ char f_trace_lines; /* Emit per-line trace events? */ char f_trace_opcodes; /* Emit per-opcode trace events? */ + char f_fast_as_locals; /* Have the fast locals of this frame been converted to a dict? */ /* The frame data, if this frame object owns the frame */ PyObject *_f_frame_data[1]; }; diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-22-15-12-28.bpo-42197.SwrrFO.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-22-15-12-28.bpo-42197.SwrrFO.rst new file mode 100644 index 0000000000000..d54002a80e44f --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-22-15-12-28.bpo-42197.SwrrFO.rst @@ -0,0 +1,2 @@ +:c:func:`PyFrame_FastToLocalsWithError` and :c:func:`PyFrame_LocalsToFast` are no longer +called during profiling nor tracing. C code can access the ``f_locals`` attribute of :c:type:`PyFrameObject` by calling :c:func:`PyFrame_GetLocals`. diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 5c6a8bcb9008d..13dfbf6b9db41 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -840,6 +840,7 @@ _PyFrame_New_NoTrack(PyCodeObject *code) f->f_trace = NULL; f->f_trace_lines = 1; f->f_trace_opcodes = 0; + f->f_fast_as_locals = 0; f->f_lineno = 0; return f; } @@ -1004,7 +1005,11 @@ PyFrame_FastToLocalsWithError(PyFrameObject *f) PyErr_BadInternalCall(); return -1; } - return _PyFrame_FastToLocalsWithError(f->f_frame); + int err = _PyFrame_FastToLocalsWithError(f->f_frame); + if (err == 0) { + f->f_fast_as_locals = 1; + } + return err; } void @@ -1028,8 +1033,9 @@ _PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear) PyObject *error_type, *error_value, *error_traceback; PyCodeObject *co; locals = frame->f_locals; - if (locals == NULL) + if (locals == NULL) { return; + } fast = _PyFrame_GetLocalsArray(frame); co = frame->f_code; @@ -1088,13 +1094,12 @@ _PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear) void PyFrame_LocalsToFast(PyFrameObject *f, int clear) { - if (f == NULL || _PyFrame_GetState(f) == FRAME_CLEARED) { - return; + if (f && f->f_fast_as_locals && _PyFrame_GetState(f) != FRAME_CLEARED) { + _PyFrame_LocalsToFast(f->f_frame, clear); + f->f_fast_as_locals = 0; } - _PyFrame_LocalsToFast(f->f_frame, clear); } - PyCodeObject * PyFrame_GetCode(PyFrameObject *frame) { @@ -1118,6 +1123,12 @@ PyFrame_GetBack(PyFrameObject *frame) return back; } +PyObject* +PyFrame_GetLocals(PyFrameObject *frame) +{ + return frame_getlocals(frame, NULL); +} + PyObject* _PyEval_BuiltinsFromGlobals(PyThreadState *tstate, PyObject *globals) { diff --git a/Python/sysmodule.c b/Python/sysmodule.c index c89f81f689f7e..6322af5f5ca81 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -924,15 +924,19 @@ static PyObject * call_trampoline(PyThreadState *tstate, PyObject* callback, PyFrameObject *frame, int what, PyObject *arg) { - if (PyFrame_FastToLocalsWithError(frame) < 0) { - return NULL; - } PyObject *stack[3]; stack[0] = (PyObject *)frame; stack[1] = whatstrings[what]; stack[2] = (arg != NULL) ? arg : Py_None; + /* Discard any previous modifications the frame's fast locals */ + if (frame->f_fast_as_locals) { + if (PyFrame_FastToLocalsWithError(frame) < 0) { + return NULL; + } + } + /* call the Python-level function */ PyObject *result = _PyObject_FastCallTstate(tstate, callback, stack, 3); From webhook-mailer at python.org Fri Mar 25 12:13:28 2022 From: webhook-mailer at python.org (markshannon) Date: Fri, 25 Mar 2022 16:13:28 -0000 Subject: [Python-checkins] bpo-47053: Reduce deoptimization in BINARY_OP_INPLACE_ADD_UNICODE (GH-31318) Message-ID: https://github.com/python/cpython/commit/cca43b7d64f47ea921d0f7a347ae1a839c5463c3 commit: cca43b7d64f47ea921d0f7a347ae1a839c5463c3 branch: main author: Dennis Sweeney <36520290+sweeneyde at users.noreply.github.com> committer: markshannon date: 2022-03-25T16:13:19Z summary: bpo-47053: Reduce deoptimization in BINARY_OP_INPLACE_ADD_UNICODE (GH-31318) * Don't deopt if refcounts are too big * Detect more at specialization time files: A Misc/NEWS.d/next/Core and Builtins/2022-03-17-22-47-29.bpo-47053.QAXk8Q.rst M Include/internal/pycore_code.h M Python/ceval.c M Python/specialize.c diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index 82dc9e4bdc62f..0f6613b6c1e3d 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -263,7 +263,7 @@ extern int _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, extern int _Py_Specialize_Precall(PyObject *callable, _Py_CODEUNIT *instr, int nargs, PyObject *kwnames, int oparg); extern void _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, - int oparg); + int oparg, PyObject **locals); extern void _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, int oparg); extern void _Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr, diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-17-22-47-29.bpo-47053.QAXk8Q.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-17-22-47-29.bpo-47053.QAXk8Q.rst new file mode 100644 index 0000000000000..097105b1c20f4 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-17-22-47-29.bpo-47053.QAXk8Q.rst @@ -0,0 +1 @@ +Reduce de-optimization in the specialized ``BINARY_OP_INPLACE_ADD_UNICODE`` opcode. diff --git a/Python/ceval.c b/Python/ceval.c index e1d961fee6a83..4824b192f4e48 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2002,10 +2002,10 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int PyObject *right = TOP(); DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); - DEOPT_IF(Py_REFCNT(left) != 2, BINARY_OP); _Py_CODEUNIT true_next = next_instr[INLINE_CACHE_ENTRIES_BINARY_OP]; int next_oparg = _Py_OPARG(true_next); - assert(_Py_OPCODE(true_next) == STORE_FAST); + assert(_Py_OPCODE(true_next) == STORE_FAST || + _Py_OPCODE(true_next) == STORE_FAST__LOAD_FAST); /* In the common case, there are 2 references to the value * stored in 'variable' when the v = v + ... is performed: one * on the value stack (in 'v') and one still stored in the @@ -2016,7 +2016,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int DEOPT_IF(var != left, BINARY_OP); STAT_INC(BINARY_OP, hit); GETLOCAL(next_oparg) = NULL; - Py_DECREF(left); + assert(Py_REFCNT(left) >= 2); + Py_DECREF(left); // XXX never need to dealloc STACK_SHRINK(1); PyUnicode_Append(&TOP(), right); Py_DECREF(right); @@ -5378,7 +5379,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int PyObject *lhs = SECOND(); PyObject *rhs = TOP(); next_instr--; - _Py_Specialize_BinaryOp(lhs, rhs, next_instr, oparg); + _Py_Specialize_BinaryOp(lhs, rhs, next_instr, oparg, &GETLOCAL(0)); DISPATCH(); } else { diff --git a/Python/specialize.c b/Python/specialize.c index ce091a2c5f078..720bc7f241586 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -1742,7 +1742,7 @@ binary_op_fail_kind(int oparg, PyObject *lhs, PyObject *rhs) void _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, - int oparg) + int oparg, PyObject **locals) { assert(_PyOpcode_Caches[BINARY_OP] == INLINE_CACHE_ENTRIES_BINARY_OP); _PyBinaryOpCache *cache = (_PyBinaryOpCache *)(instr + 1); @@ -1754,7 +1754,9 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, } if (PyUnicode_CheckExact(lhs)) { _Py_CODEUNIT next = instr[INLINE_CACHE_ENTRIES_BINARY_OP + 1]; - if (_Py_OPCODE(next) == STORE_FAST && Py_REFCNT(lhs) == 2) { + bool to_store = (_Py_OPCODE(next) == STORE_FAST || + _Py_OPCODE(next) == STORE_FAST__LOAD_FAST); + if (to_store && locals[_Py_OPARG(next)] == lhs) { _Py_SET_OPCODE(*instr, BINARY_OP_INPLACE_ADD_UNICODE); goto success; } From webhook-mailer at python.org Fri Mar 25 13:32:15 2022 From: webhook-mailer at python.org (Mariatta) Date: Fri, 25 Mar 2022 17:32:15 -0000 Subject: [Python-checkins] Fix some typos in whatsnew (GH-32098) Message-ID: https://github.com/python/cpython/commit/c07ca1aab6e1928e9eefe9dfec7e7e5ae982b420 commit: c07ca1aab6e1928e9eefe9dfec7e7e5ae982b420 branch: main author: Kurt McKee committer: Mariatta date: 2022-03-25T10:32:05-07:00 summary: Fix some typos in whatsnew (GH-32098) * Fix some typos and phrasing * Convert the `hash()` text to a link * Remove definite article files: M Doc/whatsnew/3.11.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 8c120ec45fe3f..2c09d3583ea15 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -193,9 +193,9 @@ Other CPython Implementation Changes support :class:`typing.SupportsComplex` and :class:`typing.SupportsBytes` protocols. (Contributed by Mark Dickinson and Dong-hee Na in :issue:`24234`.) -* ``siphash13`` is added as a new internal hashing algorithms. It's has similar security +* ``siphash13`` is added as a new internal hashing algorithms. It has similar security properties as ``siphash24`` but it is slightly faster for long inputs. ``str``, ``bytes``, - and some other types now use it as default algorithm for ``hash()``. :pep:`552` + and some other types now use it as default algorithm for :func:`hash`. :pep:`552` hash-based pyc files now use ``siphash13``, too. (Contributed by Inada Naoki in :issue:`29410`.) @@ -210,9 +210,9 @@ Other CPython Implementation Changes have been removed as their values can be derived from ``exc_value``. (Contributed by Irit Katriel in :issue:`45711`.) -* A new command line option for the Windows installer ``AppendPath`` has beend added. +* A new command line option for the Windows installer ``AppendPath`` has been added. It behaves similiar to ``PrependPath`` but appends the install and scripts directories - instead of prepending it. + instead of prepending them. (Contributed by Bastian Neuburger in :issue:`44934`.) From webhook-mailer at python.org Fri Mar 25 13:59:48 2022 From: webhook-mailer at python.org (asvetlov) Date: Fri, 25 Mar 2022 17:59:48 -0000 Subject: [Python-checkins] bpo-47118: Fix asyncio.Runner tests error (32117) Message-ID: https://github.com/python/cpython/commit/20e6e5636a06fe5e1472062918d0a302d82a71c3 commit: 20e6e5636a06fe5e1472062918d0a302d82a71c3 branch: main author: Andrew Svetlov committer: asvetlov date: 2022-03-25T19:59:29+02:00 summary: bpo-47118: Fix asyncio.Runner tests error (32117) files: M Lib/test/test_asyncio/test_runners.py diff --git a/Lib/test/test_asyncio/test_runners.py b/Lib/test/test_asyncio/test_runners.py index 2919412ab81db..c0bd1a242c86c 100644 --- a/Lib/test/test_asyncio/test_runners.py +++ b/Lib/test/test_asyncio/test_runners.py @@ -296,7 +296,7 @@ async def get_context(): self.assertEqual(-1, runner.run(f(1))) self.assertEqual(1, runner.run(f(2))) - self.assertEqual({cvar: 2}, dict(runner.run(get_context()))) + self.assertEqual(2, runner.run(get_context()).get(cvar)) def test_recursine_run(self): async def g(): From webhook-mailer at python.org Fri Mar 25 18:01:25 2022 From: webhook-mailer at python.org (asvetlov) Date: Fri, 25 Mar 2022 22:01:25 -0000 Subject: [Python-checkins] bpo-43352: Add a Barrier object in asyncio lib (GH-24903) Message-ID: https://github.com/python/cpython/commit/d03acd7270d66ddb8e987f9743405147ecc15087 commit: d03acd7270d66ddb8e987f9743405147ecc15087 branch: main author: Duprat committer: asvetlov date: 2022-03-26T00:01:21+02:00 summary: bpo-43352: Add a Barrier object in asyncio lib (GH-24903) Co-authored-by: Yury Selivanov Co-authored-by: Andrew Svetlov files: A Misc/NEWS.d/next/Library/2021-03-31-15-22-45.bpo-43352.nSjMuE.rst M Doc/library/asyncio-api-index.rst M Doc/library/asyncio-sync.rst M Lib/asyncio/exceptions.py M Lib/asyncio/locks.py M Lib/test/test_asyncio/test_locks.py diff --git a/Doc/library/asyncio-api-index.rst b/Doc/library/asyncio-api-index.rst index 8bc7943a71739..a4e38e469d82f 100644 --- a/Doc/library/asyncio-api-index.rst +++ b/Doc/library/asyncio-api-index.rst @@ -186,11 +186,16 @@ Threading-like synchronization primitives that can be used in Tasks. * - :class:`BoundedSemaphore` - A bounded semaphore. + * - :class:`Barrier` + - A barrier object. + .. rubric:: Examples * :ref:`Using asyncio.Event `. +* :ref:`Using asyncio.Barrier `. + * See also the documentation of asyncio :ref:`synchronization primitives `. @@ -206,6 +211,9 @@ Exceptions * - :exc:`asyncio.CancelledError` - Raised when a Task is cancelled. See also :meth:`Task.cancel`. + * - :exc:`asyncio.BrokenBarrierError` + - Raised when a Barrier is broken. See also :meth:`Barrier.wait`. + .. rubric:: Examples diff --git a/Doc/library/asyncio-sync.rst b/Doc/library/asyncio-sync.rst index f4063db2ee86e..141733ee2c800 100644 --- a/Doc/library/asyncio-sync.rst +++ b/Doc/library/asyncio-sync.rst @@ -28,6 +28,7 @@ asyncio has the following basic synchronization primitives: * :class:`Condition` * :class:`Semaphore` * :class:`BoundedSemaphore` +* :class:`Barrier` --------- @@ -340,6 +341,115 @@ BoundedSemaphore .. versionchanged:: 3.10 Removed the *loop* parameter. + +Barrier +======= + +.. class:: Barrier(parties, action=None) + + A barrier object. Not thread-safe. + + A barrier is a simple synchronization primitive that allows to block until + *parties* number of tasks are waiting on it. + Tasks can wait on the :meth:`~Barrier.wait` method and would be blocked until + the specified number of tasks end up waiting on :meth:`~Barrier.wait`. + At that point all of the waiting tasks would unblock simultaneously. + + :keyword:`async with` can be used as an alternative to awaiting on + :meth:`~Barrier.wait`. + + The barrier can be reused any number of times. + + .. _asyncio_example_barrier: + + Example:: + + async def example_barrier(): + # barrier with 3 parties + b = asyncio.Barrier(3) + + # create 2 new waiting tasks + asyncio.create_task(b.wait()) + asyncio.create_task(b.wait()) + + await asyncio.sleep(0) + print(b) + + # The third .wait() call passes the barrier + await b.wait() + print(b) + print("barrier passed") + + await asyncio.sleep(0) + print(b) + + asyncio.run(example_barrier()) + + Result of this example is:: + + + + barrier passed + + + .. versionadded:: 3.11 + + .. coroutinemethod:: wait() + + Pass the barrier. When all the tasks party to the barrier have called + this function, they are all unblocked simultaneously. + + When a waiting or blocked task in the barrier is cancelled, + this task exits the barrier which stays in the same state. + If the state of the barrier is "filling", the number of waiting task + decreases by 1. + + The return value is an integer in the range of 0 to ``parties-1``, different + for each task. This can be used to select a task to do some special + housekeeping, e.g.:: + + ... + async with barrier as position: + if position == 0: + # Only one task print this + print('End of *draining phasis*') + + This method may raise a :class:`BrokenBarrierError` exception if the + barrier is broken or reset while a task is waiting. + It could raise a :exc:`CancelledError` if a task is cancelled. + + .. coroutinemethod:: reset() + + Return the barrier to the default, empty state. Any tasks waiting on it + will receive the :class:`BrokenBarrierError` exception. + + If a barrier is broken it may be better to just leave it and create a new one. + + .. coroutinemethod:: abort() + + Put the barrier into a broken state. This causes any active or future + calls to :meth:`wait` to fail with the :class:`BrokenBarrierError`. + Use this for example if one of the taks needs to abort, to avoid infinite + waiting tasks. + + .. attribute:: parties + + The number of tasks required to pass the barrier. + + .. attribute:: n_waiting + + The number of tasks currently waiting in the barrier while filling. + + .. attribute:: broken + + A boolean that is ``True`` if the barrier is in the broken state. + + +.. exception:: BrokenBarrierError + + This exception, a subclass of :exc:`RuntimeError`, is raised when the + :class:`Barrier` object is reset or broken. + --------- diff --git a/Lib/asyncio/exceptions.py b/Lib/asyncio/exceptions.py index c764c9ffcfc19..5ece595aad647 100644 --- a/Lib/asyncio/exceptions.py +++ b/Lib/asyncio/exceptions.py @@ -1,7 +1,8 @@ """asyncio exceptions.""" -__all__ = ('CancelledError', 'InvalidStateError', 'TimeoutError', +__all__ = ('BrokenBarrierError', + 'CancelledError', 'InvalidStateError', 'TimeoutError', 'IncompleteReadError', 'LimitOverrunError', 'SendfileNotAvailableError') @@ -55,3 +56,7 @@ def __init__(self, message, consumed): def __reduce__(self): return type(self), (self.args[0], self.consumed) + + +class BrokenBarrierError(RuntimeError): + """Barrier is broken by barrier.abort() call.""" diff --git a/Lib/asyncio/locks.py b/Lib/asyncio/locks.py index 9b4612197de1d..e71130274dd6f 100644 --- a/Lib/asyncio/locks.py +++ b/Lib/asyncio/locks.py @@ -1,14 +1,15 @@ """Synchronization primitives.""" -__all__ = ('Lock', 'Event', 'Condition', 'Semaphore', 'BoundedSemaphore') +__all__ = ('Lock', 'Event', 'Condition', 'Semaphore', + 'BoundedSemaphore', 'Barrier') import collections +import enum from . import exceptions from . import mixins from . import tasks - class _ContextManagerMixin: async def __aenter__(self): await self.acquire() @@ -416,3 +417,155 @@ def release(self): if self._value >= self._bound_value: raise ValueError('BoundedSemaphore released too many times') super().release() + + + +class _BarrierState(enum.Enum): + FILLING = 'filling' + DRAINING = 'draining' + RESETTING = 'resetting' + BROKEN = 'broken' + + +class Barrier(mixins._LoopBoundMixin): + """Asyncio equivalent to threading.Barrier + + Implements a Barrier primitive. + Useful for synchronizing a fixed number of tasks at known synchronization + points. Tasks block on 'wait()' and are simultaneously awoken once they + have all made their call. + """ + + def __init__(self, parties): + """Create a barrier, initialised to 'parties' tasks.""" + if parties < 1: + raise ValueError('parties must be > 0') + + self._cond = Condition() # notify all tasks when state changes + + self._parties = parties + self._state = _BarrierState.FILLING + self._count = 0 # count tasks in Barrier + + def __repr__(self): + res = super().__repr__() + extra = f'{self._state.value}' + if not self.broken: + extra += f', waiters:{self.n_waiting}/{self.parties}' + return f'<{res[1:-1]} [{extra}]>' + + async def __aenter__(self): + # wait for the barrier reaches the parties number + # when start draining release and return index of waited task + return await self.wait() + + async def __aexit__(self, *args): + pass + + async def wait(self): + """Wait for the barrier. + + When the specified number of tasks have started waiting, they are all + simultaneously awoken. + Returns an unique and individual index number from 0 to 'parties-1'. + """ + async with self._cond: + await self._block() # Block while the barrier drains or resets. + try: + index = self._count + self._count += 1 + if index + 1 == self._parties: + # We release the barrier + await self._release() + else: + await self._wait() + return index + finally: + self._count -= 1 + # Wake up any tasks waiting for barrier to drain. + self._exit() + + async def _block(self): + # Block until the barrier is ready for us, + # or raise an exception if it is broken. + # + # It is draining or resetting, wait until done + # unless a CancelledError occurs + await self._cond.wait_for( + lambda: self._state not in ( + _BarrierState.DRAINING, _BarrierState.RESETTING + ) + ) + + # see if the barrier is in a broken state + if self._state is _BarrierState.BROKEN: + raise exceptions.BrokenBarrierError("Barrier aborted") + + async def _release(self): + # Release the tasks waiting in the barrier. + + # Enter draining state. + # Next waiting tasks will be blocked until the end of draining. + self._state = _BarrierState.DRAINING + self._cond.notify_all() + + async def _wait(self): + # Wait in the barrier until we are released. Raise an exception + # if the barrier is reset or broken. + + # wait for end of filling + # unless a CancelledError occurs + await self._cond.wait_for(lambda: self._state is not _BarrierState.FILLING) + + if self._state in (_BarrierState.BROKEN, _BarrierState.RESETTING): + raise exceptions.BrokenBarrierError("Abort or reset of barrier") + + def _exit(self): + # If we are the last tasks to exit the barrier, signal any tasks + # waiting for the barrier to drain. + if self._count == 0: + if self._state in (_BarrierState.RESETTING, _BarrierState.DRAINING): + self._state = _BarrierState.FILLING + self._cond.notify_all() + + async def reset(self): + """Reset the barrier to the initial state. + + Any tasks currently waiting will get the BrokenBarrier exception + raised. + """ + async with self._cond: + if self._count > 0: + if self._state is not _BarrierState.RESETTING: + #reset the barrier, waking up tasks + self._state = _BarrierState.RESETTING + else: + self._state = _BarrierState.FILLING + self._cond.notify_all() + + async def abort(self): + """Place the barrier into a 'broken' state. + + Useful in case of error. Any currently waiting tasks and tasks + attempting to 'wait()' will have BrokenBarrierError raised. + """ + async with self._cond: + self._state = _BarrierState.BROKEN + self._cond.notify_all() + + @property + def parties(self): + """Return the number of tasks required to trip the barrier.""" + return self._parties + + @property + def n_waiting(self): + """Return the number of tasks currently waiting at the barrier.""" + if self._state is _BarrierState.FILLING: + return self._count + return 0 + + @property + def broken(self): + """Return True if the barrier is in a broken state.""" + return self._state is _BarrierState.BROKEN diff --git a/Lib/test/test_asyncio/test_locks.py b/Lib/test/test_asyncio/test_locks.py index 920b3b5717a2c..415cbe570fde9 100644 --- a/Lib/test/test_asyncio/test_locks.py +++ b/Lib/test/test_asyncio/test_locks.py @@ -1,4 +1,4 @@ -"""Tests for lock.py""" +"""Tests for locks.py""" import unittest from unittest import mock @@ -9,7 +9,10 @@ STR_RGX_REPR = ( r'^<(?P.*?) object at (?P
.*?)' r'\[(?P' - r'(set|unset|locked|unlocked)(, value:\d)?(, waiters:\d+)?' + r'(set|unset|locked|unlocked|filling|draining|resetting|broken)' + r'(, value:\d)?' + r'(, waiters:\d+)?' + r'(, waiters:\d+\/\d+)?' # barrier r')\]>\Z' ) RGX_REPR = re.compile(STR_RGX_REPR) @@ -943,5 +946,576 @@ async def coro(tag): ) +class BarrierTests(unittest.IsolatedAsyncioTestCase): + + async def asyncSetUp(self): + await super().asyncSetUp() + self.N = 5 + + def make_tasks(self, n, coro): + tasks = [asyncio.create_task(coro()) for _ in range(n)] + return tasks + + async def gather_tasks(self, n, coro): + tasks = self.make_tasks(n, coro) + res = await asyncio.gather(*tasks) + return res, tasks + + async def test_barrier(self): + barrier = asyncio.Barrier(self.N) + self.assertIn("filling", repr(barrier)) + with self.assertRaisesRegex( + TypeError, + "object Barrier can't be used in 'await' expression", + ): + await barrier + + self.assertIn("filling", repr(barrier)) + + async def test_repr(self): + barrier = asyncio.Barrier(self.N) + + self.assertTrue(RGX_REPR.match(repr(barrier))) + self.assertIn("filling", repr(barrier)) + + waiters = [] + async def wait(barrier): + await barrier.wait() + + incr = 2 + for i in range(incr): + waiters.append(asyncio.create_task(wait(barrier))) + await asyncio.sleep(0) + + self.assertTrue(RGX_REPR.match(repr(barrier))) + self.assertTrue(f"waiters:{incr}/{self.N}" in repr(barrier)) + self.assertIn("filling", repr(barrier)) + + # create missing waiters + for i in range(barrier.parties - barrier.n_waiting): + waiters.append(asyncio.create_task(wait(barrier))) + await asyncio.sleep(0) + + self.assertTrue(RGX_REPR.match(repr(barrier))) + self.assertIn("draining", repr(barrier)) + + # add a part of waiters + for i in range(incr): + waiters.append(asyncio.create_task(wait(barrier))) + await asyncio.sleep(0) + # and reset + await barrier.reset() + + self.assertTrue(RGX_REPR.match(repr(barrier))) + self.assertIn("resetting", repr(barrier)) + + # add a part of waiters again + for i in range(incr): + waiters.append(asyncio.create_task(wait(barrier))) + await asyncio.sleep(0) + # and abort + await barrier.abort() + + self.assertTrue(RGX_REPR.match(repr(barrier))) + self.assertIn("broken", repr(barrier)) + self.assertTrue(barrier.broken) + + # suppress unhandled exceptions + await asyncio.gather(*waiters, return_exceptions=True) + + async def test_barrier_parties(self): + self.assertRaises(ValueError, lambda: asyncio.Barrier(0)) + self.assertRaises(ValueError, lambda: asyncio.Barrier(-4)) + + self.assertIsInstance(asyncio.Barrier(self.N), asyncio.Barrier) + + async def test_context_manager(self): + self.N = 3 + barrier = asyncio.Barrier(self.N) + results = [] + + async def coro(): + async with barrier as i: + results.append(i) + + await self.gather_tasks(self.N, coro) + + self.assertListEqual(sorted(results), list(range(self.N))) + self.assertEqual(barrier.n_waiting, 0) + self.assertFalse(barrier.broken) + + async def test_filling_one_task(self): + barrier = asyncio.Barrier(1) + + async def f(): + async with barrier as i: + return True + + ret = await f() + + self.assertTrue(ret) + self.assertEqual(barrier.n_waiting, 0) + self.assertFalse(barrier.broken) + + async def test_filling_one_task_twice(self): + barrier = asyncio.Barrier(1) + + t1 = asyncio.create_task(barrier.wait()) + await asyncio.sleep(0) + self.assertEqual(barrier.n_waiting, 0) + + t2 = asyncio.create_task(barrier.wait()) + await asyncio.sleep(0) + + self.assertEqual(t1.result(), t2.result()) + self.assertEqual(t1.done(), t2.done()) + + self.assertEqual(barrier.n_waiting, 0) + self.assertFalse(barrier.broken) + + async def test_filling_task_by_task(self): + self.N = 3 + barrier = asyncio.Barrier(self.N) + + t1 = asyncio.create_task(barrier.wait()) + await asyncio.sleep(0) + self.assertEqual(barrier.n_waiting, 1) + self.assertIn("filling", repr(barrier)) + + t2 = asyncio.create_task(barrier.wait()) + await asyncio.sleep(0) + self.assertEqual(barrier.n_waiting, 2) + self.assertIn("filling", repr(barrier)) + + t3 = asyncio.create_task(barrier.wait()) + await asyncio.sleep(0) + + await asyncio.wait([t1, t2, t3]) + + self.assertEqual(barrier.n_waiting, 0) + self.assertFalse(barrier.broken) + + async def test_filling_tasks_wait_twice(self): + barrier = asyncio.Barrier(self.N) + results = [] + + async def coro(): + async with barrier: + results.append(True) + + async with barrier: + results.append(False) + + await self.gather_tasks(self.N, coro) + + self.assertEqual(len(results), self.N*2) + self.assertEqual(results.count(True), self.N) + self.assertEqual(results.count(False), self.N) + + self.assertEqual(barrier.n_waiting, 0) + self.assertFalse(barrier.broken) + + async def test_filling_tasks_check_return_value(self): + barrier = asyncio.Barrier(self.N) + results1 = [] + results2 = [] + + async def coro(): + async with barrier: + results1.append(True) + + async with barrier as i: + results2.append(True) + return i + + res, _ = await self.gather_tasks(self.N, coro) + + self.assertEqual(len(results1), self.N) + self.assertTrue(all(results1)) + self.assertEqual(len(results2), self.N) + self.assertTrue(all(results2)) + self.assertListEqual(sorted(res), list(range(self.N))) + + self.assertEqual(barrier.n_waiting, 0) + self.assertFalse(barrier.broken) + + async def test_draining_state(self): + barrier = asyncio.Barrier(self.N) + results = [] + + async def coro(): + async with barrier: + # barrier state change to filling for the last task release + results.append("draining" in repr(barrier)) + + await self.gather_tasks(self.N, coro) + + self.assertEqual(len(results), self.N) + self.assertEqual(results[-1], False) + self.assertTrue(all(results[:self.N-1])) + + self.assertEqual(barrier.n_waiting, 0) + self.assertFalse(barrier.broken) + + async def test_blocking_tasks_while_draining(self): + rewait = 2 + barrier = asyncio.Barrier(self.N) + barrier_nowaiting = asyncio.Barrier(self.N - rewait) + results = [] + rewait_n = rewait + counter = 0 + + async def coro(): + nonlocal rewait_n + + # first time waiting + await barrier.wait() + + # after wainting once for all tasks + if rewait_n > 0: + rewait_n -= 1 + # wait again only for rewait tasks + await barrier.wait() + else: + # wait for end of draining state` + await barrier_nowaiting.wait() + # wait for other waiting tasks + await barrier.wait() + + # a success means that barrier_nowaiting + # was waited for exactly N-rewait=3 times + await self.gather_tasks(self.N, coro) + + async def test_filling_tasks_cancel_one(self): + self.N = 3 + barrier = asyncio.Barrier(self.N) + results = [] + + async def coro(): + await barrier.wait() + results.append(True) + + t1 = asyncio.create_task(coro()) + await asyncio.sleep(0) + self.assertEqual(barrier.n_waiting, 1) + + t2 = asyncio.create_task(coro()) + await asyncio.sleep(0) + self.assertEqual(barrier.n_waiting, 2) + + t1.cancel() + await asyncio.sleep(0) + self.assertEqual(barrier.n_waiting, 1) + with self.assertRaises(asyncio.CancelledError): + await t1 + self.assertTrue(t1.cancelled()) + + t3 = asyncio.create_task(coro()) + await asyncio.sleep(0) + self.assertEqual(barrier.n_waiting, 2) + + t4 = asyncio.create_task(coro()) + await asyncio.gather(t2, t3, t4) + + self.assertEqual(len(results), self.N) + self.assertTrue(all(results)) + + self.assertEqual(barrier.n_waiting, 0) + self.assertFalse(barrier.broken) + + async def test_reset_barrier(self): + barrier = asyncio.Barrier(1) + + asyncio.create_task(barrier.reset()) + await asyncio.sleep(0) + + self.assertEqual(barrier.n_waiting, 0) + self.assertFalse(barrier.broken) + + async def test_reset_barrier_while_tasks_waiting(self): + barrier = asyncio.Barrier(self.N) + results = [] + + async def coro(): + try: + await barrier.wait() + except asyncio.BrokenBarrierError: + results.append(True) + + async def coro_reset(): + await barrier.reset() + + # N-1 tasks waiting on barrier with N parties + tasks = self.make_tasks(self.N-1, coro) + await asyncio.sleep(0) + + # reset the barrier + asyncio.create_task(coro_reset()) + await asyncio.gather(*tasks) + + self.assertEqual(len(results), self.N-1) + self.assertTrue(all(results)) + self.assertEqual(barrier.n_waiting, 0) + self.assertNotIn("resetting", repr(barrier)) + self.assertFalse(barrier.broken) + + async def test_reset_barrier_when_tasks_half_draining(self): + barrier = asyncio.Barrier(self.N) + results1 = [] + rest_of_tasks = self.N//2 + + async def coro(): + try: + await barrier.wait() + except asyncio.BrokenBarrierError: + # catch here waiting tasks + results1.append(True) + else: + # here drained task ouside the barrier + if rest_of_tasks == barrier._count: + # tasks outside the barrier + await barrier.reset() + + await self.gather_tasks(self.N, coro) + + self.assertEqual(results1, [True]*rest_of_tasks) + self.assertEqual(barrier.n_waiting, 0) + self.assertNotIn("resetting", repr(barrier)) + self.assertFalse(barrier.broken) + + async def test_reset_barrier_when_tasks_half_draining_half_blocking(self): + barrier = asyncio.Barrier(self.N) + results1 = [] + results2 = [] + blocking_tasks = self.N//2 + count = 0 + + async def coro(): + nonlocal count + try: + await barrier.wait() + except asyncio.BrokenBarrierError: + # here catch still waiting tasks + results1.append(True) + + # so now waiting again to reach nb_parties + await barrier.wait() + else: + count += 1 + if count > blocking_tasks: + # reset now: raise asyncio.BrokenBarrierError for waiting tasks + await barrier.reset() + + # so now waiting again to reach nb_parties + await barrier.wait() + else: + try: + await barrier.wait() + except asyncio.BrokenBarrierError: + # here no catch - blocked tasks go to wait + results2.append(True) + + await self.gather_tasks(self.N, coro) + + self.assertEqual(results1, [True]*blocking_tasks) + self.assertEqual(results2, []) + self.assertEqual(barrier.n_waiting, 0) + self.assertNotIn("resetting", repr(barrier)) + self.assertFalse(barrier.broken) + + async def test_reset_barrier_while_tasks_waiting_and_waiting_again(self): + barrier = asyncio.Barrier(self.N) + results1 = [] + results2 = [] + + async def coro1(): + try: + await barrier.wait() + except asyncio.BrokenBarrierError: + results1.append(True) + finally: + await barrier.wait() + results2.append(True) + + async def coro2(): + async with barrier: + results2.append(True) + + tasks = self.make_tasks(self.N-1, coro1) + + # reset barrier, N-1 waiting tasks raise an BrokenBarrierError + asyncio.create_task(barrier.reset()) + await asyncio.sleep(0) + + # complete waiting tasks in the `finally` + asyncio.create_task(coro2()) + + await asyncio.gather(*tasks) + + self.assertFalse(barrier.broken) + self.assertEqual(len(results1), self.N-1) + self.assertTrue(all(results1)) + self.assertEqual(len(results2), self.N) + self.assertTrue(all(results2)) + + self.assertEqual(barrier.n_waiting, 0) + + + async def test_reset_barrier_while_tasks_draining(self): + barrier = asyncio.Barrier(self.N) + results1 = [] + results2 = [] + results3 = [] + count = 0 + + async def coro(): + nonlocal count + + i = await barrier.wait() + count += 1 + if count == self.N: + # last task exited from barrier + await barrier.reset() + + # wit here to reach the `parties` + await barrier.wait() + else: + try: + # second waiting + await barrier.wait() + + # N-1 tasks here + results1.append(True) + except Exception as e: + # never goes here + results2.append(True) + + # Now, pass the barrier again + # last wait, must be completed + k = await barrier.wait() + results3.append(True) + + await self.gather_tasks(self.N, coro) + + self.assertFalse(barrier.broken) + self.assertTrue(all(results1)) + self.assertEqual(len(results1), self.N-1) + self.assertEqual(len(results2), 0) + self.assertEqual(len(results3), self.N) + self.assertTrue(all(results3)) + + self.assertEqual(barrier.n_waiting, 0) + + async def test_abort_barrier(self): + barrier = asyncio.Barrier(1) + + asyncio.create_task(barrier.abort()) + await asyncio.sleep(0) + + self.assertEqual(barrier.n_waiting, 0) + self.assertTrue(barrier.broken) + + async def test_abort_barrier_when_tasks_half_draining_half_blocking(self): + barrier = asyncio.Barrier(self.N) + results1 = [] + results2 = [] + blocking_tasks = self.N//2 + count = 0 + + async def coro(): + nonlocal count + try: + await barrier.wait() + except asyncio.BrokenBarrierError: + # here catch tasks waiting to drain + results1.append(True) + else: + count += 1 + if count > blocking_tasks: + # abort now: raise asyncio.BrokenBarrierError for all tasks + await barrier.abort() + else: + try: + await barrier.wait() + except asyncio.BrokenBarrierError: + # here catch blocked tasks (already drained) + results2.append(True) + + await self.gather_tasks(self.N, coro) + + self.assertTrue(barrier.broken) + self.assertEqual(results1, [True]*blocking_tasks) + self.assertEqual(results2, [True]*(self.N-blocking_tasks-1)) + self.assertEqual(barrier.n_waiting, 0) + self.assertNotIn("resetting", repr(barrier)) + + async def test_abort_barrier_when_exception(self): + # test from threading.Barrier: see `lock_tests.test_reset` + barrier = asyncio.Barrier(self.N) + results1 = [] + results2 = [] + + async def coro(): + try: + async with barrier as i : + if i == self.N//2: + raise RuntimeError + async with barrier: + results1.append(True) + except asyncio.BrokenBarrierError: + results2.append(True) + except RuntimeError: + await barrier.abort() + + await self.gather_tasks(self.N, coro) + + self.assertTrue(barrier.broken) + self.assertEqual(len(results1), 0) + self.assertEqual(len(results2), self.N-1) + self.assertTrue(all(results2)) + self.assertEqual(barrier.n_waiting, 0) + + async def test_abort_barrier_when_exception_then_resetting(self): + # test from threading.Barrier: see `lock_tests.test_abort_and_reset`` + barrier1 = asyncio.Barrier(self.N) + barrier2 = asyncio.Barrier(self.N) + results1 = [] + results2 = [] + results3 = [] + + async def coro(): + try: + i = await barrier1.wait() + if i == self.N//2: + raise RuntimeError + await barrier1.wait() + results1.append(True) + except asyncio.BrokenBarrierError: + results2.append(True) + except RuntimeError: + await barrier1.abort() + + # Synchronize and reset the barrier. Must synchronize first so + # that everyone has left it when we reset, and after so that no + # one enters it before the reset. + i = await barrier2.wait() + if i == self.N//2: + await barrier1.reset() + await barrier2.wait() + await barrier1.wait() + results3.append(True) + + await self.gather_tasks(self.N, coro) + + self.assertFalse(barrier1.broken) + self.assertEqual(len(results1), 0) + self.assertEqual(len(results2), self.N-1) + self.assertTrue(all(results2)) + self.assertEqual(len(results3), self.N) + self.assertTrue(all(results3)) + + self.assertEqual(barrier1.n_waiting, 0) + + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2021-03-31-15-22-45.bpo-43352.nSjMuE.rst b/Misc/NEWS.d/next/Library/2021-03-31-15-22-45.bpo-43352.nSjMuE.rst new file mode 100644 index 0000000000000..e53ba28b64099 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-03-31-15-22-45.bpo-43352.nSjMuE.rst @@ -0,0 +1 @@ +Add an Barrier object in synchronization primitives of *asyncio* Lib in order to be consistant with Barrier from *threading* and *multiprocessing* libs* From webhook-mailer at python.org Fri Mar 25 18:26:35 2022 From: webhook-mailer at python.org (asvetlov) Date: Fri, 25 Mar 2022 22:26:35 -0000 Subject: [Python-checkins] bpo-47062: Rename factory argument to loop_factory (GH-32113) Message-ID: https://github.com/python/cpython/commit/bad6ffaa64eecd33f4320ca31b1201b25cd8fc91 commit: bad6ffaa64eecd33f4320ca31b1201b25cd8fc91 branch: main author: Andrew Svetlov committer: asvetlov date: 2022-03-26T00:26:23+02:00 summary: bpo-47062: Rename factory argument to loop_factory (GH-32113) files: M Doc/library/asyncio-runner.rst M Lib/asyncio/runners.py M Lib/test/test_asyncio/test_runners.py diff --git a/Doc/library/asyncio-runner.rst b/Doc/library/asyncio-runner.rst index 2f4de9edaa400..31becf192ada3 100644 --- a/Doc/library/asyncio-runner.rst +++ b/Doc/library/asyncio-runner.rst @@ -62,7 +62,7 @@ Running an asyncio Program Runner context manager ====================== -.. class:: Runner(*, debug=None, factory=None) +.. class:: Runner(*, debug=None, loop_factory=None) A context manager that simplifies *multiple* async function calls in the same context. @@ -74,7 +74,7 @@ Runner context manager debug mode explicitly. ``None`` is used to respect the global :ref:`asyncio-debug-mode` settings. - *factory* could be used for overriding the loop creation. + *loop_factory* could be used for overriding the loop creation. :func:`asyncio.new_event_loop` is used if ``None``. Basically, :func:`asyncio.run()` example can be rewritten with the runner usage:: diff --git a/Lib/asyncio/runners.py b/Lib/asyncio/runners.py index 975509c7d645d..768a403a85bee 100644 --- a/Lib/asyncio/runners.py +++ b/Lib/asyncio/runners.py @@ -21,7 +21,7 @@ class Runner: and properly finalizes the loop at the context manager exit. If debug is True, the event loop will be run in debug mode. - If factory is passed, it is used for new event loop creation. + If loop_factory is passed, it is used for new event loop creation. asyncio.run(main(), debug=True) @@ -41,10 +41,10 @@ class Runner: # Note: the class is final, it is not intended for inheritance. - def __init__(self, *, debug=None, factory=None): + def __init__(self, *, debug=None, loop_factory=None): self._state = _State.CREATED self._debug = debug - self._factory = factory + self._loop_factory = loop_factory self._loop = None self._context = None @@ -96,10 +96,10 @@ def _lazy_init(self): raise RuntimeError("Runner is closed") if self._state is _State.INITIALIZED: return - if self._factory is None: + if self._loop_factory is None: self._loop = events.new_event_loop() else: - self._loop = self._factory() + self._loop = self._loop_factory() if self._debug is not None: self._loop.set_debug(self._debug) self._context = contextvars.copy_context() diff --git a/Lib/test/test_asyncio/test_runners.py b/Lib/test/test_asyncio/test_runners.py index c0bd1a242c86c..94f26797b3309 100644 --- a/Lib/test/test_asyncio/test_runners.py +++ b/Lib/test/test_asyncio/test_runners.py @@ -201,7 +201,7 @@ def test_debug(self): def test_custom_factory(self): loop = mock.Mock() - with asyncio.Runner(factory=lambda: loop) as runner: + with asyncio.Runner(loop_factory=lambda: loop) as runner: self.assertIs(runner.get_loop(), loop) def test_run(self): From webhook-mailer at python.org Fri Mar 25 20:09:58 2022 From: webhook-mailer at python.org (ned-deily) Date: Sat, 26 Mar 2022 00:09:58 -0000 Subject: [Python-checkins] bpo-47105: Cite grp.h instead of pwd.h in grp docs (GH-32091) Message-ID: https://github.com/python/cpython/commit/ee912ad6f66bb8cf5a8a2b4a7ecd2752bf070864 commit: ee912ad6f66bb8cf5a8a2b4a7ecd2752bf070864 branch: main author: Alex Hedges committer: ned-deily date: 2022-03-25T20:09:40-04:00 summary: bpo-47105: Cite grp.h instead of pwd.h in grp docs (GH-32091) files: M Doc/library/grp.rst diff --git a/Doc/library/grp.rst b/Doc/library/grp.rst index 74de3f952005f..fbfb922d3e052 100644 --- a/Doc/library/grp.rst +++ b/Doc/library/grp.rst @@ -12,7 +12,7 @@ Unix versions. Group database entries are reported as a tuple-like object, whose attributes correspond to the members of the ``group`` structure (Attribute field below, see -````): +````): +-------+-----------+---------------------------------+ | Index | Attribute | Meaning | From webhook-mailer at python.org Fri Mar 25 20:21:55 2022 From: webhook-mailer at python.org (ned-deily) Date: Sat, 26 Mar 2022 00:21:55 -0000 Subject: [Python-checkins] bpo-47105: Cite grp.h instead of pwd.h in grp docs (GH-32091) (GH-32120) Message-ID: https://github.com/python/cpython/commit/48b3ae9e29545891bece874b4c0c0e394fe0f048 commit: 48b3ae9e29545891bece874b4c0c0e394fe0f048 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ned-deily date: 2022-03-25T20:21:50-04:00 summary: bpo-47105: Cite grp.h instead of pwd.h in grp docs (GH-32091) (GH-32120) (cherry picked from commit ee912ad6f66bb8cf5a8a2b4a7ecd2752bf070864) Co-authored-by: Alex Hedges files: M Doc/library/grp.rst diff --git a/Doc/library/grp.rst b/Doc/library/grp.rst index 74de3f952005f..fbfb922d3e052 100644 --- a/Doc/library/grp.rst +++ b/Doc/library/grp.rst @@ -12,7 +12,7 @@ Unix versions. Group database entries are reported as a tuple-like object, whose attributes correspond to the members of the ``group`` structure (Attribute field below, see -````): +````): +-------+-----------+---------------------------------+ | Index | Attribute | Meaning | From webhook-mailer at python.org Fri Mar 25 20:23:08 2022 From: webhook-mailer at python.org (ned-deily) Date: Sat, 26 Mar 2022 00:23:08 -0000 Subject: [Python-checkins] bpo-47105: Cite grp.h instead of pwd.h in grp docs (GH-32091) (GH-32121) Message-ID: https://github.com/python/cpython/commit/b8b473e943c0d105c79a6ebe2199dec18d785966 commit: b8b473e943c0d105c79a6ebe2199dec18d785966 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: ned-deily date: 2022-03-25T20:23:04-04:00 summary: bpo-47105: Cite grp.h instead of pwd.h in grp docs (GH-32091) (GH-32121) (cherry picked from commit ee912ad6f66bb8cf5a8a2b4a7ecd2752bf070864) Co-authored-by: Alex Hedges files: M Doc/library/grp.rst diff --git a/Doc/library/grp.rst b/Doc/library/grp.rst index 74de3f952005f..fbfb922d3e052 100644 --- a/Doc/library/grp.rst +++ b/Doc/library/grp.rst @@ -12,7 +12,7 @@ Unix versions. Group database entries are reported as a tuple-like object, whose attributes correspond to the members of the ``group`` structure (Attribute field below, see -````): +````): +-------+-----------+---------------------------------+ | Index | Attribute | Meaning | From webhook-mailer at python.org Sat Mar 26 12:29:16 2022 From: webhook-mailer at python.org (miss-islington) Date: Sat, 26 Mar 2022 16:29:16 -0000 Subject: [Python-checkins] bpo-47117: Don't crash if we fail to decode characters when the tokenizer buffers are uninitialized (GH-32129) Message-ID: https://github.com/python/cpython/commit/26cca8067bf5306e372c0e90036d832c5021fd90 commit: 26cca8067bf5306e372c0e90036d832c5021fd90 branch: main author: Pablo Galindo Salgado committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-26T09:29:02-07:00 summary: bpo-47117: Don't crash if we fail to decode characters when the tokenizer buffers are uninitialized (GH-32129) Automerge-Triggered-By: GH:pablogsal files: A Misc/NEWS.d/next/Core and Builtins/2022-03-26-15-45-57.bpo-47117.60W6GQ.rst M Parser/pegen_errors.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-26-15-45-57.bpo-47117.60W6GQ.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-26-15-45-57.bpo-47117.60W6GQ.rst new file mode 100644 index 0000000000000..5098ed86d0793 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-26-15-45-57.bpo-47117.60W6GQ.rst @@ -0,0 +1,2 @@ +Fix a crash if we fail to decode characters in interactive mode if the +tokenizer buffers are uninitialized. Patch by Pablo Galindo. diff --git a/Parser/pegen_errors.c b/Parser/pegen_errors.c index 0be9df0ae5535..489699679633e 100644 --- a/Parser/pegen_errors.c +++ b/Parser/pegen_errors.c @@ -248,7 +248,12 @@ get_error_line_from_tokenizer_buffers(Parser *p, Py_ssize_t lineno) assert((p->tok->fp == NULL && p->tok->str != NULL) || p->tok->fp == stdin); char *cur_line = p->tok->fp_interactive ? p->tok->interactive_src_start : p->tok->str; - assert(cur_line != NULL); + if (cur_line == NULL) { + assert(p->tok->fp_interactive); + // We can reach this point if the tokenizer buffers for interactive source have not been + // initialized because we failed to decode the original source with the given locale. + return PyUnicode_FromStringAndSize("", 0); + } Py_ssize_t relative_lineno = p->starting_lineno ? lineno - p->starting_lineno + 1 : lineno; const char* buf_end = p->tok->fp_interactive ? p->tok->interactive_src_end : p->tok->inp; @@ -311,7 +316,7 @@ _PyPegen_raise_error_known_location(Parser *p, PyObject *errtype, goto error; } - if (p->tok->fp_interactive) { + if (p->tok->fp_interactive && p->tok->interactive_src_start != NULL) { error_line = get_error_line_from_tokenizer_buffers(p, lineno); } else if (p->start_rule == Py_file_input) { From webhook-mailer at python.org Sat Mar 26 12:55:57 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Sat, 26 Mar 2022 16:55:57 -0000 Subject: [Python-checkins] bpo-43224: Implement PEP 646 grammar changes (GH-31018) Message-ID: https://github.com/python/cpython/commit/e8e737bcf6d22927caebc30c5d57ac4634063219 commit: e8e737bcf6d22927caebc30c5d57ac4634063219 branch: main author: Matthew Rahtz committer: JelleZijlstra date: 2022-03-26T09:55:35-07:00 summary: bpo-43224: Implement PEP 646 grammar changes (GH-31018) Co-authored-by: Jelle Zijlstra files: A Lib/test/test_pep646_syntax.py A Misc/NEWS.d/next/Core and Builtins/2022-01-20-16-48-09.bpo-43224.WDihrT.rst M Grammar/python.gram M Lib/ast.py M Lib/test/test_ast.py M Lib/test/test_future.py M Lib/test/test_syntax.py M Lib/test/test_unparse.py M Lib/typing.py M Parser/parser.c M Python/ast_unparse.c M Python/compile.c diff --git a/Grammar/python.gram b/Grammar/python.gram index 696f6a11191e1..b9965d224a85b 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -309,6 +309,8 @@ star_etc[StarEtc*]: | invalid_star_etc | '*' a=param_no_default b=param_maybe_default* c=[kwds] { _PyPegen_star_etc(p, a, b, c) } + | '*' a=param_no_default_star_annotation b=param_maybe_default* c=[kwds] { + _PyPegen_star_etc(p, a, b, c) } | '*' ',' b=param_maybe_default+ c=[kwds] { _PyPegen_star_etc(p, NULL, b, c) } | a=kwds { _PyPegen_star_etc(p, NULL, NULL, a) } @@ -333,6 +335,9 @@ kwds[arg_ty]: param_no_default[arg_ty]: | a=param ',' tc=TYPE_COMMENT? { _PyPegen_add_type_comment_to_arg(p, a, tc) } | a=param tc=TYPE_COMMENT? &')' { _PyPegen_add_type_comment_to_arg(p, a, tc) } +param_no_default_star_annotation[arg_ty]: + | a=param_star_annotation ',' tc=TYPE_COMMENT? { _PyPegen_add_type_comment_to_arg(p, a, tc) } + | a=param_star_annotation tc=TYPE_COMMENT? &')' { _PyPegen_add_type_comment_to_arg(p, a, tc) } param_with_default[NameDefaultPair*]: | a=param c=default ',' tc=TYPE_COMMENT? { _PyPegen_name_default_pair(p, a, c, tc) } | a=param c=default tc=TYPE_COMMENT? &')' { _PyPegen_name_default_pair(p, a, c, tc) } @@ -340,7 +345,9 @@ param_maybe_default[NameDefaultPair*]: | a=param c=default? ',' tc=TYPE_COMMENT? { _PyPegen_name_default_pair(p, a, c, tc) } | a=param c=default? tc=TYPE_COMMENT? &')' { _PyPegen_name_default_pair(p, a, c, tc) } param[arg_ty]: a=NAME b=annotation? { _PyAST_arg(a->v.Name.id, b, NULL, EXTRA) } +param_star_annotation[arg_ty]: a=NAME b=star_annotation { _PyAST_arg(a->v.Name.id, b, NULL, EXTRA) } annotation[expr_ty]: ':' a=expression { a } +star_annotation[expr_ty]: ':' a=star_expression { a } default[expr_ty]: '=' a=expression { a } | invalid_default # If statement @@ -782,7 +789,7 @@ primary[expr_ty]: slices[expr_ty]: | a=slice !',' { a } - | a[asdl_expr_seq*]=','.slice+ [','] { _PyAST_Tuple(a, Load, EXTRA) } + | a[asdl_expr_seq*]=','.(slice | starred_expression)+ [','] { _PyAST_Tuple(a, Load, EXTRA) } slice[expr_ty]: | a=[expression] ':' b=[expression] c=[':' d=[expression] { d }] { _PyAST_Slice(a, b, c, EXTRA) } diff --git a/Lib/ast.py b/Lib/ast.py index 625738ad681af..e81e28044bc6e 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -1476,20 +1476,17 @@ def visit_Call(self, node): self.traverse(e) def visit_Subscript(self, node): - def is_simple_tuple(slice_value): - # when unparsing a non-empty tuple, the parentheses can be safely - # omitted if there aren't any elements that explicitly requires - # parentheses (such as starred expressions). + def is_non_empty_tuple(slice_value): return ( isinstance(slice_value, Tuple) and slice_value.elts - and not any(isinstance(elt, Starred) for elt in slice_value.elts) ) self.set_precedence(_Precedence.ATOM, node.value) self.traverse(node.value) with self.delimit("[", "]"): - if is_simple_tuple(node.slice): + if is_non_empty_tuple(node.slice): + # parentheses can be omitted if the tuple isn't empty self.items_view(self.traverse, node.slice.elts) else: self.traverse(node.slice) diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index 039d1c1010b6d..03d9b310f161b 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -13,7 +13,7 @@ from test import support def to_tuple(t): - if t is None or isinstance(t, (str, int, complex)): + if t is None or isinstance(t, (str, int, complex)) or t is Ellipsis: return t elif isinstance(t, list): return [to_tuple(e) for e in t] @@ -46,10 +46,20 @@ def to_tuple(t): "def f(a=0): pass", # FunctionDef with varargs "def f(*args): pass", + # FunctionDef with varargs as TypeVarTuple + "def f(*args: *Ts): pass", + # FunctionDef with varargs as unpacked Tuple + "def f(*args: *tuple[int, ...]): pass", + # FunctionDef with varargs as unpacked Tuple *and* TypeVarTuple + "def f(*args: *tuple[int, *Ts]): pass", # FunctionDef with kwargs "def f(**kwargs): pass", # FunctionDef with all kind of args and docstring "def f(a, b=1, c=None, d=[], e={}, *args, f=42, **kwargs): 'doc for f()'", + # FunctionDef with type annotation on return involving unpacking + "def f() -> tuple[*Ts]: pass", + "def f() -> tuple[int, *Ts]: pass", + "def f() -> tuple[int, *tuple[int, ...]]: pass", # ClassDef "class C:pass", # ClassDef with docstring @@ -65,6 +75,10 @@ def to_tuple(t): "a,b = c", "(a,b) = c", "[a,b] = c", + # AnnAssign with unpacked types + "x: tuple[*Ts]", + "x: tuple[int, *Ts]", + "x: tuple[int, *tuple[str, ...]]", # AugAssign "v += 1", # For @@ -2315,8 +2329,14 @@ def main(): ('Module', [('FunctionDef', (1, 0, 1, 14), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None)], None, [], [], None, []), [('Pass', (1, 10, 1, 14))], [], None, None)], []), ('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None)], None, [], [], None, [('Constant', (1, 8, 1, 9), 0, None)]), [('Pass', (1, 12, 1, 16))], [], None, None)], []), ('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 11), 'args', None, None), [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0, 1, 23), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 16), 'args', ('Starred', (1, 13, 1, 16), ('Name', (1, 14, 1, 16), 'Ts', ('Load',)), ('Load',)), None), [], [], None, []), [('Pass', (1, 19, 1, 23))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0, 1, 36), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 29), 'args', ('Starred', (1, 13, 1, 29), ('Subscript', (1, 14, 1, 29), ('Name', (1, 14, 1, 19), 'tuple', ('Load',)), ('Tuple', (1, 20, 1, 28), [('Name', (1, 20, 1, 23), 'int', ('Load',)), ('Constant', (1, 25, 1, 28), Ellipsis, None)], ('Load',)), ('Load',)), ('Load',)), None), [], [], None, []), [('Pass', (1, 32, 1, 36))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0, 1, 36), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 29), 'args', ('Starred', (1, 13, 1, 29), ('Subscript', (1, 14, 1, 29), ('Name', (1, 14, 1, 19), 'tuple', ('Load',)), ('Tuple', (1, 20, 1, 28), [('Name', (1, 20, 1, 23), 'int', ('Load',)), ('Starred', (1, 25, 1, 28), ('Name', (1, 26, 1, 28), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), ('Load',)), None), [], [], None, []), [('Pass', (1, 32, 1, 36))], [], None, None)], []), ('Module', [('FunctionDef', (1, 0, 1, 21), 'f', ('arguments', [], [], None, [], [], ('arg', (1, 8, 1, 14), 'kwargs', None, None), []), [('Pass', (1, 17, 1, 21))], [], None, None)], []), ('Module', [('FunctionDef', (1, 0, 1, 71), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None), ('arg', (1, 9, 1, 10), 'b', None, None), ('arg', (1, 14, 1, 15), 'c', None, None), ('arg', (1, 22, 1, 23), 'd', None, None), ('arg', (1, 28, 1, 29), 'e', None, None)], ('arg', (1, 35, 1, 39), 'args', None, None), [('arg', (1, 41, 1, 42), 'f', None, None)], [('Constant', (1, 43, 1, 45), 42, None)], ('arg', (1, 49, 1, 55), 'kwargs', None, None), [('Constant', (1, 11, 1, 12), 1, None), ('Constant', (1, 16, 1, 20), None, None), ('List', (1, 24, 1, 26), [], ('Load',)), ('Dict', (1, 30, 1, 32), [], [])]), [('Expr', (1, 58, 1, 71), ('Constant', (1, 58, 1, 71), 'doc for f()', None))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0, 1, 27), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 23, 1, 27))], [], ('Subscript', (1, 11, 1, 21), ('Name', (1, 11, 1, 16), 'tuple', ('Load',)), ('Tuple', (1, 17, 1, 20), [('Starred', (1, 17, 1, 20), ('Name', (1, 18, 1, 20), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), None)], []), +('Module', [('FunctionDef', (1, 0, 1, 32), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 28, 1, 32))], [], ('Subscript', (1, 11, 1, 26), ('Name', (1, 11, 1, 16), 'tuple', ('Load',)), ('Tuple', (1, 17, 1, 25), [('Name', (1, 17, 1, 20), 'int', ('Load',)), ('Starred', (1, 22, 1, 25), ('Name', (1, 23, 1, 25), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), None)], []), +('Module', [('FunctionDef', (1, 0, 1, 45), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 41, 1, 45))], [], ('Subscript', (1, 11, 1, 39), ('Name', (1, 11, 1, 16), 'tuple', ('Load',)), ('Tuple', (1, 17, 1, 38), [('Name', (1, 17, 1, 20), 'int', ('Load',)), ('Starred', (1, 22, 1, 38), ('Subscript', (1, 23, 1, 38), ('Name', (1, 23, 1, 28), 'tuple', ('Load',)), ('Tuple', (1, 29, 1, 37), [('Name', (1, 29, 1, 32), 'int', ('Load',)), ('Constant', (1, 34, 1, 37), Ellipsis, None)], ('Load',)), ('Load',)), ('Load',))], ('Load',)), ('Load',)), None)], []), ('Module', [('ClassDef', (1, 0, 1, 12), 'C', [], [], [('Pass', (1, 8, 1, 12))], [])], []), ('Module', [('ClassDef', (1, 0, 1, 32), 'C', [], [], [('Expr', (1, 9, 1, 32), ('Constant', (1, 9, 1, 32), 'docstring for class C', None))], [])], []), ('Module', [('ClassDef', (1, 0, 1, 21), 'C', [('Name', (1, 8, 1, 14), 'object', ('Load',))], [], [('Pass', (1, 17, 1, 21))], [])], []), @@ -2326,6 +2346,9 @@ def main(): ('Module', [('Assign', (1, 0, 1, 7), [('Tuple', (1, 0, 1, 3), [('Name', (1, 0, 1, 1), 'a', ('Store',)), ('Name', (1, 2, 1, 3), 'b', ('Store',))], ('Store',))], ('Name', (1, 6, 1, 7), 'c', ('Load',)), None)], []), ('Module', [('Assign', (1, 0, 1, 9), [('Tuple', (1, 0, 1, 5), [('Name', (1, 1, 1, 2), 'a', ('Store',)), ('Name', (1, 3, 1, 4), 'b', ('Store',))], ('Store',))], ('Name', (1, 8, 1, 9), 'c', ('Load',)), None)], []), ('Module', [('Assign', (1, 0, 1, 9), [('List', (1, 0, 1, 5), [('Name', (1, 1, 1, 2), 'a', ('Store',)), ('Name', (1, 3, 1, 4), 'b', ('Store',))], ('Store',))], ('Name', (1, 8, 1, 9), 'c', ('Load',)), None)], []), +('Module', [('AnnAssign', (1, 0, 1, 13), ('Name', (1, 0, 1, 1), 'x', ('Store',)), ('Subscript', (1, 3, 1, 13), ('Name', (1, 3, 1, 8), 'tuple', ('Load',)), ('Tuple', (1, 9, 1, 12), [('Starred', (1, 9, 1, 12), ('Name', (1, 10, 1, 12), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), None, 1)], []), +('Module', [('AnnAssign', (1, 0, 1, 18), ('Name', (1, 0, 1, 1), 'x', ('Store',)), ('Subscript', (1, 3, 1, 18), ('Name', (1, 3, 1, 8), 'tuple', ('Load',)), ('Tuple', (1, 9, 1, 17), [('Name', (1, 9, 1, 12), 'int', ('Load',)), ('Starred', (1, 14, 1, 17), ('Name', (1, 15, 1, 17), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), None, 1)], []), +('Module', [('AnnAssign', (1, 0, 1, 31), ('Name', (1, 0, 1, 1), 'x', ('Store',)), ('Subscript', (1, 3, 1, 31), ('Name', (1, 3, 1, 8), 'tuple', ('Load',)), ('Tuple', (1, 9, 1, 30), [('Name', (1, 9, 1, 12), 'int', ('Load',)), ('Starred', (1, 14, 1, 30), ('Subscript', (1, 15, 1, 30), ('Name', (1, 15, 1, 20), 'tuple', ('Load',)), ('Tuple', (1, 21, 1, 29), [('Name', (1, 21, 1, 24), 'str', ('Load',)), ('Constant', (1, 26, 1, 29), Ellipsis, None)], ('Load',)), ('Load',)), ('Load',))], ('Load',)), ('Load',)), None, 1)], []), ('Module', [('AugAssign', (1, 0, 1, 6), ('Name', (1, 0, 1, 1), 'v', ('Store',)), ('Add',), ('Constant', (1, 5, 1, 6), 1, None))], []), ('Module', [('For', (1, 0, 1, 15), ('Name', (1, 4, 1, 5), 'v', ('Store',)), ('Name', (1, 9, 1, 10), 'v', ('Load',)), [('Pass', (1, 11, 1, 15))], [], None)], []), ('Module', [('While', (1, 0, 1, 12), ('Name', (1, 6, 1, 7), 'v', ('Load',)), [('Pass', (1, 8, 1, 12))], [])], []), diff --git a/Lib/test/test_future.py b/Lib/test/test_future.py index 5a3944e69e640..c3e8420d6672c 100644 --- a/Lib/test/test_future.py +++ b/Lib/test/test_future.py @@ -175,7 +175,7 @@ def _exec_future(self, code): scope = {} exec( "from __future__ import annotations\n" - + code, {}, scope + + code, scope ) return scope @@ -287,10 +287,11 @@ def test_annotations(self): eq("list[str]") eq("dict[str, int]") eq("set[str,]") + eq("tuple[()]") eq("tuple[str, ...]") - eq("tuple[(str, *types)]") + eq("tuple[str, *types]") eq("tuple[str, int, (str, int)]") - eq("tuple[(*int, str, str, (str, int))]") + eq("tuple[*int, str, str, (str, int)]") eq("tuple[str, int, float, dict[str, int]]") eq("slice[0]") eq("slice[0:1]") @@ -305,6 +306,21 @@ def test_annotations(self): eq("slice[1:2, 1]") eq("slice[1:2, 2, 3]") eq("slice[()]") + # Note that `slice[*Ts]`, `slice[*Ts,]`, and `slice[(*Ts,)]` all have + # the same AST, but only `slice[*Ts,]` passes this test, because that's + # what the unparser produces. + eq("slice[*Ts,]") + eq("slice[1, *Ts]") + eq("slice[*Ts, 2]") + eq("slice[1, *Ts, 2]") + eq("slice[*Ts, *Ts]") + eq("slice[1, *Ts, *Ts]") + eq("slice[*Ts, 1, *Ts]") + eq("slice[*Ts, *Ts, 1]") + eq("slice[1, *Ts, *Ts, 2]") + eq("slice[1:2, *Ts]") + eq("slice[*Ts, 1:2]") + eq("slice[1:2, *Ts, 3:4]") eq("slice[a, b:c, d:e:f]") eq("slice[(x for x in a)]") eq('str or None if sys.version_info[0] > (3,) else str or bytes or None') @@ -403,6 +419,25 @@ def foo(): def bar(arg: (yield)): pass """)) + def test_get_type_hints_on_func_with_variadic_arg(self): + # `typing.get_type_hints` might break on a function with a variadic + # annotation (e.g. `f(*args: *Ts)`) if `from __future__ import + # annotations`, because it could try to evaluate `*Ts` as an expression, + # which on its own isn't value syntax. + namespace = self._exec_future(dedent("""\ + class StarredC: pass + class C: + def __iter__(self): + yield StarredC() + c = C() + def f(*args: *c): pass + import typing + hints = typing.get_type_hints(f) + """)) + + hints = namespace.pop('hints') + self.assertIsInstance(hints['args'], namespace['StarredC']) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_pep646_syntax.py b/Lib/test/test_pep646_syntax.py new file mode 100644 index 0000000000000..3ffa82dc55fa2 --- /dev/null +++ b/Lib/test/test_pep646_syntax.py @@ -0,0 +1,326 @@ +doctests = """ + +Setup + + >>> class AClass: + ... def __init__(self): + ... self._setitem_name = None + ... self._setitem_val = None + ... self._delitem_name = None + ... def __setitem__(self, name, val): + ... self._delitem_name = None + ... self._setitem_name = name + ... self._setitem_val = val + ... def __repr__(self): + ... if self._setitem_name is not None: + ... return f"A[{self._setitem_name}]={self._setitem_val}" + ... elif self._delitem_name is not None: + ... return f"delA[{self._delitem_name}]" + ... def __getitem__(self, name): + ... return ParameterisedA(name) + ... def __delitem__(self, name): + ... self._setitem_name = None + ... self._delitem_name = name + ... + >>> class ParameterisedA: + ... def __init__(self, name): + ... self._name = name + ... def __repr__(self): + ... return f"A[{self._name}]" + ... def __iter__(self): + ... for p in self._name: + ... yield p + >>> class B: + ... def __iter__(self): + ... yield StarredB() + ... def __repr__(self): + ... return "B" + >>> class StarredB: + ... def __repr__(self): + ... return "StarredB" + >>> A = AClass() + >>> b = B() + +Slices that are supposed to work, starring our custom B class + + >>> A[*b] + A[(StarredB,)] + >>> A[*b] = 1; A + A[(StarredB,)]=1 + >>> del A[*b]; A + delA[(StarredB,)] + + >>> A[*b, *b] + A[(StarredB, StarredB)] + >>> A[*b, *b] = 1; A + A[(StarredB, StarredB)]=1 + >>> del A[*b, *b]; A + delA[(StarredB, StarredB)] + + >>> A[b, *b] + A[(B, StarredB)] + >>> A[b, *b] = 1; A + A[(B, StarredB)]=1 + >>> del A[b, *b]; A + delA[(B, StarredB)] + + >>> A[*b, b] + A[(StarredB, B)] + >>> A[*b, b] = 1; A + A[(StarredB, B)]=1 + >>> del A[*b, b]; A + delA[(StarredB, B)] + + >>> A[b, b, *b] + A[(B, B, StarredB)] + >>> A[b, b, *b] = 1; A + A[(B, B, StarredB)]=1 + >>> del A[b, b, *b]; A + delA[(B, B, StarredB)] + + >>> A[*b, b, b] + A[(StarredB, B, B)] + >>> A[*b, b, b] = 1; A + A[(StarredB, B, B)]=1 + >>> del A[*b, b, b]; A + delA[(StarredB, B, B)] + + >>> A[b, *b, b] + A[(B, StarredB, B)] + >>> A[b, *b, b] = 1; A + A[(B, StarredB, B)]=1 + >>> del A[b, *b, b]; A + delA[(B, StarredB, B)] + + >>> A[b, b, *b, b] + A[(B, B, StarredB, B)] + >>> A[b, b, *b, b] = 1; A + A[(B, B, StarredB, B)]=1 + >>> del A[b, b, *b, b]; A + delA[(B, B, StarredB, B)] + + >>> A[b, *b, b, b] + A[(B, StarredB, B, B)] + >>> A[b, *b, b, b] = 1; A + A[(B, StarredB, B, B)]=1 + >>> del A[b, *b, b, b]; A + delA[(B, StarredB, B, B)] + + >>> A[A[b, *b, b]] + A[A[(B, StarredB, B)]] + >>> A[A[b, *b, b]] = 1; A + A[A[(B, StarredB, B)]]=1 + >>> del A[A[b, *b, b]]; A + delA[A[(B, StarredB, B)]] + + >>> A[*A[b, *b, b]] + A[(B, StarredB, B)] + >>> A[*A[b, *b, b]] = 1; A + A[(B, StarredB, B)]=1 + >>> del A[*A[b, *b, b]]; A + delA[(B, StarredB, B)] + + >>> A[b, ...] + A[(B, Ellipsis)] + >>> A[b, ...] = 1; A + A[(B, Ellipsis)]=1 + >>> del A[b, ...]; A + delA[(B, Ellipsis)] + + >>> A[*A[b, ...]] + A[(B, Ellipsis)] + >>> A[*A[b, ...]] = 1; A + A[(B, Ellipsis)]=1 + >>> del A[*A[b, ...]]; A + delA[(B, Ellipsis)] + +Slices that are supposed to work, starring a list + + >>> l = [1, 2, 3] + + >>> A[*l] + A[(1, 2, 3)] + >>> A[*l] = 1; A + A[(1, 2, 3)]=1 + >>> del A[*l]; A + delA[(1, 2, 3)] + + >>> A[*l, 4] + A[(1, 2, 3, 4)] + >>> A[*l, 4] = 1; A + A[(1, 2, 3, 4)]=1 + >>> del A[*l, 4]; A + delA[(1, 2, 3, 4)] + + >>> A[0, *l] + A[(0, 1, 2, 3)] + >>> A[0, *l] = 1; A + A[(0, 1, 2, 3)]=1 + >>> del A[0, *l]; A + delA[(0, 1, 2, 3)] + + >>> A[1:2, *l] + A[(slice(1, 2, None), 1, 2, 3)] + >>> A[1:2, *l] = 1; A + A[(slice(1, 2, None), 1, 2, 3)]=1 + >>> del A[1:2, *l]; A + delA[(slice(1, 2, None), 1, 2, 3)] + + >>> repr(A[1:2, *l]) == repr(A[1:2, 1, 2, 3]) + True + +Slices that are supposed to work, starring a tuple + + >>> t = (1, 2, 3) + + >>> A[*t] + A[(1, 2, 3)] + >>> A[*t] = 1; A + A[(1, 2, 3)]=1 + >>> del A[*t]; A + delA[(1, 2, 3)] + + >>> A[*t, 4] + A[(1, 2, 3, 4)] + >>> A[*t, 4] = 1; A + A[(1, 2, 3, 4)]=1 + >>> del A[*t, 4]; A + delA[(1, 2, 3, 4)] + + >>> A[0, *t] + A[(0, 1, 2, 3)] + >>> A[0, *t] = 1; A + A[(0, 1, 2, 3)]=1 + >>> del A[0, *t]; A + delA[(0, 1, 2, 3)] + + >>> A[1:2, *t] + A[(slice(1, 2, None), 1, 2, 3)] + >>> A[1:2, *t] = 1; A + A[(slice(1, 2, None), 1, 2, 3)]=1 + >>> del A[1:2, *t]; A + delA[(slice(1, 2, None), 1, 2, 3)] + + >>> repr(A[1:2, *t]) == repr(A[1:2, 1, 2, 3]) + True + +Starring an expression (rather than a name) in a slice + + >>> def returns_list(): + ... return [1, 2, 3] + + >>> A[returns_list()] + A[[1, 2, 3]] + >>> A[returns_list()] = 1; A + A[[1, 2, 3]]=1 + >>> del A[returns_list()]; A + delA[[1, 2, 3]] + + >>> A[returns_list(), 4] + A[([1, 2, 3], 4)] + >>> A[returns_list(), 4] = 1; A + A[([1, 2, 3], 4)]=1 + >>> del A[returns_list(), 4]; A + delA[([1, 2, 3], 4)] + + >>> A[*returns_list()] + A[(1, 2, 3)] + >>> A[*returns_list()] = 1; A + A[(1, 2, 3)]=1 + >>> del A[*returns_list()]; A + delA[(1, 2, 3)] + + >>> A[*returns_list(), 4] + A[(1, 2, 3, 4)] + >>> A[*returns_list(), 4] = 1; A + A[(1, 2, 3, 4)]=1 + >>> del A[*returns_list(), 4]; A + delA[(1, 2, 3, 4)] + + >>> A[0, *returns_list()] + A[(0, 1, 2, 3)] + >>> A[0, *returns_list()] = 1; A + A[(0, 1, 2, 3)]=1 + >>> del A[0, *returns_list()]; A + delA[(0, 1, 2, 3)] + + >>> A[*returns_list(), *returns_list()] + A[(1, 2, 3, 1, 2, 3)] + >>> A[*returns_list(), *returns_list()] = 1; A + A[(1, 2, 3, 1, 2, 3)]=1 + >>> del A[*returns_list(), *returns_list()]; A + delA[(1, 2, 3, 1, 2, 3)] + +Using both a starred object and a start:stop in a slice +(See also tests in test_syntax confirming that starring *inside* a start:stop +is *not* valid syntax.) + + >>> A[1:2, *b] + A[(slice(1, 2, None), StarredB)] + >>> A[*b, 1:2] + A[(StarredB, slice(1, 2, None))] + >>> A[1:2, *b, 1:2] + A[(slice(1, 2, None), StarredB, slice(1, 2, None))] + >>> A[*b, 1:2, *b] + A[(StarredB, slice(1, 2, None), StarredB)] + + >>> A[1:, *b] + A[(slice(1, None, None), StarredB)] + >>> A[*b, 1:] + A[(StarredB, slice(1, None, None))] + >>> A[1:, *b, 1:] + A[(slice(1, None, None), StarredB, slice(1, None, None))] + >>> A[*b, 1:, *b] + A[(StarredB, slice(1, None, None), StarredB)] + + >>> A[:1, *b] + A[(slice(None, 1, None), StarredB)] + >>> A[*b, :1] + A[(StarredB, slice(None, 1, None))] + >>> A[:1, *b, :1] + A[(slice(None, 1, None), StarredB, slice(None, 1, None))] + >>> A[*b, :1, *b] + A[(StarredB, slice(None, 1, None), StarredB)] + + >>> A[:, *b] + A[(slice(None, None, None), StarredB)] + >>> A[*b, :] + A[(StarredB, slice(None, None, None))] + >>> A[:, *b, :] + A[(slice(None, None, None), StarredB, slice(None, None, None))] + >>> A[*b, :, *b] + A[(StarredB, slice(None, None, None), StarredB)] + +*args annotated as starred expression + + >>> def f1(*args: *b): pass + >>> f1.__annotations__ + {'args': StarredB} + + >>> def f2(*args: *b, arg1): pass + >>> f2.__annotations__ + {'args': StarredB} + + >>> def f3(*args: *b, arg1: int): pass + >>> f3.__annotations__ + {'args': StarredB, 'arg1': } + + >>> def f4(*args: *b, arg1: int = 2): pass + >>> f4.__annotations__ + {'args': StarredB, 'arg1': } + + >>> def f5(*args: *b = (1,)): pass + Traceback (most recent call last): + ... + SyntaxError: invalid syntax +""" + +__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) + +if __name__ == "__main__": + test_main(verbose=True) diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 5f16a159f13d3..3e79ebfc68351 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -1622,6 +1622,149 @@ ... ... Traceback (most recent call last): SyntaxError: positional patterns follow keyword patterns + +Uses of the star operator which should fail: + +A[:*b] + + >>> A[:*b] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> A[:(*b)] + Traceback (most recent call last): + ... + SyntaxError: cannot use starred expression here + >>> A[:*b] = 1 + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> del A[:*b] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + +A[*b:] + + >>> A[*b:] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> A[(*b):] + Traceback (most recent call last): + ... + SyntaxError: cannot use starred expression here + >>> A[*b:] = 1 + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> del A[*b:] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + +A[*b:*b] + + >>> A[*b:*b] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> A[(*b:*b)] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> A[*b:*b] = 1 + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> del A[*b:*b] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + +A[*(1:2)] + + >>> A[*(1:2)] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> A[*(1:2)] = 1 + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> del A[*(1:2)] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + +A[*:] and A[:*] + + >>> A[*:] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> A[:*] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + +A[*] + + >>> A[*] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + +A[**] + + >>> A[**] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + +A[**b] + + >>> A[**b] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> A[**b] = 1 + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> del A[**b] + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + +def f(x: *b) + + >>> def f6(x: *b): pass + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> def f7(x: *b = 1): pass + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + +**kwargs: *a + + >>> def f8(**kwargs: *a): pass + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + +x: *b + + >>> x: *b + Traceback (most recent call last): + ... + SyntaxError: invalid syntax + >>> x: *b = 1 + Traceback (most recent call last): + ... + SyntaxError: invalid syntax """ import re diff --git a/Lib/test/test_unparse.py b/Lib/test/test_unparse.py index f5be13aa94a64..e38b33574cccc 100644 --- a/Lib/test/test_unparse.py +++ b/Lib/test/test_unparse.py @@ -344,7 +344,17 @@ def test_slices(self): self.check_ast_roundtrip("a[i]") self.check_ast_roundtrip("a[i,]") self.check_ast_roundtrip("a[i, j]") + # The AST for these next two both look like `a[(*a,)]` self.check_ast_roundtrip("a[(*a,)]") + self.check_ast_roundtrip("a[*a]") + self.check_ast_roundtrip("a[b, *a]") + self.check_ast_roundtrip("a[*a, c]") + self.check_ast_roundtrip("a[b, *a, c]") + self.check_ast_roundtrip("a[*a, *a]") + self.check_ast_roundtrip("a[b, *a, *a]") + self.check_ast_roundtrip("a[*a, b, *a]") + self.check_ast_roundtrip("a[*a, *a, b]") + self.check_ast_roundtrip("a[b, *a, *a, c]") self.check_ast_roundtrip("a[(a:=b)]") self.check_ast_roundtrip("a[(a:=b,c)]") self.check_ast_roundtrip("a[()]") @@ -543,9 +553,23 @@ def test_unary_op_factor(self): self.check_src_roundtrip(f"{prefix} 1") def test_slices(self): + self.check_src_roundtrip("a[()]") self.check_src_roundtrip("a[1]") self.check_src_roundtrip("a[1, 2]") - self.check_src_roundtrip("a[(1, *a)]") + # Note that `a[*a]`, `a[*a,]`, and `a[(*a,)]` all evaluate to the same + # thing at runtime and have the same AST, but only `a[*a,]` passes + # this test, because that's what `ast.unparse` produces. + self.check_src_roundtrip("a[*a,]") + self.check_src_roundtrip("a[1, *a]") + self.check_src_roundtrip("a[*a, 2]") + self.check_src_roundtrip("a[1, *a, 2]") + self.check_src_roundtrip("a[*a, *a]") + self.check_src_roundtrip("a[1, *a, *a]") + self.check_src_roundtrip("a[*a, 1, *a]") + self.check_src_roundtrip("a[*a, *a, 1]") + self.check_src_roundtrip("a[1, *a, *a, 2]") + self.check_src_roundtrip("a[1:2, *a]") + self.check_src_roundtrip("a[*a, 1:2]") def test_lambda_parameters(self): self.check_src_roundtrip("lambda: something") diff --git a/Lib/typing.py b/Lib/typing.py index 64b348e0b9d5c..36f9eceb38c7c 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -734,10 +734,19 @@ class ForwardRef(_Final, _root=True): def __init__(self, arg, is_argument=True, module=None, *, is_class=False): if not isinstance(arg, str): raise TypeError(f"Forward reference must be a string -- got {arg!r}") + + # If we do `def f(*args: *Ts)`, then we'll have `arg = '*Ts'`. + # Unfortunately, this isn't a valid expression on its own, so we + # do the unpacking manually. + if arg[0] == '*': + arg_to_compile = f'({arg},)[0]' # E.g. (*Ts,)[0] + else: + arg_to_compile = arg try: - code = compile(arg, '', 'eval') + code = compile(arg_to_compile, '', 'eval') except SyntaxError: raise SyntaxError(f"Forward reference must be an expression -- got {arg!r}") + self.__forward_arg__ = arg self.__forward_code__ = code self.__forward_evaluated__ = False diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-01-20-16-48-09.bpo-43224.WDihrT.rst b/Misc/NEWS.d/next/Core and Builtins/2022-01-20-16-48-09.bpo-43224.WDihrT.rst new file mode 100644 index 0000000000000..55affb26c1937 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-01-20-16-48-09.bpo-43224.WDihrT.rst @@ -0,0 +1 @@ +Make grammar changes required for PEP 646. diff --git a/Parser/parser.c b/Parser/parser.c index 8595efba73309..40c5d62fe49d7 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -116,434 +116,439 @@ static char *soft_keywords[] = { #define star_etc_type 1040 #define kwds_type 1041 #define param_no_default_type 1042 -#define param_with_default_type 1043 -#define param_maybe_default_type 1044 -#define param_type 1045 -#define annotation_type 1046 -#define default_type 1047 -#define if_stmt_type 1048 -#define elif_stmt_type 1049 -#define else_block_type 1050 -#define while_stmt_type 1051 -#define for_stmt_type 1052 -#define with_stmt_type 1053 -#define with_item_type 1054 -#define try_stmt_type 1055 -#define except_block_type 1056 -#define except_star_block_type 1057 -#define finally_block_type 1058 -#define match_stmt_type 1059 -#define subject_expr_type 1060 -#define case_block_type 1061 -#define guard_type 1062 -#define patterns_type 1063 -#define pattern_type 1064 -#define as_pattern_type 1065 -#define or_pattern_type 1066 -#define closed_pattern_type 1067 -#define literal_pattern_type 1068 -#define literal_expr_type 1069 -#define complex_number_type 1070 -#define signed_number_type 1071 -#define signed_real_number_type 1072 -#define real_number_type 1073 -#define imaginary_number_type 1074 -#define capture_pattern_type 1075 -#define pattern_capture_target_type 1076 -#define wildcard_pattern_type 1077 -#define value_pattern_type 1078 -#define attr_type 1079 // Left-recursive -#define name_or_attr_type 1080 // Left-recursive -#define group_pattern_type 1081 -#define sequence_pattern_type 1082 -#define open_sequence_pattern_type 1083 -#define maybe_sequence_pattern_type 1084 -#define maybe_star_pattern_type 1085 -#define star_pattern_type 1086 -#define mapping_pattern_type 1087 -#define items_pattern_type 1088 -#define key_value_pattern_type 1089 -#define double_star_pattern_type 1090 -#define class_pattern_type 1091 -#define positional_patterns_type 1092 -#define keyword_patterns_type 1093 -#define keyword_pattern_type 1094 -#define expressions_type 1095 -#define expression_type 1096 -#define yield_expr_type 1097 -#define star_expressions_type 1098 -#define star_expression_type 1099 -#define star_named_expressions_type 1100 -#define star_named_expression_type 1101 -#define assignment_expression_type 1102 -#define named_expression_type 1103 -#define disjunction_type 1104 -#define conjunction_type 1105 -#define inversion_type 1106 -#define comparison_type 1107 -#define compare_op_bitwise_or_pair_type 1108 -#define eq_bitwise_or_type 1109 -#define noteq_bitwise_or_type 1110 -#define lte_bitwise_or_type 1111 -#define lt_bitwise_or_type 1112 -#define gte_bitwise_or_type 1113 -#define gt_bitwise_or_type 1114 -#define notin_bitwise_or_type 1115 -#define in_bitwise_or_type 1116 -#define isnot_bitwise_or_type 1117 -#define is_bitwise_or_type 1118 -#define bitwise_or_type 1119 // Left-recursive -#define bitwise_xor_type 1120 // Left-recursive -#define bitwise_and_type 1121 // Left-recursive -#define shift_expr_type 1122 // Left-recursive -#define sum_type 1123 // Left-recursive -#define term_type 1124 // Left-recursive -#define factor_type 1125 -#define power_type 1126 -#define await_primary_type 1127 -#define primary_type 1128 // Left-recursive -#define slices_type 1129 -#define slice_type 1130 -#define atom_type 1131 -#define group_type 1132 -#define lambdef_type 1133 -#define lambda_params_type 1134 -#define lambda_parameters_type 1135 -#define lambda_slash_no_default_type 1136 -#define lambda_slash_with_default_type 1137 -#define lambda_star_etc_type 1138 -#define lambda_kwds_type 1139 -#define lambda_param_no_default_type 1140 -#define lambda_param_with_default_type 1141 -#define lambda_param_maybe_default_type 1142 -#define lambda_param_type 1143 -#define strings_type 1144 -#define list_type 1145 -#define tuple_type 1146 -#define set_type 1147 -#define dict_type 1148 -#define double_starred_kvpairs_type 1149 -#define double_starred_kvpair_type 1150 -#define kvpair_type 1151 -#define for_if_clauses_type 1152 -#define for_if_clause_type 1153 -#define listcomp_type 1154 -#define setcomp_type 1155 -#define genexp_type 1156 -#define dictcomp_type 1157 -#define arguments_type 1158 -#define args_type 1159 -#define kwargs_type 1160 -#define starred_expression_type 1161 -#define kwarg_or_starred_type 1162 -#define kwarg_or_double_starred_type 1163 -#define star_targets_type 1164 -#define star_targets_list_seq_type 1165 -#define star_targets_tuple_seq_type 1166 -#define star_target_type 1167 -#define target_with_star_atom_type 1168 -#define star_atom_type 1169 -#define single_target_type 1170 -#define single_subscript_attribute_target_type 1171 -#define t_primary_type 1172 // Left-recursive -#define t_lookahead_type 1173 -#define del_targets_type 1174 -#define del_target_type 1175 -#define del_t_atom_type 1176 -#define type_expressions_type 1177 -#define func_type_comment_type 1178 -#define invalid_arguments_type 1179 -#define invalid_kwarg_type 1180 -#define expression_without_invalid_type 1181 -#define invalid_legacy_expression_type 1182 -#define invalid_expression_type 1183 -#define invalid_named_expression_type 1184 -#define invalid_assignment_type 1185 -#define invalid_ann_assign_target_type 1186 -#define invalid_del_stmt_type 1187 -#define invalid_block_type 1188 -#define invalid_comprehension_type 1189 -#define invalid_dict_comprehension_type 1190 -#define invalid_parameters_type 1191 -#define invalid_default_type 1192 -#define invalid_star_etc_type 1193 -#define invalid_kwds_type 1194 -#define invalid_parameters_helper_type 1195 -#define invalid_lambda_parameters_type 1196 -#define invalid_lambda_parameters_helper_type 1197 -#define invalid_lambda_star_etc_type 1198 -#define invalid_lambda_kwds_type 1199 -#define invalid_double_type_comments_type 1200 -#define invalid_with_item_type 1201 -#define invalid_for_target_type 1202 -#define invalid_group_type 1203 -#define invalid_import_from_targets_type 1204 -#define invalid_with_stmt_type 1205 -#define invalid_with_stmt_indent_type 1206 -#define invalid_try_stmt_type 1207 -#define invalid_except_stmt_type 1208 -#define invalid_finally_stmt_type 1209 -#define invalid_except_stmt_indent_type 1210 -#define invalid_except_star_stmt_indent_type 1211 -#define invalid_match_stmt_type 1212 -#define invalid_case_block_type 1213 -#define invalid_as_pattern_type 1214 -#define invalid_class_pattern_type 1215 -#define invalid_class_argument_pattern_type 1216 -#define invalid_if_stmt_type 1217 -#define invalid_elif_stmt_type 1218 -#define invalid_else_stmt_type 1219 -#define invalid_while_stmt_type 1220 -#define invalid_for_stmt_type 1221 -#define invalid_def_raw_type 1222 -#define invalid_class_def_raw_type 1223 -#define invalid_double_starred_kvpairs_type 1224 -#define invalid_kvpair_type 1225 -#define _loop0_1_type 1226 -#define _loop0_2_type 1227 -#define _loop1_3_type 1228 -#define _loop0_5_type 1229 -#define _gather_4_type 1230 -#define _tmp_6_type 1231 -#define _tmp_7_type 1232 -#define _tmp_8_type 1233 -#define _tmp_9_type 1234 -#define _tmp_10_type 1235 -#define _tmp_11_type 1236 -#define _tmp_12_type 1237 -#define _tmp_13_type 1238 -#define _loop1_14_type 1239 -#define _tmp_15_type 1240 -#define _tmp_16_type 1241 -#define _tmp_17_type 1242 -#define _loop0_19_type 1243 -#define _gather_18_type 1244 -#define _loop0_21_type 1245 -#define _gather_20_type 1246 -#define _tmp_22_type 1247 -#define _tmp_23_type 1248 -#define _loop0_24_type 1249 -#define _loop1_25_type 1250 -#define _loop0_27_type 1251 -#define _gather_26_type 1252 -#define _tmp_28_type 1253 -#define _loop0_30_type 1254 -#define _gather_29_type 1255 -#define _tmp_31_type 1256 -#define _loop1_32_type 1257 -#define _tmp_33_type 1258 -#define _tmp_34_type 1259 -#define _tmp_35_type 1260 -#define _loop0_36_type 1261 -#define _loop0_37_type 1262 -#define _loop0_38_type 1263 -#define _loop1_39_type 1264 -#define _loop0_40_type 1265 -#define _loop1_41_type 1266 -#define _loop1_42_type 1267 -#define _loop1_43_type 1268 -#define _loop0_44_type 1269 -#define _loop1_45_type 1270 -#define _loop0_46_type 1271 -#define _loop1_47_type 1272 -#define _loop0_48_type 1273 -#define _loop1_49_type 1274 -#define _loop0_51_type 1275 -#define _gather_50_type 1276 -#define _loop0_53_type 1277 -#define _gather_52_type 1278 -#define _loop0_55_type 1279 -#define _gather_54_type 1280 -#define _loop0_57_type 1281 -#define _gather_56_type 1282 -#define _tmp_58_type 1283 -#define _loop1_59_type 1284 -#define _loop1_60_type 1285 -#define _tmp_61_type 1286 -#define _tmp_62_type 1287 -#define _loop1_63_type 1288 -#define _loop0_65_type 1289 -#define _gather_64_type 1290 -#define _tmp_66_type 1291 -#define _tmp_67_type 1292 -#define _tmp_68_type 1293 -#define _tmp_69_type 1294 -#define _loop0_71_type 1295 -#define _gather_70_type 1296 -#define _loop0_73_type 1297 -#define _gather_72_type 1298 -#define _tmp_74_type 1299 -#define _loop0_76_type 1300 -#define _gather_75_type 1301 -#define _loop0_78_type 1302 -#define _gather_77_type 1303 -#define _loop1_79_type 1304 -#define _loop1_80_type 1305 -#define _loop0_82_type 1306 -#define _gather_81_type 1307 -#define _loop1_83_type 1308 -#define _loop1_84_type 1309 -#define _loop1_85_type 1310 -#define _tmp_86_type 1311 -#define _loop0_88_type 1312 -#define _gather_87_type 1313 -#define _tmp_89_type 1314 -#define _tmp_90_type 1315 -#define _tmp_91_type 1316 -#define _tmp_92_type 1317 -#define _tmp_93_type 1318 -#define _loop0_94_type 1319 -#define _loop0_95_type 1320 -#define _loop0_96_type 1321 -#define _loop1_97_type 1322 -#define _loop0_98_type 1323 -#define _loop1_99_type 1324 -#define _loop1_100_type 1325 -#define _loop1_101_type 1326 -#define _loop0_102_type 1327 -#define _loop1_103_type 1328 -#define _loop0_104_type 1329 -#define _loop1_105_type 1330 -#define _loop0_106_type 1331 -#define _loop1_107_type 1332 -#define _loop1_108_type 1333 -#define _tmp_109_type 1334 -#define _loop0_111_type 1335 -#define _gather_110_type 1336 -#define _loop1_112_type 1337 -#define _loop0_113_type 1338 -#define _loop0_114_type 1339 -#define _tmp_115_type 1340 -#define _loop0_117_type 1341 -#define _gather_116_type 1342 -#define _tmp_118_type 1343 -#define _loop0_120_type 1344 -#define _gather_119_type 1345 -#define _loop0_122_type 1346 -#define _gather_121_type 1347 -#define _loop0_124_type 1348 -#define _gather_123_type 1349 -#define _loop0_126_type 1350 -#define _gather_125_type 1351 -#define _loop0_127_type 1352 -#define _loop0_129_type 1353 -#define _gather_128_type 1354 -#define _loop1_130_type 1355 -#define _tmp_131_type 1356 -#define _loop0_133_type 1357 -#define _gather_132_type 1358 -#define _loop0_135_type 1359 -#define _gather_134_type 1360 -#define _loop0_137_type 1361 -#define _gather_136_type 1362 -#define _loop0_139_type 1363 -#define _gather_138_type 1364 -#define _loop0_141_type 1365 -#define _gather_140_type 1366 -#define _tmp_142_type 1367 -#define _tmp_143_type 1368 -#define _tmp_144_type 1369 -#define _tmp_145_type 1370 -#define _tmp_146_type 1371 -#define _tmp_147_type 1372 -#define _tmp_148_type 1373 -#define _tmp_149_type 1374 -#define _tmp_150_type 1375 -#define _loop0_151_type 1376 -#define _loop0_152_type 1377 -#define _loop0_153_type 1378 -#define _tmp_154_type 1379 -#define _tmp_155_type 1380 -#define _tmp_156_type 1381 -#define _tmp_157_type 1382 -#define _loop0_158_type 1383 -#define _loop0_159_type 1384 -#define _loop1_160_type 1385 -#define _tmp_161_type 1386 -#define _loop0_162_type 1387 -#define _tmp_163_type 1388 -#define _loop0_164_type 1389 -#define _tmp_165_type 1390 -#define _loop0_166_type 1391 -#define _loop1_167_type 1392 -#define _tmp_168_type 1393 -#define _tmp_169_type 1394 -#define _tmp_170_type 1395 -#define _loop0_171_type 1396 -#define _tmp_172_type 1397 -#define _tmp_173_type 1398 -#define _loop1_174_type 1399 -#define _loop0_175_type 1400 -#define _loop0_176_type 1401 -#define _loop0_178_type 1402 -#define _gather_177_type 1403 -#define _tmp_179_type 1404 -#define _loop0_180_type 1405 -#define _tmp_181_type 1406 -#define _loop0_182_type 1407 -#define _tmp_183_type 1408 -#define _loop0_184_type 1409 -#define _loop1_185_type 1410 -#define _loop1_186_type 1411 -#define _tmp_187_type 1412 -#define _tmp_188_type 1413 -#define _loop0_189_type 1414 -#define _tmp_190_type 1415 -#define _tmp_191_type 1416 -#define _tmp_192_type 1417 -#define _loop0_194_type 1418 -#define _gather_193_type 1419 -#define _loop0_196_type 1420 -#define _gather_195_type 1421 -#define _loop0_198_type 1422 -#define _gather_197_type 1423 -#define _loop0_200_type 1424 -#define _gather_199_type 1425 -#define _tmp_201_type 1426 -#define _loop0_202_type 1427 -#define _tmp_203_type 1428 -#define _loop0_204_type 1429 -#define _tmp_205_type 1430 -#define _tmp_206_type 1431 -#define _tmp_207_type 1432 -#define _tmp_208_type 1433 -#define _tmp_209_type 1434 -#define _tmp_210_type 1435 -#define _tmp_211_type 1436 -#define _tmp_212_type 1437 -#define _loop0_214_type 1438 -#define _gather_213_type 1439 -#define _tmp_215_type 1440 -#define _tmp_216_type 1441 -#define _tmp_217_type 1442 -#define _tmp_218_type 1443 -#define _tmp_219_type 1444 -#define _tmp_220_type 1445 -#define _tmp_221_type 1446 -#define _tmp_222_type 1447 -#define _tmp_223_type 1448 -#define _tmp_224_type 1449 -#define _tmp_225_type 1450 -#define _tmp_226_type 1451 -#define _tmp_227_type 1452 -#define _tmp_228_type 1453 -#define _tmp_229_type 1454 -#define _tmp_230_type 1455 -#define _tmp_231_type 1456 -#define _tmp_232_type 1457 -#define _tmp_233_type 1458 -#define _tmp_234_type 1459 -#define _tmp_235_type 1460 -#define _tmp_236_type 1461 -#define _tmp_237_type 1462 -#define _tmp_238_type 1463 -#define _tmp_239_type 1464 -#define _tmp_240_type 1465 -#define _tmp_241_type 1466 -#define _tmp_242_type 1467 -#define _tmp_243_type 1468 -#define _loop1_244_type 1469 -#define _loop1_245_type 1470 +#define param_no_default_star_annotation_type 1043 +#define param_with_default_type 1044 +#define param_maybe_default_type 1045 +#define param_type 1046 +#define param_star_annotation_type 1047 +#define annotation_type 1048 +#define star_annotation_type 1049 +#define default_type 1050 +#define if_stmt_type 1051 +#define elif_stmt_type 1052 +#define else_block_type 1053 +#define while_stmt_type 1054 +#define for_stmt_type 1055 +#define with_stmt_type 1056 +#define with_item_type 1057 +#define try_stmt_type 1058 +#define except_block_type 1059 +#define except_star_block_type 1060 +#define finally_block_type 1061 +#define match_stmt_type 1062 +#define subject_expr_type 1063 +#define case_block_type 1064 +#define guard_type 1065 +#define patterns_type 1066 +#define pattern_type 1067 +#define as_pattern_type 1068 +#define or_pattern_type 1069 +#define closed_pattern_type 1070 +#define literal_pattern_type 1071 +#define literal_expr_type 1072 +#define complex_number_type 1073 +#define signed_number_type 1074 +#define signed_real_number_type 1075 +#define real_number_type 1076 +#define imaginary_number_type 1077 +#define capture_pattern_type 1078 +#define pattern_capture_target_type 1079 +#define wildcard_pattern_type 1080 +#define value_pattern_type 1081 +#define attr_type 1082 // Left-recursive +#define name_or_attr_type 1083 // Left-recursive +#define group_pattern_type 1084 +#define sequence_pattern_type 1085 +#define open_sequence_pattern_type 1086 +#define maybe_sequence_pattern_type 1087 +#define maybe_star_pattern_type 1088 +#define star_pattern_type 1089 +#define mapping_pattern_type 1090 +#define items_pattern_type 1091 +#define key_value_pattern_type 1092 +#define double_star_pattern_type 1093 +#define class_pattern_type 1094 +#define positional_patterns_type 1095 +#define keyword_patterns_type 1096 +#define keyword_pattern_type 1097 +#define expressions_type 1098 +#define expression_type 1099 +#define yield_expr_type 1100 +#define star_expressions_type 1101 +#define star_expression_type 1102 +#define star_named_expressions_type 1103 +#define star_named_expression_type 1104 +#define assignment_expression_type 1105 +#define named_expression_type 1106 +#define disjunction_type 1107 +#define conjunction_type 1108 +#define inversion_type 1109 +#define comparison_type 1110 +#define compare_op_bitwise_or_pair_type 1111 +#define eq_bitwise_or_type 1112 +#define noteq_bitwise_or_type 1113 +#define lte_bitwise_or_type 1114 +#define lt_bitwise_or_type 1115 +#define gte_bitwise_or_type 1116 +#define gt_bitwise_or_type 1117 +#define notin_bitwise_or_type 1118 +#define in_bitwise_or_type 1119 +#define isnot_bitwise_or_type 1120 +#define is_bitwise_or_type 1121 +#define bitwise_or_type 1122 // Left-recursive +#define bitwise_xor_type 1123 // Left-recursive +#define bitwise_and_type 1124 // Left-recursive +#define shift_expr_type 1125 // Left-recursive +#define sum_type 1126 // Left-recursive +#define term_type 1127 // Left-recursive +#define factor_type 1128 +#define power_type 1129 +#define await_primary_type 1130 +#define primary_type 1131 // Left-recursive +#define slices_type 1132 +#define slice_type 1133 +#define atom_type 1134 +#define group_type 1135 +#define lambdef_type 1136 +#define lambda_params_type 1137 +#define lambda_parameters_type 1138 +#define lambda_slash_no_default_type 1139 +#define lambda_slash_with_default_type 1140 +#define lambda_star_etc_type 1141 +#define lambda_kwds_type 1142 +#define lambda_param_no_default_type 1143 +#define lambda_param_with_default_type 1144 +#define lambda_param_maybe_default_type 1145 +#define lambda_param_type 1146 +#define strings_type 1147 +#define list_type 1148 +#define tuple_type 1149 +#define set_type 1150 +#define dict_type 1151 +#define double_starred_kvpairs_type 1152 +#define double_starred_kvpair_type 1153 +#define kvpair_type 1154 +#define for_if_clauses_type 1155 +#define for_if_clause_type 1156 +#define listcomp_type 1157 +#define setcomp_type 1158 +#define genexp_type 1159 +#define dictcomp_type 1160 +#define arguments_type 1161 +#define args_type 1162 +#define kwargs_type 1163 +#define starred_expression_type 1164 +#define kwarg_or_starred_type 1165 +#define kwarg_or_double_starred_type 1166 +#define star_targets_type 1167 +#define star_targets_list_seq_type 1168 +#define star_targets_tuple_seq_type 1169 +#define star_target_type 1170 +#define target_with_star_atom_type 1171 +#define star_atom_type 1172 +#define single_target_type 1173 +#define single_subscript_attribute_target_type 1174 +#define t_primary_type 1175 // Left-recursive +#define t_lookahead_type 1176 +#define del_targets_type 1177 +#define del_target_type 1178 +#define del_t_atom_type 1179 +#define type_expressions_type 1180 +#define func_type_comment_type 1181 +#define invalid_arguments_type 1182 +#define invalid_kwarg_type 1183 +#define expression_without_invalid_type 1184 +#define invalid_legacy_expression_type 1185 +#define invalid_expression_type 1186 +#define invalid_named_expression_type 1187 +#define invalid_assignment_type 1188 +#define invalid_ann_assign_target_type 1189 +#define invalid_del_stmt_type 1190 +#define invalid_block_type 1191 +#define invalid_comprehension_type 1192 +#define invalid_dict_comprehension_type 1193 +#define invalid_parameters_type 1194 +#define invalid_default_type 1195 +#define invalid_star_etc_type 1196 +#define invalid_kwds_type 1197 +#define invalid_parameters_helper_type 1198 +#define invalid_lambda_parameters_type 1199 +#define invalid_lambda_parameters_helper_type 1200 +#define invalid_lambda_star_etc_type 1201 +#define invalid_lambda_kwds_type 1202 +#define invalid_double_type_comments_type 1203 +#define invalid_with_item_type 1204 +#define invalid_for_target_type 1205 +#define invalid_group_type 1206 +#define invalid_import_from_targets_type 1207 +#define invalid_with_stmt_type 1208 +#define invalid_with_stmt_indent_type 1209 +#define invalid_try_stmt_type 1210 +#define invalid_except_stmt_type 1211 +#define invalid_finally_stmt_type 1212 +#define invalid_except_stmt_indent_type 1213 +#define invalid_except_star_stmt_indent_type 1214 +#define invalid_match_stmt_type 1215 +#define invalid_case_block_type 1216 +#define invalid_as_pattern_type 1217 +#define invalid_class_pattern_type 1218 +#define invalid_class_argument_pattern_type 1219 +#define invalid_if_stmt_type 1220 +#define invalid_elif_stmt_type 1221 +#define invalid_else_stmt_type 1222 +#define invalid_while_stmt_type 1223 +#define invalid_for_stmt_type 1224 +#define invalid_def_raw_type 1225 +#define invalid_class_def_raw_type 1226 +#define invalid_double_starred_kvpairs_type 1227 +#define invalid_kvpair_type 1228 +#define _loop0_1_type 1229 +#define _loop0_2_type 1230 +#define _loop1_3_type 1231 +#define _loop0_5_type 1232 +#define _gather_4_type 1233 +#define _tmp_6_type 1234 +#define _tmp_7_type 1235 +#define _tmp_8_type 1236 +#define _tmp_9_type 1237 +#define _tmp_10_type 1238 +#define _tmp_11_type 1239 +#define _tmp_12_type 1240 +#define _tmp_13_type 1241 +#define _loop1_14_type 1242 +#define _tmp_15_type 1243 +#define _tmp_16_type 1244 +#define _tmp_17_type 1245 +#define _loop0_19_type 1246 +#define _gather_18_type 1247 +#define _loop0_21_type 1248 +#define _gather_20_type 1249 +#define _tmp_22_type 1250 +#define _tmp_23_type 1251 +#define _loop0_24_type 1252 +#define _loop1_25_type 1253 +#define _loop0_27_type 1254 +#define _gather_26_type 1255 +#define _tmp_28_type 1256 +#define _loop0_30_type 1257 +#define _gather_29_type 1258 +#define _tmp_31_type 1259 +#define _loop1_32_type 1260 +#define _tmp_33_type 1261 +#define _tmp_34_type 1262 +#define _tmp_35_type 1263 +#define _loop0_36_type 1264 +#define _loop0_37_type 1265 +#define _loop0_38_type 1266 +#define _loop1_39_type 1267 +#define _loop0_40_type 1268 +#define _loop1_41_type 1269 +#define _loop1_42_type 1270 +#define _loop1_43_type 1271 +#define _loop0_44_type 1272 +#define _loop1_45_type 1273 +#define _loop0_46_type 1274 +#define _loop1_47_type 1275 +#define _loop0_48_type 1276 +#define _loop0_49_type 1277 +#define _loop1_50_type 1278 +#define _loop0_52_type 1279 +#define _gather_51_type 1280 +#define _loop0_54_type 1281 +#define _gather_53_type 1282 +#define _loop0_56_type 1283 +#define _gather_55_type 1284 +#define _loop0_58_type 1285 +#define _gather_57_type 1286 +#define _tmp_59_type 1287 +#define _loop1_60_type 1288 +#define _loop1_61_type 1289 +#define _tmp_62_type 1290 +#define _tmp_63_type 1291 +#define _loop1_64_type 1292 +#define _loop0_66_type 1293 +#define _gather_65_type 1294 +#define _tmp_67_type 1295 +#define _tmp_68_type 1296 +#define _tmp_69_type 1297 +#define _tmp_70_type 1298 +#define _loop0_72_type 1299 +#define _gather_71_type 1300 +#define _loop0_74_type 1301 +#define _gather_73_type 1302 +#define _tmp_75_type 1303 +#define _loop0_77_type 1304 +#define _gather_76_type 1305 +#define _loop0_79_type 1306 +#define _gather_78_type 1307 +#define _loop1_80_type 1308 +#define _loop1_81_type 1309 +#define _loop0_83_type 1310 +#define _gather_82_type 1311 +#define _loop1_84_type 1312 +#define _loop1_85_type 1313 +#define _loop1_86_type 1314 +#define _tmp_87_type 1315 +#define _loop0_89_type 1316 +#define _gather_88_type 1317 +#define _tmp_90_type 1318 +#define _tmp_91_type 1319 +#define _tmp_92_type 1320 +#define _tmp_93_type 1321 +#define _tmp_94_type 1322 +#define _loop0_95_type 1323 +#define _loop0_96_type 1324 +#define _loop0_97_type 1325 +#define _loop1_98_type 1326 +#define _loop0_99_type 1327 +#define _loop1_100_type 1328 +#define _loop1_101_type 1329 +#define _loop1_102_type 1330 +#define _loop0_103_type 1331 +#define _loop1_104_type 1332 +#define _loop0_105_type 1333 +#define _loop1_106_type 1334 +#define _loop0_107_type 1335 +#define _loop1_108_type 1336 +#define _loop1_109_type 1337 +#define _tmp_110_type 1338 +#define _loop0_112_type 1339 +#define _gather_111_type 1340 +#define _loop1_113_type 1341 +#define _loop0_114_type 1342 +#define _loop0_115_type 1343 +#define _tmp_116_type 1344 +#define _loop0_118_type 1345 +#define _gather_117_type 1346 +#define _tmp_119_type 1347 +#define _loop0_121_type 1348 +#define _gather_120_type 1349 +#define _loop0_123_type 1350 +#define _gather_122_type 1351 +#define _loop0_125_type 1352 +#define _gather_124_type 1353 +#define _loop0_127_type 1354 +#define _gather_126_type 1355 +#define _loop0_128_type 1356 +#define _loop0_130_type 1357 +#define _gather_129_type 1358 +#define _loop1_131_type 1359 +#define _tmp_132_type 1360 +#define _loop0_134_type 1361 +#define _gather_133_type 1362 +#define _loop0_136_type 1363 +#define _gather_135_type 1364 +#define _loop0_138_type 1365 +#define _gather_137_type 1366 +#define _loop0_140_type 1367 +#define _gather_139_type 1368 +#define _loop0_142_type 1369 +#define _gather_141_type 1370 +#define _tmp_143_type 1371 +#define _tmp_144_type 1372 +#define _tmp_145_type 1373 +#define _tmp_146_type 1374 +#define _tmp_147_type 1375 +#define _tmp_148_type 1376 +#define _tmp_149_type 1377 +#define _tmp_150_type 1378 +#define _tmp_151_type 1379 +#define _loop0_152_type 1380 +#define _loop0_153_type 1381 +#define _loop0_154_type 1382 +#define _tmp_155_type 1383 +#define _tmp_156_type 1384 +#define _tmp_157_type 1385 +#define _tmp_158_type 1386 +#define _loop0_159_type 1387 +#define _loop0_160_type 1388 +#define _loop1_161_type 1389 +#define _tmp_162_type 1390 +#define _loop0_163_type 1391 +#define _tmp_164_type 1392 +#define _loop0_165_type 1393 +#define _tmp_166_type 1394 +#define _loop0_167_type 1395 +#define _loop1_168_type 1396 +#define _tmp_169_type 1397 +#define _tmp_170_type 1398 +#define _tmp_171_type 1399 +#define _loop0_172_type 1400 +#define _tmp_173_type 1401 +#define _tmp_174_type 1402 +#define _loop1_175_type 1403 +#define _loop0_176_type 1404 +#define _loop0_177_type 1405 +#define _loop0_179_type 1406 +#define _gather_178_type 1407 +#define _tmp_180_type 1408 +#define _loop0_181_type 1409 +#define _tmp_182_type 1410 +#define _loop0_183_type 1411 +#define _tmp_184_type 1412 +#define _loop0_185_type 1413 +#define _loop1_186_type 1414 +#define _loop1_187_type 1415 +#define _tmp_188_type 1416 +#define _tmp_189_type 1417 +#define _loop0_190_type 1418 +#define _tmp_191_type 1419 +#define _tmp_192_type 1420 +#define _tmp_193_type 1421 +#define _loop0_195_type 1422 +#define _gather_194_type 1423 +#define _loop0_197_type 1424 +#define _gather_196_type 1425 +#define _loop0_199_type 1426 +#define _gather_198_type 1427 +#define _loop0_201_type 1428 +#define _gather_200_type 1429 +#define _tmp_202_type 1430 +#define _loop0_203_type 1431 +#define _tmp_204_type 1432 +#define _loop0_205_type 1433 +#define _tmp_206_type 1434 +#define _tmp_207_type 1435 +#define _tmp_208_type 1436 +#define _tmp_209_type 1437 +#define _tmp_210_type 1438 +#define _tmp_211_type 1439 +#define _tmp_212_type 1440 +#define _tmp_213_type 1441 +#define _loop0_215_type 1442 +#define _gather_214_type 1443 +#define _tmp_216_type 1444 +#define _tmp_217_type 1445 +#define _tmp_218_type 1446 +#define _tmp_219_type 1447 +#define _tmp_220_type 1448 +#define _tmp_221_type 1449 +#define _tmp_222_type 1450 +#define _tmp_223_type 1451 +#define _tmp_224_type 1452 +#define _tmp_225_type 1453 +#define _tmp_226_type 1454 +#define _tmp_227_type 1455 +#define _tmp_228_type 1456 +#define _tmp_229_type 1457 +#define _tmp_230_type 1458 +#define _tmp_231_type 1459 +#define _tmp_232_type 1460 +#define _tmp_233_type 1461 +#define _tmp_234_type 1462 +#define _tmp_235_type 1463 +#define _tmp_236_type 1464 +#define _tmp_237_type 1465 +#define _tmp_238_type 1466 +#define _tmp_239_type 1467 +#define _tmp_240_type 1468 +#define _tmp_241_type 1469 +#define _tmp_242_type 1470 +#define _tmp_243_type 1471 +#define _tmp_244_type 1472 +#define _tmp_245_type 1473 +#define _loop1_246_type 1474 +#define _loop1_247_type 1475 static mod_ty file_rule(Parser *p); static mod_ty interactive_rule(Parser *p); @@ -588,10 +593,13 @@ static SlashWithDefault* slash_with_default_rule(Parser *p); static StarEtc* star_etc_rule(Parser *p); static arg_ty kwds_rule(Parser *p); static arg_ty param_no_default_rule(Parser *p); +static arg_ty param_no_default_star_annotation_rule(Parser *p); static NameDefaultPair* param_with_default_rule(Parser *p); static NameDefaultPair* param_maybe_default_rule(Parser *p); static arg_ty param_rule(Parser *p); +static arg_ty param_star_annotation_rule(Parser *p); static expr_ty annotation_rule(Parser *p); +static expr_ty star_annotation_rule(Parser *p); static expr_ty default_rule(Parser *p); static stmt_ty if_stmt_rule(Parser *p); static stmt_ty elif_stmt_rule(Parser *p); @@ -819,100 +827,100 @@ static asdl_seq *_loop1_45_rule(Parser *p); static asdl_seq *_loop0_46_rule(Parser *p); static asdl_seq *_loop1_47_rule(Parser *p); static asdl_seq *_loop0_48_rule(Parser *p); -static asdl_seq *_loop1_49_rule(Parser *p); -static asdl_seq *_loop0_51_rule(Parser *p); -static asdl_seq *_gather_50_rule(Parser *p); -static asdl_seq *_loop0_53_rule(Parser *p); -static asdl_seq *_gather_52_rule(Parser *p); -static asdl_seq *_loop0_55_rule(Parser *p); -static asdl_seq *_gather_54_rule(Parser *p); -static asdl_seq *_loop0_57_rule(Parser *p); -static asdl_seq *_gather_56_rule(Parser *p); -static void *_tmp_58_rule(Parser *p); -static asdl_seq *_loop1_59_rule(Parser *p); +static asdl_seq *_loop0_49_rule(Parser *p); +static asdl_seq *_loop1_50_rule(Parser *p); +static asdl_seq *_loop0_52_rule(Parser *p); +static asdl_seq *_gather_51_rule(Parser *p); +static asdl_seq *_loop0_54_rule(Parser *p); +static asdl_seq *_gather_53_rule(Parser *p); +static asdl_seq *_loop0_56_rule(Parser *p); +static asdl_seq *_gather_55_rule(Parser *p); +static asdl_seq *_loop0_58_rule(Parser *p); +static asdl_seq *_gather_57_rule(Parser *p); +static void *_tmp_59_rule(Parser *p); static asdl_seq *_loop1_60_rule(Parser *p); -static void *_tmp_61_rule(Parser *p); +static asdl_seq *_loop1_61_rule(Parser *p); static void *_tmp_62_rule(Parser *p); -static asdl_seq *_loop1_63_rule(Parser *p); -static asdl_seq *_loop0_65_rule(Parser *p); -static asdl_seq *_gather_64_rule(Parser *p); -static void *_tmp_66_rule(Parser *p); +static void *_tmp_63_rule(Parser *p); +static asdl_seq *_loop1_64_rule(Parser *p); +static asdl_seq *_loop0_66_rule(Parser *p); +static asdl_seq *_gather_65_rule(Parser *p); static void *_tmp_67_rule(Parser *p); static void *_tmp_68_rule(Parser *p); static void *_tmp_69_rule(Parser *p); -static asdl_seq *_loop0_71_rule(Parser *p); -static asdl_seq *_gather_70_rule(Parser *p); -static asdl_seq *_loop0_73_rule(Parser *p); -static asdl_seq *_gather_72_rule(Parser *p); -static void *_tmp_74_rule(Parser *p); -static asdl_seq *_loop0_76_rule(Parser *p); -static asdl_seq *_gather_75_rule(Parser *p); -static asdl_seq *_loop0_78_rule(Parser *p); -static asdl_seq *_gather_77_rule(Parser *p); -static asdl_seq *_loop1_79_rule(Parser *p); +static void *_tmp_70_rule(Parser *p); +static asdl_seq *_loop0_72_rule(Parser *p); +static asdl_seq *_gather_71_rule(Parser *p); +static asdl_seq *_loop0_74_rule(Parser *p); +static asdl_seq *_gather_73_rule(Parser *p); +static void *_tmp_75_rule(Parser *p); +static asdl_seq *_loop0_77_rule(Parser *p); +static asdl_seq *_gather_76_rule(Parser *p); +static asdl_seq *_loop0_79_rule(Parser *p); +static asdl_seq *_gather_78_rule(Parser *p); static asdl_seq *_loop1_80_rule(Parser *p); -static asdl_seq *_loop0_82_rule(Parser *p); -static asdl_seq *_gather_81_rule(Parser *p); -static asdl_seq *_loop1_83_rule(Parser *p); +static asdl_seq *_loop1_81_rule(Parser *p); +static asdl_seq *_loop0_83_rule(Parser *p); +static asdl_seq *_gather_82_rule(Parser *p); static asdl_seq *_loop1_84_rule(Parser *p); static asdl_seq *_loop1_85_rule(Parser *p); -static void *_tmp_86_rule(Parser *p); -static asdl_seq *_loop0_88_rule(Parser *p); -static asdl_seq *_gather_87_rule(Parser *p); -static void *_tmp_89_rule(Parser *p); +static asdl_seq *_loop1_86_rule(Parser *p); +static void *_tmp_87_rule(Parser *p); +static asdl_seq *_loop0_89_rule(Parser *p); +static asdl_seq *_gather_88_rule(Parser *p); static void *_tmp_90_rule(Parser *p); static void *_tmp_91_rule(Parser *p); static void *_tmp_92_rule(Parser *p); static void *_tmp_93_rule(Parser *p); -static asdl_seq *_loop0_94_rule(Parser *p); +static void *_tmp_94_rule(Parser *p); static asdl_seq *_loop0_95_rule(Parser *p); static asdl_seq *_loop0_96_rule(Parser *p); -static asdl_seq *_loop1_97_rule(Parser *p); -static asdl_seq *_loop0_98_rule(Parser *p); -static asdl_seq *_loop1_99_rule(Parser *p); +static asdl_seq *_loop0_97_rule(Parser *p); +static asdl_seq *_loop1_98_rule(Parser *p); +static asdl_seq *_loop0_99_rule(Parser *p); static asdl_seq *_loop1_100_rule(Parser *p); static asdl_seq *_loop1_101_rule(Parser *p); -static asdl_seq *_loop0_102_rule(Parser *p); -static asdl_seq *_loop1_103_rule(Parser *p); -static asdl_seq *_loop0_104_rule(Parser *p); -static asdl_seq *_loop1_105_rule(Parser *p); -static asdl_seq *_loop0_106_rule(Parser *p); -static asdl_seq *_loop1_107_rule(Parser *p); +static asdl_seq *_loop1_102_rule(Parser *p); +static asdl_seq *_loop0_103_rule(Parser *p); +static asdl_seq *_loop1_104_rule(Parser *p); +static asdl_seq *_loop0_105_rule(Parser *p); +static asdl_seq *_loop1_106_rule(Parser *p); +static asdl_seq *_loop0_107_rule(Parser *p); static asdl_seq *_loop1_108_rule(Parser *p); -static void *_tmp_109_rule(Parser *p); -static asdl_seq *_loop0_111_rule(Parser *p); -static asdl_seq *_gather_110_rule(Parser *p); -static asdl_seq *_loop1_112_rule(Parser *p); -static asdl_seq *_loop0_113_rule(Parser *p); +static asdl_seq *_loop1_109_rule(Parser *p); +static void *_tmp_110_rule(Parser *p); +static asdl_seq *_loop0_112_rule(Parser *p); +static asdl_seq *_gather_111_rule(Parser *p); +static asdl_seq *_loop1_113_rule(Parser *p); static asdl_seq *_loop0_114_rule(Parser *p); -static void *_tmp_115_rule(Parser *p); -static asdl_seq *_loop0_117_rule(Parser *p); -static asdl_seq *_gather_116_rule(Parser *p); -static void *_tmp_118_rule(Parser *p); -static asdl_seq *_loop0_120_rule(Parser *p); -static asdl_seq *_gather_119_rule(Parser *p); -static asdl_seq *_loop0_122_rule(Parser *p); -static asdl_seq *_gather_121_rule(Parser *p); -static asdl_seq *_loop0_124_rule(Parser *p); -static asdl_seq *_gather_123_rule(Parser *p); -static asdl_seq *_loop0_126_rule(Parser *p); -static asdl_seq *_gather_125_rule(Parser *p); +static asdl_seq *_loop0_115_rule(Parser *p); +static void *_tmp_116_rule(Parser *p); +static asdl_seq *_loop0_118_rule(Parser *p); +static asdl_seq *_gather_117_rule(Parser *p); +static void *_tmp_119_rule(Parser *p); +static asdl_seq *_loop0_121_rule(Parser *p); +static asdl_seq *_gather_120_rule(Parser *p); +static asdl_seq *_loop0_123_rule(Parser *p); +static asdl_seq *_gather_122_rule(Parser *p); +static asdl_seq *_loop0_125_rule(Parser *p); +static asdl_seq *_gather_124_rule(Parser *p); static asdl_seq *_loop0_127_rule(Parser *p); -static asdl_seq *_loop0_129_rule(Parser *p); -static asdl_seq *_gather_128_rule(Parser *p); -static asdl_seq *_loop1_130_rule(Parser *p); -static void *_tmp_131_rule(Parser *p); -static asdl_seq *_loop0_133_rule(Parser *p); -static asdl_seq *_gather_132_rule(Parser *p); -static asdl_seq *_loop0_135_rule(Parser *p); -static asdl_seq *_gather_134_rule(Parser *p); -static asdl_seq *_loop0_137_rule(Parser *p); -static asdl_seq *_gather_136_rule(Parser *p); -static asdl_seq *_loop0_139_rule(Parser *p); -static asdl_seq *_gather_138_rule(Parser *p); -static asdl_seq *_loop0_141_rule(Parser *p); -static asdl_seq *_gather_140_rule(Parser *p); -static void *_tmp_142_rule(Parser *p); +static asdl_seq *_gather_126_rule(Parser *p); +static asdl_seq *_loop0_128_rule(Parser *p); +static asdl_seq *_loop0_130_rule(Parser *p); +static asdl_seq *_gather_129_rule(Parser *p); +static asdl_seq *_loop1_131_rule(Parser *p); +static void *_tmp_132_rule(Parser *p); +static asdl_seq *_loop0_134_rule(Parser *p); +static asdl_seq *_gather_133_rule(Parser *p); +static asdl_seq *_loop0_136_rule(Parser *p); +static asdl_seq *_gather_135_rule(Parser *p); +static asdl_seq *_loop0_138_rule(Parser *p); +static asdl_seq *_gather_137_rule(Parser *p); +static asdl_seq *_loop0_140_rule(Parser *p); +static asdl_seq *_gather_139_rule(Parser *p); +static asdl_seq *_loop0_142_rule(Parser *p); +static asdl_seq *_gather_141_rule(Parser *p); static void *_tmp_143_rule(Parser *p); static void *_tmp_144_rule(Parser *p); static void *_tmp_145_rule(Parser *p); @@ -921,61 +929,61 @@ static void *_tmp_147_rule(Parser *p); static void *_tmp_148_rule(Parser *p); static void *_tmp_149_rule(Parser *p); static void *_tmp_150_rule(Parser *p); -static asdl_seq *_loop0_151_rule(Parser *p); +static void *_tmp_151_rule(Parser *p); static asdl_seq *_loop0_152_rule(Parser *p); static asdl_seq *_loop0_153_rule(Parser *p); -static void *_tmp_154_rule(Parser *p); +static asdl_seq *_loop0_154_rule(Parser *p); static void *_tmp_155_rule(Parser *p); static void *_tmp_156_rule(Parser *p); static void *_tmp_157_rule(Parser *p); -static asdl_seq *_loop0_158_rule(Parser *p); +static void *_tmp_158_rule(Parser *p); static asdl_seq *_loop0_159_rule(Parser *p); -static asdl_seq *_loop1_160_rule(Parser *p); -static void *_tmp_161_rule(Parser *p); -static asdl_seq *_loop0_162_rule(Parser *p); -static void *_tmp_163_rule(Parser *p); -static asdl_seq *_loop0_164_rule(Parser *p); -static void *_tmp_165_rule(Parser *p); -static asdl_seq *_loop0_166_rule(Parser *p); -static asdl_seq *_loop1_167_rule(Parser *p); -static void *_tmp_168_rule(Parser *p); +static asdl_seq *_loop0_160_rule(Parser *p); +static asdl_seq *_loop1_161_rule(Parser *p); +static void *_tmp_162_rule(Parser *p); +static asdl_seq *_loop0_163_rule(Parser *p); +static void *_tmp_164_rule(Parser *p); +static asdl_seq *_loop0_165_rule(Parser *p); +static void *_tmp_166_rule(Parser *p); +static asdl_seq *_loop0_167_rule(Parser *p); +static asdl_seq *_loop1_168_rule(Parser *p); static void *_tmp_169_rule(Parser *p); static void *_tmp_170_rule(Parser *p); -static asdl_seq *_loop0_171_rule(Parser *p); -static void *_tmp_172_rule(Parser *p); +static void *_tmp_171_rule(Parser *p); +static asdl_seq *_loop0_172_rule(Parser *p); static void *_tmp_173_rule(Parser *p); -static asdl_seq *_loop1_174_rule(Parser *p); -static asdl_seq *_loop0_175_rule(Parser *p); +static void *_tmp_174_rule(Parser *p); +static asdl_seq *_loop1_175_rule(Parser *p); static asdl_seq *_loop0_176_rule(Parser *p); -static asdl_seq *_loop0_178_rule(Parser *p); -static asdl_seq *_gather_177_rule(Parser *p); -static void *_tmp_179_rule(Parser *p); -static asdl_seq *_loop0_180_rule(Parser *p); -static void *_tmp_181_rule(Parser *p); -static asdl_seq *_loop0_182_rule(Parser *p); -static void *_tmp_183_rule(Parser *p); -static asdl_seq *_loop0_184_rule(Parser *p); -static asdl_seq *_loop1_185_rule(Parser *p); +static asdl_seq *_loop0_177_rule(Parser *p); +static asdl_seq *_loop0_179_rule(Parser *p); +static asdl_seq *_gather_178_rule(Parser *p); +static void *_tmp_180_rule(Parser *p); +static asdl_seq *_loop0_181_rule(Parser *p); +static void *_tmp_182_rule(Parser *p); +static asdl_seq *_loop0_183_rule(Parser *p); +static void *_tmp_184_rule(Parser *p); +static asdl_seq *_loop0_185_rule(Parser *p); static asdl_seq *_loop1_186_rule(Parser *p); -static void *_tmp_187_rule(Parser *p); +static asdl_seq *_loop1_187_rule(Parser *p); static void *_tmp_188_rule(Parser *p); -static asdl_seq *_loop0_189_rule(Parser *p); -static void *_tmp_190_rule(Parser *p); +static void *_tmp_189_rule(Parser *p); +static asdl_seq *_loop0_190_rule(Parser *p); static void *_tmp_191_rule(Parser *p); static void *_tmp_192_rule(Parser *p); -static asdl_seq *_loop0_194_rule(Parser *p); -static asdl_seq *_gather_193_rule(Parser *p); -static asdl_seq *_loop0_196_rule(Parser *p); -static asdl_seq *_gather_195_rule(Parser *p); -static asdl_seq *_loop0_198_rule(Parser *p); -static asdl_seq *_gather_197_rule(Parser *p); -static asdl_seq *_loop0_200_rule(Parser *p); -static asdl_seq *_gather_199_rule(Parser *p); -static void *_tmp_201_rule(Parser *p); -static asdl_seq *_loop0_202_rule(Parser *p); -static void *_tmp_203_rule(Parser *p); -static asdl_seq *_loop0_204_rule(Parser *p); -static void *_tmp_205_rule(Parser *p); +static void *_tmp_193_rule(Parser *p); +static asdl_seq *_loop0_195_rule(Parser *p); +static asdl_seq *_gather_194_rule(Parser *p); +static asdl_seq *_loop0_197_rule(Parser *p); +static asdl_seq *_gather_196_rule(Parser *p); +static asdl_seq *_loop0_199_rule(Parser *p); +static asdl_seq *_gather_198_rule(Parser *p); +static asdl_seq *_loop0_201_rule(Parser *p); +static asdl_seq *_gather_200_rule(Parser *p); +static void *_tmp_202_rule(Parser *p); +static asdl_seq *_loop0_203_rule(Parser *p); +static void *_tmp_204_rule(Parser *p); +static asdl_seq *_loop0_205_rule(Parser *p); static void *_tmp_206_rule(Parser *p); static void *_tmp_207_rule(Parser *p); static void *_tmp_208_rule(Parser *p); @@ -983,9 +991,9 @@ static void *_tmp_209_rule(Parser *p); static void *_tmp_210_rule(Parser *p); static void *_tmp_211_rule(Parser *p); static void *_tmp_212_rule(Parser *p); -static asdl_seq *_loop0_214_rule(Parser *p); -static asdl_seq *_gather_213_rule(Parser *p); -static void *_tmp_215_rule(Parser *p); +static void *_tmp_213_rule(Parser *p); +static asdl_seq *_loop0_215_rule(Parser *p); +static asdl_seq *_gather_214_rule(Parser *p); static void *_tmp_216_rule(Parser *p); static void *_tmp_217_rule(Parser *p); static void *_tmp_218_rule(Parser *p); @@ -1014,8 +1022,10 @@ static void *_tmp_240_rule(Parser *p); static void *_tmp_241_rule(Parser *p); static void *_tmp_242_rule(Parser *p); static void *_tmp_243_rule(Parser *p); -static asdl_seq *_loop1_244_rule(Parser *p); -static asdl_seq *_loop1_245_rule(Parser *p); +static void *_tmp_244_rule(Parser *p); +static void *_tmp_245_rule(Parser *p); +static asdl_seq *_loop1_246_rule(Parser *p); +static asdl_seq *_loop1_247_rule(Parser *p); // file: statements? $ @@ -4917,6 +4927,7 @@ slash_with_default_rule(Parser *p) // star_etc: // | invalid_star_etc // | '*' param_no_default param_maybe_default* kwds? +// | '*' param_no_default_star_annotation param_maybe_default* kwds? // | '*' ',' param_maybe_default+ kwds? // | kwds static StarEtc* @@ -4984,6 +4995,39 @@ star_etc_rule(Parser *p) D(fprintf(stderr, "%*c%s star_etc[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' param_no_default param_maybe_default* kwds?")); } + { // '*' param_no_default_star_annotation param_maybe_default* kwds? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' param_no_default_star_annotation param_maybe_default* kwds?")); + Token * _literal; + arg_ty a; + asdl_seq * b; + void *c; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (a = param_no_default_star_annotation_rule(p)) // param_no_default_star_annotation + && + (b = _loop0_49_rule(p)) // param_maybe_default* + && + (c = kwds_rule(p), !p->error_indicator) // kwds? + ) + { + D(fprintf(stderr, "%*c+ star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' param_no_default_star_annotation param_maybe_default* kwds?")); + _res = _PyPegen_star_etc ( p , a , b , c ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s star_etc[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' param_no_default_star_annotation param_maybe_default* kwds?")); + } { // '*' ',' param_maybe_default+ kwds? if (p->error_indicator) { p->level--; @@ -4999,7 +5043,7 @@ star_etc_rule(Parser *p) && (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' && - (b = _loop1_49_rule(p)) // param_maybe_default+ + (b = _loop1_50_rule(p)) // param_maybe_default+ && (c = kwds_rule(p), !p->error_indicator) // kwds? ) @@ -5192,6 +5236,87 @@ param_no_default_rule(Parser *p) return _res; } +// param_no_default_star_annotation: +// | param_star_annotation ',' TYPE_COMMENT? +// | param_star_annotation TYPE_COMMENT? &')' +static arg_ty +param_no_default_star_annotation_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + arg_ty _res = NULL; + int _mark = p->mark; + { // param_star_annotation ',' TYPE_COMMENT? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> param_no_default_star_annotation[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_star_annotation ',' TYPE_COMMENT?")); + Token * _literal; + arg_ty a; + void *tc; + if ( + (a = param_star_annotation_rule(p)) // param_star_annotation + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? + ) + { + D(fprintf(stderr, "%*c+ param_no_default_star_annotation[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_star_annotation ',' TYPE_COMMENT?")); + _res = _PyPegen_add_type_comment_to_arg ( p , a , tc ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s param_no_default_star_annotation[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_star_annotation ',' TYPE_COMMENT?")); + } + { // param_star_annotation TYPE_COMMENT? &')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> param_no_default_star_annotation[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_star_annotation TYPE_COMMENT? &')'")); + arg_ty a; + void *tc; + if ( + (a = param_star_annotation_rule(p)) // param_star_annotation + && + (tc = _PyPegen_expect_token(p, TYPE_COMMENT), !p->error_indicator) // TYPE_COMMENT? + && + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 8) // token=')' + ) + { + D(fprintf(stderr, "%*c+ param_no_default_star_annotation[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_star_annotation TYPE_COMMENT? &')'")); + _res = _PyPegen_add_type_comment_to_arg ( p , a , tc ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s param_no_default_star_annotation[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_star_annotation TYPE_COMMENT? &')'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + // param_with_default: param default ',' TYPE_COMMENT? | param default TYPE_COMMENT? &')' static NameDefaultPair* param_with_default_rule(Parser *p) @@ -5429,6 +5554,71 @@ param_rule(Parser *p) return _res; } +// param_star_annotation: NAME star_annotation +static arg_ty +param_star_annotation_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + arg_ty _res = NULL; + int _mark = p->mark; + if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { + p->error_indicator = 1; + p->level--; + return NULL; + } + int _start_lineno = p->tokens[_mark]->lineno; + UNUSED(_start_lineno); // Only used by EXTRA macro + int _start_col_offset = p->tokens[_mark]->col_offset; + UNUSED(_start_col_offset); // Only used by EXTRA macro + { // NAME star_annotation + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> param_star_annotation[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME star_annotation")); + expr_ty a; + expr_ty b; + if ( + (a = _PyPegen_name_token(p)) // NAME + && + (b = star_annotation_rule(p)) // star_annotation + ) + { + D(fprintf(stderr, "%*c+ param_star_annotation[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME star_annotation")); + Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); + if (_token == NULL) { + p->level--; + return NULL; + } + int _end_lineno = _token->end_lineno; + UNUSED(_end_lineno); // Only used by EXTRA macro + int _end_col_offset = _token->end_col_offset; + UNUSED(_end_col_offset); // Only used by EXTRA macro + _res = _PyAST_arg ( a -> v . Name . id , b , NULL , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s param_star_annotation[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME star_annotation")); + } + _res = NULL; + done: + p->level--; + return _res; +} + // annotation: ':' expression static expr_ty annotation_rule(Parser *p) @@ -5476,6 +5666,53 @@ annotation_rule(Parser *p) return _res; } +// star_annotation: ':' star_expression +static expr_ty +star_annotation_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + int _mark = p->mark; + { // ':' star_expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> star_annotation[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':' star_expression")); + Token * _literal; + expr_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (a = star_expression_rule(p)) // star_expression + ) + { + D(fprintf(stderr, "%*c+ star_annotation[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':' star_expression")); + _res = a; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s star_annotation[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':' star_expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + // default: '=' expression | invalid_default static expr_ty default_rule(Parser *p) @@ -6249,7 +6486,7 @@ with_stmt_rule(Parser *p) && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (a = (asdl_withitem_seq*)_gather_50_rule(p)) // ','.with_item+ + (a = (asdl_withitem_seq*)_gather_51_rule(p)) // ','.with_item+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -6296,7 +6533,7 @@ with_stmt_rule(Parser *p) if ( (_keyword = _PyPegen_expect_token(p, 612)) // token='with' && - (a = (asdl_withitem_seq*)_gather_52_rule(p)) // ','.with_item+ + (a = (asdl_withitem_seq*)_gather_53_rule(p)) // ','.with_item+ && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -6349,7 +6586,7 @@ with_stmt_rule(Parser *p) && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (a = (asdl_withitem_seq*)_gather_54_rule(p)) // ','.with_item+ + (a = (asdl_withitem_seq*)_gather_55_rule(p)) // ','.with_item+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -6399,7 +6636,7 @@ with_stmt_rule(Parser *p) && (_keyword = _PyPegen_expect_token(p, 612)) // token='with' && - (a = (asdl_withitem_seq*)_gather_56_rule(p)) // ','.with_item+ + (a = (asdl_withitem_seq*)_gather_57_rule(p)) // ','.with_item+ && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -6488,7 +6725,7 @@ with_item_rule(Parser *p) && (t = star_target_rule(p)) // star_target && - _PyPegen_lookahead(1, _tmp_58_rule, p) + _PyPegen_lookahead(1, _tmp_59_rule, p) ) { D(fprintf(stderr, "%*c+ with_item[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression 'as' star_target &(',' | ')' | ':')")); @@ -6660,7 +6897,7 @@ try_stmt_rule(Parser *p) && (b = block_rule(p)) // block && - (ex = (asdl_excepthandler_seq*)_loop1_59_rule(p)) // except_block+ + (ex = (asdl_excepthandler_seq*)_loop1_60_rule(p)) // except_block+ && (el = else_block_rule(p), !p->error_indicator) // else_block? && @@ -6708,7 +6945,7 @@ try_stmt_rule(Parser *p) && (b = block_rule(p)) // block && - (ex = (asdl_excepthandler_seq*)_loop1_60_rule(p)) // except_star_block+ + (ex = (asdl_excepthandler_seq*)_loop1_61_rule(p)) // except_star_block+ && (el = else_block_rule(p), !p->error_indicator) // else_block? && @@ -6805,7 +7042,7 @@ except_block_rule(Parser *p) && (e = expression_rule(p)) // expression && - (t = _tmp_61_rule(p), !p->error_indicator) // ['as' NAME] + (t = _tmp_62_rule(p), !p->error_indicator) // ['as' NAME] && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -6962,7 +7199,7 @@ except_star_block_rule(Parser *p) && (e = expression_rule(p)) // expression && - (t = _tmp_62_rule(p), !p->error_indicator) // ['as' NAME] + (t = _tmp_63_rule(p), !p->error_indicator) // ['as' NAME] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' && @@ -7134,7 +7371,7 @@ match_stmt_rule(Parser *p) && (indent_var = _PyPegen_expect_token(p, INDENT)) // token='INDENT' && - (cases = (asdl_match_case_seq*)_loop1_63_rule(p)) // case_block+ + (cases = (asdl_match_case_seq*)_loop1_64_rule(p)) // case_block+ && (dedent_var = _PyPegen_expect_token(p, DEDENT)) // token='DEDENT' ) @@ -7652,7 +7889,7 @@ or_pattern_rule(Parser *p) D(fprintf(stderr, "%*c> or_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'|'.closed_pattern+")); asdl_pattern_seq* patterns; if ( - (patterns = (asdl_pattern_seq*)_gather_64_rule(p)) // '|'.closed_pattern+ + (patterns = (asdl_pattern_seq*)_gather_65_rule(p)) // '|'.closed_pattern+ ) { D(fprintf(stderr, "%*c+ or_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'|'.closed_pattern+")); @@ -7902,7 +8139,7 @@ literal_pattern_rule(Parser *p) if ( (value = signed_number_rule(p)) // signed_number && - _PyPegen_lookahead(0, _tmp_66_rule, p) + _PyPegen_lookahead(0, _tmp_67_rule, p) ) { D(fprintf(stderr, "%*c+ literal_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "signed_number !('+' | '-')")); @@ -8137,7 +8374,7 @@ literal_expr_rule(Parser *p) if ( (signed_number_var = signed_number_rule(p)) // signed_number && - _PyPegen_lookahead(0, _tmp_67_rule, p) + _PyPegen_lookahead(0, _tmp_68_rule, p) ) { D(fprintf(stderr, "%*c+ literal_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "signed_number !('+' | '-')")); @@ -8744,7 +8981,7 @@ pattern_capture_target_rule(Parser *p) && (name = _PyPegen_name_token(p)) // NAME && - _PyPegen_lookahead(0, _tmp_68_rule, p) + _PyPegen_lookahead(0, _tmp_69_rule, p) ) { D(fprintf(stderr, "%*c+ pattern_capture_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!\"_\" NAME !('.' | '(' | '=')")); @@ -8861,7 +9098,7 @@ value_pattern_rule(Parser *p) if ( (attr = attr_rule(p)) // attr && - _PyPegen_lookahead(0, _tmp_69_rule, p) + _PyPegen_lookahead(0, _tmp_70_rule, p) ) { D(fprintf(stderr, "%*c+ value_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "attr !('.' | '(' | '=')")); @@ -9287,7 +9524,7 @@ maybe_sequence_pattern_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings asdl_seq * patterns; if ( - (patterns = _gather_70_rule(p)) // ','.maybe_star_pattern+ + (patterns = _gather_71_rule(p)) // ','.maybe_star_pattern+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -9694,13 +9931,13 @@ items_pattern_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> items_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.key_value_pattern+")); - asdl_seq * _gather_72_var; + asdl_seq * _gather_73_var; if ( - (_gather_72_var = _gather_72_rule(p)) // ','.key_value_pattern+ + (_gather_73_var = _gather_73_rule(p)) // ','.key_value_pattern+ ) { D(fprintf(stderr, "%*c+ items_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.key_value_pattern+")); - _res = _gather_72_var; + _res = _gather_73_var; goto done; } p->mark = _mark; @@ -9737,7 +9974,7 @@ key_value_pattern_rule(Parser *p) void *key; pattern_ty pattern; if ( - (key = _tmp_74_rule(p)) // literal_expr | attr + (key = _tmp_75_rule(p)) // literal_expr | attr && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -10068,7 +10305,7 @@ positional_patterns_rule(Parser *p) D(fprintf(stderr, "%*c> positional_patterns[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.pattern+")); asdl_pattern_seq* args; if ( - (args = (asdl_pattern_seq*)_gather_75_rule(p)) // ','.pattern+ + (args = (asdl_pattern_seq*)_gather_76_rule(p)) // ','.pattern+ ) { D(fprintf(stderr, "%*c+ positional_patterns[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.pattern+")); @@ -10110,13 +10347,13 @@ keyword_patterns_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> keyword_patterns[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.keyword_pattern+")); - asdl_seq * _gather_77_var; + asdl_seq * _gather_78_var; if ( - (_gather_77_var = _gather_77_rule(p)) // ','.keyword_pattern+ + (_gather_78_var = _gather_78_rule(p)) // ','.keyword_pattern+ ) { D(fprintf(stderr, "%*c+ keyword_patterns[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.keyword_pattern+")); - _res = _gather_77_var; + _res = _gather_78_var; goto done; } p->mark = _mark; @@ -10215,7 +10452,7 @@ expressions_rule(Parser *p) if ( (a = expression_rule(p)) // expression && - (b = _loop1_79_rule(p)) // ((',' expression))+ + (b = _loop1_80_rule(p)) // ((',' expression))+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -10606,7 +10843,7 @@ star_expressions_rule(Parser *p) if ( (a = star_expression_rule(p)) // star_expression && - (b = _loop1_80_rule(p)) // ((',' star_expression))+ + (b = _loop1_81_rule(p)) // ((',' star_expression))+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -10807,7 +11044,7 @@ star_named_expressions_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings asdl_expr_seq* a; if ( - (a = (asdl_expr_seq*)_gather_81_rule(p)) // ','.star_named_expression+ + (a = (asdl_expr_seq*)_gather_82_rule(p)) // ','.star_named_expression+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -11107,7 +11344,7 @@ disjunction_rule(Parser *p) if ( (a = conjunction_rule(p)) // conjunction && - (b = _loop1_83_rule(p)) // (('or' conjunction))+ + (b = _loop1_84_rule(p)) // (('or' conjunction))+ ) { D(fprintf(stderr, "%*c+ disjunction[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "conjunction (('or' conjunction))+")); @@ -11196,7 +11433,7 @@ conjunction_rule(Parser *p) if ( (a = inversion_rule(p)) // inversion && - (b = _loop1_84_rule(p)) // (('and' inversion))+ + (b = _loop1_85_rule(p)) // (('and' inversion))+ ) { D(fprintf(stderr, "%*c+ conjunction[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "inversion (('and' inversion))+")); @@ -11370,7 +11607,7 @@ comparison_rule(Parser *p) if ( (a = bitwise_or_rule(p)) // bitwise_or && - (b = _loop1_85_rule(p)) // compare_op_bitwise_or_pair+ + (b = _loop1_86_rule(p)) // compare_op_bitwise_or_pair+ ) { D(fprintf(stderr, "%*c+ comparison[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "bitwise_or compare_op_bitwise_or_pair+")); @@ -11707,10 +11944,10 @@ noteq_bitwise_or_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> noteq_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('!=') bitwise_or")); - void *_tmp_86_var; + void *_tmp_87_var; expr_ty a; if ( - (_tmp_86_var = _tmp_86_rule(p)) // '!=' + (_tmp_87_var = _tmp_87_rule(p)) // '!=' && (a = bitwise_or_rule(p)) // bitwise_or ) @@ -13686,7 +13923,7 @@ primary_raw(Parser *p) return _res; } -// slices: slice !',' | ','.slice+ ','? +// slices: slice !',' | ','.(slice | starred_expression)+ ','? static expr_ty slices_rule(Parser *p) { @@ -13735,22 +13972,22 @@ slices_rule(Parser *p) D(fprintf(stderr, "%*c%s slices[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slice !','")); } - { // ','.slice+ ','? + { // ','.(slice | starred_expression)+ ','? if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> slices[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.slice+ ','?")); + D(fprintf(stderr, "%*c> slices[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.(slice | starred_expression)+ ','?")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings asdl_expr_seq* a; if ( - (a = (asdl_expr_seq*)_gather_87_rule(p)) // ','.slice+ + (a = (asdl_expr_seq*)_gather_88_rule(p)) // ','.(slice | starred_expression)+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) { - D(fprintf(stderr, "%*c+ slices[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.slice+ ','?")); + D(fprintf(stderr, "%*c+ slices[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.(slice | starred_expression)+ ','?")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { p->level--; @@ -13770,7 +14007,7 @@ slices_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s slices[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.slice+ ','?")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.(slice | starred_expression)+ ','?")); } _res = NULL; done: @@ -13818,7 +14055,7 @@ slice_rule(Parser *p) && (b = expression_rule(p), !p->error_indicator) // expression? && - (c = _tmp_89_rule(p), !p->error_indicator) // [':' expression?] + (c = _tmp_90_rule(p), !p->error_indicator) // [':' expression?] ) { D(fprintf(stderr, "%*c+ slice[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression? ':' expression? [':' expression?]")); @@ -14070,15 +14307,15 @@ atom_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'(' (tuple | group | genexp)")); - void *_tmp_90_var; + void *_tmp_91_var; if ( _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 7) // token='(' && - (_tmp_90_var = _tmp_90_rule(p)) // tuple | group | genexp + (_tmp_91_var = _tmp_91_rule(p)) // tuple | group | genexp ) { D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'(' (tuple | group | genexp)")); - _res = _tmp_90_var; + _res = _tmp_91_var; goto done; } p->mark = _mark; @@ -14091,15 +14328,15 @@ atom_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'[' (list | listcomp)")); - void *_tmp_91_var; + void *_tmp_92_var; if ( _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 9) // token='[' && - (_tmp_91_var = _tmp_91_rule(p)) // list | listcomp + (_tmp_92_var = _tmp_92_rule(p)) // list | listcomp ) { D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'[' (list | listcomp)")); - _res = _tmp_91_var; + _res = _tmp_92_var; goto done; } p->mark = _mark; @@ -14112,15 +14349,15 @@ atom_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'{' (dict | set | dictcomp | setcomp)")); - void *_tmp_92_var; + void *_tmp_93_var; if ( _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 25) // token='{' && - (_tmp_92_var = _tmp_92_rule(p)) // dict | set | dictcomp | setcomp + (_tmp_93_var = _tmp_93_rule(p)) // dict | set | dictcomp | setcomp ) { D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'{' (dict | set | dictcomp | setcomp)")); - _res = _tmp_92_var; + _res = _tmp_93_var; goto done; } p->mark = _mark; @@ -14192,7 +14429,7 @@ group_rule(Parser *p) if ( (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (a = _tmp_93_rule(p)) // yield_expr | named_expression + (a = _tmp_94_rule(p)) // yield_expr | named_expression && (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' ) @@ -14396,9 +14633,9 @@ lambda_parameters_rule(Parser *p) if ( (a = lambda_slash_no_default_rule(p)) // lambda_slash_no_default && - (b = (asdl_arg_seq*)_loop0_94_rule(p)) // lambda_param_no_default* + (b = (asdl_arg_seq*)_loop0_95_rule(p)) // lambda_param_no_default* && - (c = _loop0_95_rule(p)) // lambda_param_with_default* + (c = _loop0_96_rule(p)) // lambda_param_with_default* && (d = lambda_star_etc_rule(p), !p->error_indicator) // lambda_star_etc? ) @@ -14428,7 +14665,7 @@ lambda_parameters_rule(Parser *p) if ( (a = lambda_slash_with_default_rule(p)) // lambda_slash_with_default && - (b = _loop0_96_rule(p)) // lambda_param_with_default* + (b = _loop0_97_rule(p)) // lambda_param_with_default* && (c = lambda_star_etc_rule(p), !p->error_indicator) // lambda_star_etc? ) @@ -14456,9 +14693,9 @@ lambda_parameters_rule(Parser *p) asdl_seq * b; void *c; if ( - (a = (asdl_arg_seq*)_loop1_97_rule(p)) // lambda_param_no_default+ + (a = (asdl_arg_seq*)_loop1_98_rule(p)) // lambda_param_no_default+ && - (b = _loop0_98_rule(p)) // lambda_param_with_default* + (b = _loop0_99_rule(p)) // lambda_param_with_default* && (c = lambda_star_etc_rule(p), !p->error_indicator) // lambda_star_etc? ) @@ -14485,7 +14722,7 @@ lambda_parameters_rule(Parser *p) asdl_seq * a; void *b; if ( - (a = _loop1_99_rule(p)) // lambda_param_with_default+ + (a = _loop1_100_rule(p)) // lambda_param_with_default+ && (b = lambda_star_etc_rule(p), !p->error_indicator) // lambda_star_etc? ) @@ -14559,7 +14796,7 @@ lambda_slash_no_default_rule(Parser *p) Token * _literal_1; asdl_arg_seq* a; if ( - (a = (asdl_arg_seq*)_loop1_100_rule(p)) // lambda_param_no_default+ + (a = (asdl_arg_seq*)_loop1_101_rule(p)) // lambda_param_no_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -14588,7 +14825,7 @@ lambda_slash_no_default_rule(Parser *p) Token * _literal; asdl_arg_seq* a; if ( - (a = (asdl_arg_seq*)_loop1_101_rule(p)) // lambda_param_no_default+ + (a = (asdl_arg_seq*)_loop1_102_rule(p)) // lambda_param_no_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -14641,9 +14878,9 @@ lambda_slash_with_default_rule(Parser *p) asdl_seq * a; asdl_seq * b; if ( - (a = _loop0_102_rule(p)) // lambda_param_no_default* + (a = _loop0_103_rule(p)) // lambda_param_no_default* && - (b = _loop1_103_rule(p)) // lambda_param_with_default+ + (b = _loop1_104_rule(p)) // lambda_param_with_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -14673,9 +14910,9 @@ lambda_slash_with_default_rule(Parser *p) asdl_seq * a; asdl_seq * b; if ( - (a = _loop0_104_rule(p)) // lambda_param_no_default* + (a = _loop0_105_rule(p)) // lambda_param_no_default* && - (b = _loop1_105_rule(p)) // lambda_param_with_default+ + (b = _loop1_106_rule(p)) // lambda_param_with_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -14753,7 +14990,7 @@ lambda_star_etc_rule(Parser *p) && (a = lambda_param_no_default_rule(p)) // lambda_param_no_default && - (b = _loop0_106_rule(p)) // lambda_param_maybe_default* + (b = _loop0_107_rule(p)) // lambda_param_maybe_default* && (c = lambda_kwds_rule(p), !p->error_indicator) // lambda_kwds? ) @@ -14786,7 +15023,7 @@ lambda_star_etc_rule(Parser *p) && (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' && - (b = _loop1_107_rule(p)) // lambda_param_maybe_default+ + (b = _loop1_108_rule(p)) // lambda_param_maybe_default+ && (c = lambda_kwds_rule(p), !p->error_indicator) // lambda_kwds? ) @@ -15219,7 +15456,7 @@ strings_rule(Parser *p) D(fprintf(stderr, "%*c> strings[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "STRING+")); asdl_seq * a; if ( - (a = _loop1_108_rule(p)) // STRING+ + (a = _loop1_109_rule(p)) // STRING+ ) { D(fprintf(stderr, "%*c+ strings[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "STRING+")); @@ -15345,7 +15582,7 @@ tuple_rule(Parser *p) if ( (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (a = _tmp_109_rule(p), !p->error_indicator) // [star_named_expression ',' star_named_expressions?] + (a = _tmp_110_rule(p), !p->error_indicator) // [star_named_expression ',' star_named_expressions?] && (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' ) @@ -15563,7 +15800,7 @@ double_starred_kvpairs_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings asdl_seq * a; if ( - (a = _gather_110_rule(p)) // ','.double_starred_kvpair+ + (a = _gather_111_rule(p)) // ','.double_starred_kvpair+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -15725,7 +15962,7 @@ for_if_clauses_rule(Parser *p) D(fprintf(stderr, "%*c> for_if_clauses[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "for_if_clause+")); asdl_comprehension_seq* a; if ( - (a = (asdl_comprehension_seq*)_loop1_112_rule(p)) // for_if_clause+ + (a = (asdl_comprehension_seq*)_loop1_113_rule(p)) // for_if_clause+ ) { D(fprintf(stderr, "%*c+ for_if_clauses[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "for_if_clause+")); @@ -15790,7 +16027,7 @@ for_if_clause_rule(Parser *p) && (b = disjunction_rule(p)) // disjunction && - (c = (asdl_expr_seq*)_loop0_113_rule(p)) // (('if' disjunction))* + (c = (asdl_expr_seq*)_loop0_114_rule(p)) // (('if' disjunction))* ) { D(fprintf(stderr, "%*c+ for_if_clause[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); @@ -15833,7 +16070,7 @@ for_if_clause_rule(Parser *p) && (b = disjunction_rule(p)) // disjunction && - (c = (asdl_expr_seq*)_loop0_114_rule(p)) // (('if' disjunction))* + (c = (asdl_expr_seq*)_loop0_115_rule(p)) // (('if' disjunction))* ) { D(fprintf(stderr, "%*c+ for_if_clause[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); @@ -16096,7 +16333,7 @@ genexp_rule(Parser *p) if ( (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (a = _tmp_115_rule(p)) // assignment_expression | expression !':=' + (a = _tmp_116_rule(p)) // assignment_expression | expression !':=' && (b = for_if_clauses_rule(p)) // for_if_clauses && @@ -16348,9 +16585,9 @@ args_rule(Parser *p) asdl_expr_seq* a; void *b; if ( - (a = (asdl_expr_seq*)_gather_116_rule(p)) // ','.(starred_expression | (assignment_expression | expression !':=') !'=')+ + (a = (asdl_expr_seq*)_gather_117_rule(p)) // ','.(starred_expression | (assignment_expression | expression !':=') !'=')+ && - (b = _tmp_118_rule(p), !p->error_indicator) // [',' kwargs] + (b = _tmp_119_rule(p), !p->error_indicator) // [',' kwargs] ) { D(fprintf(stderr, "%*c+ args[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | (assignment_expression | expression !':=') !'=')+ [',' kwargs]")); @@ -16441,11 +16678,11 @@ kwargs_rule(Parser *p) asdl_seq * a; asdl_seq * b; if ( - (a = _gather_119_rule(p)) // ','.kwarg_or_starred+ + (a = _gather_120_rule(p)) // ','.kwarg_or_starred+ && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (b = _gather_121_rule(p)) // ','.kwarg_or_double_starred+ + (b = _gather_122_rule(p)) // ','.kwarg_or_double_starred+ ) { D(fprintf(stderr, "%*c+ kwargs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_starred+ ',' ','.kwarg_or_double_starred+")); @@ -16467,13 +16704,13 @@ kwargs_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> kwargs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_starred+")); - asdl_seq * _gather_123_var; + asdl_seq * _gather_124_var; if ( - (_gather_123_var = _gather_123_rule(p)) // ','.kwarg_or_starred+ + (_gather_124_var = _gather_124_rule(p)) // ','.kwarg_or_starred+ ) { D(fprintf(stderr, "%*c+ kwargs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_starred+")); - _res = _gather_123_var; + _res = _gather_124_var; goto done; } p->mark = _mark; @@ -16486,13 +16723,13 @@ kwargs_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> kwargs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_double_starred+")); - asdl_seq * _gather_125_var; + asdl_seq * _gather_126_var; if ( - (_gather_125_var = _gather_125_rule(p)) // ','.kwarg_or_double_starred+ + (_gather_126_var = _gather_126_rule(p)) // ','.kwarg_or_double_starred+ ) { D(fprintf(stderr, "%*c+ kwargs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_double_starred+")); - _res = _gather_125_var; + _res = _gather_126_var; goto done; } p->mark = _mark; @@ -16866,7 +17103,7 @@ star_targets_rule(Parser *p) if ( (a = star_target_rule(p)) // star_target && - (b = _loop0_127_rule(p)) // ((',' star_target))* + (b = _loop0_128_rule(p)) // ((',' star_target))* && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -16923,7 +17160,7 @@ star_targets_list_seq_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings asdl_expr_seq* a; if ( - (a = (asdl_expr_seq*)_gather_128_rule(p)) // ','.star_target+ + (a = (asdl_expr_seq*)_gather_129_rule(p)) // ','.star_target+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -16974,7 +17211,7 @@ star_targets_tuple_seq_rule(Parser *p) if ( (a = star_target_rule(p)) // star_target && - (b = _loop1_130_rule(p)) // ((',' star_target))+ + (b = _loop1_131_rule(p)) // ((',' star_target))+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -17063,7 +17300,7 @@ star_target_rule(Parser *p) if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (a = _tmp_131_rule(p)) // !'*' star_target + (a = _tmp_132_rule(p)) // !'*' star_target ) { D(fprintf(stderr, "%*c+ star_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (!'*' star_target)")); @@ -17994,7 +18231,7 @@ del_targets_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings asdl_expr_seq* a; if ( - (a = (asdl_expr_seq*)_gather_132_rule(p)) // ','.del_target+ + (a = (asdl_expr_seq*)_gather_133_rule(p)) // ','.del_target+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -18355,7 +18592,7 @@ type_expressions_rule(Parser *p) expr_ty b; expr_ty c; if ( - (a = _gather_134_rule(p)) // ','.expression+ + (a = _gather_135_rule(p)) // ','.expression+ && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && @@ -18394,7 +18631,7 @@ type_expressions_rule(Parser *p) asdl_seq * a; expr_ty b; if ( - (a = _gather_136_rule(p)) // ','.expression+ + (a = _gather_137_rule(p)) // ','.expression+ && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && @@ -18427,7 +18664,7 @@ type_expressions_rule(Parser *p) asdl_seq * a; expr_ty b; if ( - (a = _gather_138_rule(p)) // ','.expression+ + (a = _gather_139_rule(p)) // ','.expression+ && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && @@ -18547,7 +18784,7 @@ type_expressions_rule(Parser *p) D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.expression+")); asdl_expr_seq* a; if ( - (a = (asdl_expr_seq*)_gather_140_rule(p)) // ','.expression+ + (a = (asdl_expr_seq*)_gather_141_rule(p)) // ','.expression+ ) { D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.expression+")); @@ -18599,7 +18836,7 @@ func_type_comment_rule(Parser *p) && (t = _PyPegen_expect_token(p, TYPE_COMMENT)) // token='TYPE_COMMENT' && - _PyPegen_lookahead(1, _tmp_142_rule, p) + _PyPegen_lookahead(1, _tmp_143_rule, p) ) { D(fprintf(stderr, "%*c+ func_type_comment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE TYPE_COMMENT &(NEWLINE INDENT)")); @@ -18727,7 +18964,7 @@ invalid_arguments_rule(Parser *p) && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_opt_var = _tmp_143_rule(p), !p->error_indicator) // [args | expression for_if_clauses] + (_opt_var = _tmp_144_rule(p), !p->error_indicator) // [args | expression for_if_clauses] ) { D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses ',' [args | expression for_if_clauses]")); @@ -18898,7 +19135,7 @@ invalid_kwarg_rule(Parser *p) Token* a; Token * b; if ( - (a = (Token*)_tmp_144_rule(p)) // 'True' | 'False' | 'None' + (a = (Token*)_tmp_145_rule(p)) // 'True' | 'False' | 'None' && (b = _PyPegen_expect_token(p, 22)) // token='=' ) @@ -18958,7 +19195,7 @@ invalid_kwarg_rule(Parser *p) expr_ty a; Token * b; if ( - _PyPegen_lookahead(0, _tmp_145_rule, p) + _PyPegen_lookahead(0, _tmp_146_rule, p) && (a = expression_rule(p)) // expression && @@ -19183,7 +19420,7 @@ invalid_expression_rule(Parser *p) expr_ty a; expr_ty b; if ( - _PyPegen_lookahead(0, _tmp_146_rule, p) + _PyPegen_lookahead(0, _tmp_147_rule, p) && (a = disjunction_rule(p)) // disjunction && @@ -19219,7 +19456,7 @@ invalid_expression_rule(Parser *p) && (b = disjunction_rule(p)) // disjunction && - _PyPegen_lookahead(0, _tmp_147_rule, p) + _PyPegen_lookahead(0, _tmp_148_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction !('else' | ':')")); @@ -19308,7 +19545,7 @@ invalid_named_expression_rule(Parser *p) && (b = bitwise_or_rule(p)) // bitwise_or && - _PyPegen_lookahead(0, _tmp_148_rule, p) + _PyPegen_lookahead(0, _tmp_149_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '=' bitwise_or !('=' | ':=')")); @@ -19334,7 +19571,7 @@ invalid_named_expression_rule(Parser *p) Token * b; expr_ty bitwise_or_var; if ( - _PyPegen_lookahead(0, _tmp_149_rule, p) + _PyPegen_lookahead(0, _tmp_150_rule, p) && (a = bitwise_or_rule(p)) // bitwise_or && @@ -19342,7 +19579,7 @@ invalid_named_expression_rule(Parser *p) && (bitwise_or_var = bitwise_or_rule(p)) // bitwise_or && - _PyPegen_lookahead(0, _tmp_150_rule, p) + _PyPegen_lookahead(0, _tmp_151_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!(list | tuple | genexp | 'True' | 'None' | 'False') bitwise_or '=' bitwise_or !('=' | ':=')")); @@ -19423,7 +19660,7 @@ invalid_assignment_rule(Parser *p) D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions* ':' expression")); Token * _literal; Token * _literal_1; - asdl_seq * _loop0_151_var; + asdl_seq * _loop0_152_var; expr_ty a; expr_ty expression_var; if ( @@ -19431,7 +19668,7 @@ invalid_assignment_rule(Parser *p) && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_loop0_151_var = _loop0_151_rule(p)) // star_named_expressions* + (_loop0_152_var = _loop0_152_rule(p)) // star_named_expressions* && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' && @@ -19488,10 +19725,10 @@ invalid_assignment_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* star_expressions '='")); Token * _literal; - asdl_seq * _loop0_152_var; + asdl_seq * _loop0_153_var; expr_ty a; if ( - (_loop0_152_var = _loop0_152_rule(p)) // ((star_targets '='))* + (_loop0_153_var = _loop0_153_rule(p)) // ((star_targets '='))* && (a = star_expressions_rule(p)) // star_expressions && @@ -19518,10 +19755,10 @@ invalid_assignment_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* yield_expr '='")); Token * _literal; - asdl_seq * _loop0_153_var; + asdl_seq * _loop0_154_var; expr_ty a; if ( - (_loop0_153_var = _loop0_153_rule(p)) // ((star_targets '='))* + (_loop0_154_var = _loop0_154_rule(p)) // ((star_targets '='))* && (a = yield_expr_rule(p)) // yield_expr && @@ -19547,7 +19784,7 @@ invalid_assignment_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions augassign (yield_expr | star_expressions)")); - void *_tmp_154_var; + void *_tmp_155_var; expr_ty a; AugOperator* augassign_var; if ( @@ -19555,7 +19792,7 @@ invalid_assignment_rule(Parser *p) && (augassign_var = augassign_rule(p)) // augassign && - (_tmp_154_var = _tmp_154_rule(p)) // yield_expr | star_expressions + (_tmp_155_var = _tmp_155_rule(p)) // yield_expr | star_expressions ) { D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions augassign (yield_expr | star_expressions)")); @@ -19781,11 +20018,11 @@ invalid_comprehension_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '(' | '{') starred_expression for_if_clauses")); - void *_tmp_155_var; + void *_tmp_156_var; expr_ty a; asdl_comprehension_seq* for_if_clauses_var; if ( - (_tmp_155_var = _tmp_155_rule(p)) // '[' | '(' | '{' + (_tmp_156_var = _tmp_156_rule(p)) // '[' | '(' | '{' && (a = starred_expression_rule(p)) // starred_expression && @@ -19812,12 +20049,12 @@ invalid_comprehension_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '{') star_named_expression ',' star_named_expressions for_if_clauses")); Token * _literal; - void *_tmp_156_var; + void *_tmp_157_var; expr_ty a; asdl_expr_seq* b; asdl_comprehension_seq* for_if_clauses_var; if ( - (_tmp_156_var = _tmp_156_rule(p)) // '[' | '{' + (_tmp_157_var = _tmp_157_rule(p)) // '[' | '{' && (a = star_named_expression_rule(p)) // star_named_expression && @@ -19847,12 +20084,12 @@ invalid_comprehension_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '{') star_named_expression ',' for_if_clauses")); - void *_tmp_157_var; + void *_tmp_158_var; expr_ty a; Token * b; asdl_comprehension_seq* for_if_clauses_var; if ( - (_tmp_157_var = _tmp_157_rule(p)) // '[' | '{' + (_tmp_158_var = _tmp_158_rule(p)) // '[' | '{' && (a = star_named_expression_rule(p)) // star_named_expression && @@ -19962,11 +20199,11 @@ invalid_parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default* invalid_parameters_helper param_no_default")); - asdl_seq * _loop0_158_var; + asdl_seq * _loop0_159_var; arg_ty a; void *invalid_parameters_helper_var; if ( - (_loop0_158_var = _loop0_158_rule(p)) // param_no_default* + (_loop0_159_var = _loop0_159_rule(p)) // param_no_default* && (invalid_parameters_helper_var = invalid_parameters_helper_rule(p)) // invalid_parameters_helper && @@ -19992,18 +20229,18 @@ invalid_parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default* '(' param_no_default+ ','? ')'")); - asdl_seq * _loop0_159_var; - asdl_seq * _loop1_160_var; + asdl_seq * _loop0_160_var; + asdl_seq * _loop1_161_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings Token * a; Token * b; if ( - (_loop0_159_var = _loop0_159_rule(p)) // param_no_default* + (_loop0_160_var = _loop0_160_rule(p)) // param_no_default* && (a = _PyPegen_expect_token(p, 7)) // token='(' && - (_loop1_160_var = _loop1_160_rule(p)) // param_no_default+ + (_loop1_161_var = _loop1_161_rule(p)) // param_no_default+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -20056,13 +20293,13 @@ invalid_parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(slash_no_default | slash_with_default) param_maybe_default* '/'")); - asdl_seq * _loop0_162_var; - void *_tmp_161_var; + asdl_seq * _loop0_163_var; + void *_tmp_162_var; Token * a; if ( - (_tmp_161_var = _tmp_161_rule(p)) // slash_no_default | slash_with_default + (_tmp_162_var = _tmp_162_rule(p)) // slash_no_default | slash_with_default && - (_loop0_162_var = _loop0_162_rule(p)) // param_maybe_default* + (_loop0_163_var = _loop0_163_rule(p)) // param_maybe_default* && (a = _PyPegen_expect_token(p, 17)) // token='/' ) @@ -20087,22 +20324,22 @@ invalid_parameters_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "[(slash_no_default | slash_with_default)] param_maybe_default* '*' (',' | param_no_default) param_maybe_default* '/'")); Token * _literal; - asdl_seq * _loop0_164_var; - asdl_seq * _loop0_166_var; + asdl_seq * _loop0_165_var; + asdl_seq * _loop0_167_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings - void *_tmp_165_var; + void *_tmp_166_var; Token * a; if ( - (_opt_var = _tmp_163_rule(p), !p->error_indicator) // [(slash_no_default | slash_with_default)] + (_opt_var = _tmp_164_rule(p), !p->error_indicator) // [(slash_no_default | slash_with_default)] && - (_loop0_164_var = _loop0_164_rule(p)) // param_maybe_default* + (_loop0_165_var = _loop0_165_rule(p)) // param_maybe_default* && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_165_var = _tmp_165_rule(p)) // ',' | param_no_default + (_tmp_166_var = _tmp_166_rule(p)) // ',' | param_no_default && - (_loop0_166_var = _loop0_166_rule(p)) // param_maybe_default* + (_loop0_167_var = _loop0_167_rule(p)) // param_maybe_default* && (a = _PyPegen_expect_token(p, 17)) // token='/' ) @@ -20127,10 +20364,10 @@ invalid_parameters_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default+ '/' '*'")); Token * _literal; - asdl_seq * _loop1_167_var; + asdl_seq * _loop1_168_var; Token * a; if ( - (_loop1_167_var = _loop1_167_rule(p)) // param_maybe_default+ + (_loop1_168_var = _loop1_168_rule(p)) // param_maybe_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -20180,7 +20417,7 @@ invalid_default_rule(Parser *p) if ( (a = _PyPegen_expect_token(p, 22)) // token='=' && - _PyPegen_lookahead(1, _tmp_168_rule, p) + _PyPegen_lookahead(1, _tmp_169_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'=' &(')' | ',')")); @@ -20226,12 +20463,12 @@ invalid_star_etc_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); - void *_tmp_169_var; + void *_tmp_170_var; Token * a; if ( (a = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_169_var = _tmp_169_rule(p)) // ')' | ',' (')' | '**') + (_tmp_170_var = _tmp_170_rule(p)) // ')' | ',' (')' | '**') ) { D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); @@ -20314,20 +20551,20 @@ invalid_star_etc_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (param_no_default | ',') param_maybe_default* '*' (param_no_default | ',')")); Token * _literal; - asdl_seq * _loop0_171_var; - void *_tmp_170_var; - void *_tmp_172_var; + asdl_seq * _loop0_172_var; + void *_tmp_171_var; + void *_tmp_173_var; Token * a; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_170_var = _tmp_170_rule(p)) // param_no_default | ',' + (_tmp_171_var = _tmp_171_rule(p)) // param_no_default | ',' && - (_loop0_171_var = _loop0_171_rule(p)) // param_maybe_default* + (_loop0_172_var = _loop0_172_rule(p)) // param_maybe_default* && (a = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_172_var = _tmp_172_rule(p)) // param_no_default | ',' + (_tmp_173_var = _tmp_173_rule(p)) // param_no_default | ',' ) { D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (param_no_default | ',') param_maybe_default* '*' (param_no_default | ',')")); @@ -20443,7 +20680,7 @@ invalid_kwds_rule(Parser *p) && (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' && - (a = (Token*)_tmp_173_rule(p)) // '*' | '**' | '/' + (a = (Token*)_tmp_174_rule(p)) // '*' | '**' | '/' ) { D(fprintf(stderr, "%*c+ invalid_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' param ',' ('*' | '**' | '/')")); @@ -20509,13 +20746,13 @@ invalid_parameters_helper_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_parameters_helper[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default+")); - asdl_seq * _loop1_174_var; + asdl_seq * _loop1_175_var; if ( - (_loop1_174_var = _loop1_174_rule(p)) // param_with_default+ + (_loop1_175_var = _loop1_175_rule(p)) // param_with_default+ ) { D(fprintf(stderr, "%*c+ invalid_parameters_helper[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_with_default+")); - _res = _loop1_174_var; + _res = _loop1_175_var; goto done; } p->mark = _mark; @@ -20554,11 +20791,11 @@ invalid_lambda_parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default")); - asdl_seq * _loop0_175_var; + asdl_seq * _loop0_176_var; arg_ty a; void *invalid_lambda_parameters_helper_var; if ( - (_loop0_175_var = _loop0_175_rule(p)) // lambda_param_no_default* + (_loop0_176_var = _loop0_176_rule(p)) // lambda_param_no_default* && (invalid_lambda_parameters_helper_var = invalid_lambda_parameters_helper_rule(p)) // invalid_lambda_parameters_helper && @@ -20584,18 +20821,18 @@ invalid_lambda_parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* '(' ','.lambda_param+ ','? ')'")); - asdl_seq * _gather_177_var; - asdl_seq * _loop0_176_var; + asdl_seq * _gather_178_var; + asdl_seq * _loop0_177_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings Token * a; Token * b; if ( - (_loop0_176_var = _loop0_176_rule(p)) // lambda_param_no_default* + (_loop0_177_var = _loop0_177_rule(p)) // lambda_param_no_default* && (a = _PyPegen_expect_token(p, 7)) // token='(' && - (_gather_177_var = _gather_177_rule(p)) // ','.lambda_param+ + (_gather_178_var = _gather_178_rule(p)) // ','.lambda_param+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -20648,13 +20885,13 @@ invalid_lambda_parameters_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* '/'")); - asdl_seq * _loop0_180_var; - void *_tmp_179_var; + asdl_seq * _loop0_181_var; + void *_tmp_180_var; Token * a; if ( - (_tmp_179_var = _tmp_179_rule(p)) // lambda_slash_no_default | lambda_slash_with_default + (_tmp_180_var = _tmp_180_rule(p)) // lambda_slash_no_default | lambda_slash_with_default && - (_loop0_180_var = _loop0_180_rule(p)) // lambda_param_maybe_default* + (_loop0_181_var = _loop0_181_rule(p)) // lambda_param_maybe_default* && (a = _PyPegen_expect_token(p, 17)) // token='/' ) @@ -20679,22 +20916,22 @@ invalid_lambda_parameters_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "[(lambda_slash_no_default | lambda_slash_with_default)] lambda_param_maybe_default* '*' (',' | lambda_param_no_default) lambda_param_maybe_default* '/'")); Token * _literal; - asdl_seq * _loop0_182_var; - asdl_seq * _loop0_184_var; + asdl_seq * _loop0_183_var; + asdl_seq * _loop0_185_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings - void *_tmp_183_var; + void *_tmp_184_var; Token * a; if ( - (_opt_var = _tmp_181_rule(p), !p->error_indicator) // [(lambda_slash_no_default | lambda_slash_with_default)] + (_opt_var = _tmp_182_rule(p), !p->error_indicator) // [(lambda_slash_no_default | lambda_slash_with_default)] && - (_loop0_182_var = _loop0_182_rule(p)) // lambda_param_maybe_default* + (_loop0_183_var = _loop0_183_rule(p)) // lambda_param_maybe_default* && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_183_var = _tmp_183_rule(p)) // ',' | lambda_param_no_default + (_tmp_184_var = _tmp_184_rule(p)) // ',' | lambda_param_no_default && - (_loop0_184_var = _loop0_184_rule(p)) // lambda_param_maybe_default* + (_loop0_185_var = _loop0_185_rule(p)) // lambda_param_maybe_default* && (a = _PyPegen_expect_token(p, 17)) // token='/' ) @@ -20719,10 +20956,10 @@ invalid_lambda_parameters_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default+ '/' '*'")); Token * _literal; - asdl_seq * _loop1_185_var; + asdl_seq * _loop1_186_var; Token * a; if ( - (_loop1_185_var = _loop1_185_rule(p)) // lambda_param_maybe_default+ + (_loop1_186_var = _loop1_186_rule(p)) // lambda_param_maybe_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -20794,13 +21031,13 @@ invalid_lambda_parameters_helper_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_lambda_parameters_helper[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+")); - asdl_seq * _loop1_186_var; + asdl_seq * _loop1_187_var; if ( - (_loop1_186_var = _loop1_186_rule(p)) // lambda_param_with_default+ + (_loop1_187_var = _loop1_187_rule(p)) // lambda_param_with_default+ ) { D(fprintf(stderr, "%*c+ invalid_lambda_parameters_helper[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+")); - _res = _loop1_186_var; + _res = _loop1_187_var; goto done; } p->mark = _mark; @@ -20837,11 +21074,11 @@ invalid_lambda_star_etc_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); Token * _literal; - void *_tmp_187_var; + void *_tmp_188_var; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_187_var = _tmp_187_rule(p)) // ':' | ',' (':' | '**') + (_tmp_188_var = _tmp_188_rule(p)) // ':' | ',' (':' | '**') ) { D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); @@ -20894,20 +21131,20 @@ invalid_lambda_star_etc_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (lambda_param_no_default | ',') lambda_param_maybe_default* '*' (lambda_param_no_default | ',')")); Token * _literal; - asdl_seq * _loop0_189_var; - void *_tmp_188_var; - void *_tmp_190_var; + asdl_seq * _loop0_190_var; + void *_tmp_189_var; + void *_tmp_191_var; Token * a; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_188_var = _tmp_188_rule(p)) // lambda_param_no_default | ',' + (_tmp_189_var = _tmp_189_rule(p)) // lambda_param_no_default | ',' && - (_loop0_189_var = _loop0_189_rule(p)) // lambda_param_maybe_default* + (_loop0_190_var = _loop0_190_rule(p)) // lambda_param_maybe_default* && (a = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_190_var = _tmp_190_rule(p)) // lambda_param_no_default | ',' + (_tmp_191_var = _tmp_191_rule(p)) // lambda_param_no_default | ',' ) { D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (lambda_param_no_default | ',') lambda_param_maybe_default* '*' (lambda_param_no_default | ',')")); @@ -21026,7 +21263,7 @@ invalid_lambda_kwds_rule(Parser *p) && (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' && - (a = (Token*)_tmp_191_rule(p)) // '*' | '**' | '/' + (a = (Token*)_tmp_192_rule(p)) // '*' | '**' | '/' ) { D(fprintf(stderr, "%*c+ invalid_lambda_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' lambda_param ',' ('*' | '**' | '/')")); @@ -21134,7 +21371,7 @@ invalid_with_item_rule(Parser *p) && (a = expression_rule(p)) // expression && - _PyPegen_lookahead(1, _tmp_192_rule, p) + _PyPegen_lookahead(1, _tmp_193_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_with_item[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression 'as' expression &(',' | ')' | ':')")); @@ -21362,7 +21599,7 @@ invalid_with_stmt_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ &&':'")); - asdl_seq * _gather_193_var; + asdl_seq * _gather_194_var; Token * _keyword; Token * _literal; void *_opt_var; @@ -21372,13 +21609,13 @@ invalid_with_stmt_rule(Parser *p) && (_keyword = _PyPegen_expect_token(p, 612)) // token='with' && - (_gather_193_var = _gather_193_rule(p)) // ','.(expression ['as' star_target])+ + (_gather_194_var = _gather_194_rule(p)) // ','.(expression ['as' star_target])+ && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' ) { D(fprintf(stderr, "%*c+ invalid_with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ &&':'")); - _res = _PyPegen_dummy_name(p, _opt_var, _keyword, _gather_193_var, _literal); + _res = _PyPegen_dummy_name(p, _opt_var, _keyword, _gather_194_var, _literal); goto done; } p->mark = _mark; @@ -21391,7 +21628,7 @@ invalid_with_stmt_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' &&':'")); - asdl_seq * _gather_195_var; + asdl_seq * _gather_196_var; Token * _keyword; Token * _literal; Token * _literal_1; @@ -21407,7 +21644,7 @@ invalid_with_stmt_rule(Parser *p) && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (_gather_195_var = _gather_195_rule(p)) // ','.(expressions ['as' star_target])+ + (_gather_196_var = _gather_196_rule(p)) // ','.(expressions ['as' star_target])+ && (_opt_var_1 = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -21417,7 +21654,7 @@ invalid_with_stmt_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ invalid_with_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' &&':'")); - _res = _PyPegen_dummy_name(p, _opt_var, _keyword, _literal, _gather_195_var, _opt_var_1, _literal_1, _literal_2); + _res = _PyPegen_dummy_name(p, _opt_var, _keyword, _literal, _gather_196_var, _opt_var_1, _literal_1, _literal_2); goto done; } p->mark = _mark; @@ -21452,7 +21689,7 @@ invalid_with_stmt_indent_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_with_stmt_indent[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT")); - asdl_seq * _gather_197_var; + asdl_seq * _gather_198_var; Token * _literal; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings @@ -21463,7 +21700,7 @@ invalid_with_stmt_indent_rule(Parser *p) && (a = _PyPegen_expect_token(p, 612)) // token='with' && - (_gather_197_var = _gather_197_rule(p)) // ','.(expression ['as' star_target])+ + (_gather_198_var = _gather_198_rule(p)) // ','.(expression ['as' star_target])+ && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -21491,7 +21728,7 @@ invalid_with_stmt_indent_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_with_stmt_indent[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT")); - asdl_seq * _gather_199_var; + asdl_seq * _gather_200_var; Token * _literal; Token * _literal_1; Token * _literal_2; @@ -21508,7 +21745,7 @@ invalid_with_stmt_indent_rule(Parser *p) && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (_gather_199_var = _gather_199_rule(p)) // ','.(expressions ['as' star_target])+ + (_gather_200_var = _gather_200_rule(p)) // ','.(expressions ['as' star_target])+ && (_opt_var_1 = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -21605,7 +21842,7 @@ invalid_try_stmt_rule(Parser *p) && (block_var = block_rule(p)) // block && - _PyPegen_lookahead(0, _tmp_201_rule, p) + _PyPegen_lookahead(0, _tmp_202_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' ':' block !('except' | 'finally')")); @@ -21629,19 +21866,19 @@ invalid_try_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> invalid_try_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'try' ':' block* ((except_block+ except_star_block) | (except_star_block+ except_block)) block*")); Token * _keyword; Token * _literal; - asdl_seq * _loop0_202_var; - asdl_seq * _loop0_204_var; - void *_tmp_203_var; + asdl_seq * _loop0_203_var; + asdl_seq * _loop0_205_var; + void *_tmp_204_var; if ( (_keyword = _PyPegen_expect_token(p, 618)) // token='try' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && - (_loop0_202_var = _loop0_202_rule(p)) // block* + (_loop0_203_var = _loop0_203_rule(p)) // block* && - (_tmp_203_var = _tmp_203_rule(p)) // (except_block+ except_star_block) | (except_star_block+ except_block) + (_tmp_204_var = _tmp_204_rule(p)) // (except_block+ except_star_block) | (except_star_block+ except_block) && - (_loop0_204_var = _loop0_204_rule(p)) // block* + (_loop0_205_var = _loop0_205_rule(p)) // block* ) { D(fprintf(stderr, "%*c+ invalid_try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' ':' block* ((except_block+ except_star_block) | (except_star_block+ except_block)) block*")); @@ -21707,7 +21944,7 @@ invalid_except_stmt_rule(Parser *p) && (expressions_var = expressions_rule(p)) // expressions && - (_opt_var_1 = _tmp_205_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var_1 = _tmp_206_rule(p), !p->error_indicator) // ['as' NAME] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' ) @@ -21745,7 +21982,7 @@ invalid_except_stmt_rule(Parser *p) && (expression_var = expression_rule(p)) // expression && - (_opt_var_1 = _tmp_206_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var_1 = _tmp_207_rule(p), !p->error_indicator) // ['as' NAME] && (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) @@ -21797,14 +22034,14 @@ invalid_except_stmt_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_except_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' '*' (NEWLINE | ':')")); Token * _literal; - void *_tmp_207_var; + void *_tmp_208_var; Token * a; if ( (a = _PyPegen_expect_token(p, 629)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_207_var = _tmp_207_rule(p)) // NEWLINE | ':' + (_tmp_208_var = _tmp_208_rule(p)) // NEWLINE | ':' ) { D(fprintf(stderr, "%*c+ invalid_except_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' '*' (NEWLINE | ':')")); @@ -21911,7 +22148,7 @@ invalid_except_stmt_indent_rule(Parser *p) && (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_208_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var = _tmp_209_rule(p), !p->error_indicator) // ['as' NAME] && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -22006,7 +22243,7 @@ invalid_except_star_stmt_indent_rule(Parser *p) && (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_209_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var = _tmp_210_rule(p), !p->error_indicator) // ['as' NAME] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' && @@ -22373,7 +22610,7 @@ invalid_class_argument_pattern_rule(Parser *p) asdl_pattern_seq* a; asdl_seq* keyword_patterns_var; if ( - (_opt_var = _tmp_210_rule(p), !p->error_indicator) // [positional_patterns ','] + (_opt_var = _tmp_211_rule(p), !p->error_indicator) // [positional_patterns ','] && (keyword_patterns_var = keyword_patterns_rule(p)) // keyword_patterns && @@ -22825,7 +23062,7 @@ invalid_def_raw_rule(Parser *p) && (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' && - (_opt_var_2 = _tmp_211_rule(p), !p->error_indicator) // ['->' expression] + (_opt_var_2 = _tmp_212_rule(p), !p->error_indicator) // ['->' expression] && (_literal_2 = _PyPegen_expect_token(p, 11)) // token=':' && @@ -22884,7 +23121,7 @@ invalid_class_def_raw_rule(Parser *p) && (name_var = _PyPegen_name_token(p)) // NAME && - (_opt_var = _tmp_212_rule(p), !p->error_indicator) // ['(' arguments? ')'] + (_opt_var = _tmp_213_rule(p), !p->error_indicator) // ['(' arguments? ')'] && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -22935,11 +23172,11 @@ invalid_double_starred_kvpairs_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_double_starred_kvpairs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.double_starred_kvpair+ ',' invalid_kvpair")); - asdl_seq * _gather_213_var; + asdl_seq * _gather_214_var; Token * _literal; void *invalid_kvpair_var; if ( - (_gather_213_var = _gather_213_rule(p)) // ','.double_starred_kvpair+ + (_gather_214_var = _gather_214_rule(p)) // ','.double_starred_kvpair+ && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && @@ -22947,7 +23184,7 @@ invalid_double_starred_kvpairs_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ invalid_double_starred_kvpairs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.double_starred_kvpair+ ',' invalid_kvpair")); - _res = _PyPegen_dummy_name(p, _gather_213_var, _literal, invalid_kvpair_var); + _res = _PyPegen_dummy_name(p, _gather_214_var, _literal, invalid_kvpair_var); goto done; } p->mark = _mark; @@ -23000,7 +23237,7 @@ invalid_double_starred_kvpairs_rule(Parser *p) && (a = _PyPegen_expect_token(p, 11)) // token=':' && - _PyPegen_lookahead(1, _tmp_215_rule, p) + _PyPegen_lookahead(1, _tmp_216_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_double_starred_kvpairs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' &('}' | ',')")); @@ -23962,12 +24199,12 @@ _loop1_14_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_14[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_216_var; + void *_tmp_217_var; while ( - (_tmp_216_var = _tmp_216_rule(p)) // star_targets '=' + (_tmp_217_var = _tmp_217_rule(p)) // star_targets '=' ) { - _res = _tmp_216_var; + _res = _tmp_217_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -24544,12 +24781,12 @@ _loop0_24_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop0_24[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); - void *_tmp_217_var; + void *_tmp_218_var; while ( - (_tmp_217_var = _tmp_217_rule(p)) // '.' | '...' + (_tmp_218_var = _tmp_218_rule(p)) // '.' | '...' ) { - _res = _tmp_217_var; + _res = _tmp_218_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -24613,12 +24850,12 @@ _loop1_25_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_25[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); - void *_tmp_218_var; + void *_tmp_219_var; while ( - (_tmp_218_var = _tmp_218_rule(p)) // '.' | '...' + (_tmp_219_var = _tmp_219_rule(p)) // '.' | '...' ) { - _res = _tmp_218_var; + _res = _tmp_219_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -25021,12 +25258,12 @@ _loop1_32_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> _loop1_32[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('@' named_expression NEWLINE)")); - void *_tmp_219_var; + void *_tmp_220_var; while ( - (_tmp_219_var = _tmp_219_rule(p)) // '@' named_expression NEWLINE + (_tmp_220_var = _tmp_220_rule(p)) // '@' named_expression NEWLINE ) { - _res = _tmp_219_var; + _res = _tmp_220_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -26136,9 +26373,9 @@ _loop0_48_rule(Parser *p) return _seq; } -// _loop1_49: param_maybe_default +// _loop0_49: param_maybe_default static asdl_seq * -_loop1_49_rule(Parser *p) +_loop0_49_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -26165,7 +26402,7 @@ _loop1_49_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_49[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_49[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); NameDefaultPair* param_maybe_default_var; while ( (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default @@ -26187,7 +26424,76 @@ _loop1_49_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_49[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_49[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + _PyPegen_insert_memo(p, _start_mark, _loop0_49_type, _seq); + p->level--; + return _seq; +} + +// _loop1_50: param_maybe_default +static asdl_seq * +_loop1_50_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + int _start_mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // param_maybe_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_50[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + NameDefaultPair* param_maybe_default_var; + while ( + (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default + ) + { + _res = param_maybe_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop1_50[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } if (_n == 0 || p->error_indicator) { @@ -26205,14 +26511,14 @@ _loop1_49_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_49_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_50_type, _seq); p->level--; return _seq; } -// _loop0_51: ',' with_item +// _loop0_52: ',' with_item static asdl_seq * -_loop0_51_rule(Parser *p) +_loop0_52_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -26239,7 +26545,7 @@ _loop0_51_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_51[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); + D(fprintf(stderr, "%*c> _loop0_52[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); Token * _literal; withitem_ty elem; while ( @@ -26270,7 +26576,7 @@ _loop0_51_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_51[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_52[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' with_item")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -26283,14 +26589,14 @@ _loop0_51_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_51_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_52_type, _seq); p->level--; return _seq; } -// _gather_50: with_item _loop0_51 +// _gather_51: with_item _loop0_52 static asdl_seq * -_gather_50_rule(Parser *p) +_gather_51_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -26302,27 +26608,27 @@ _gather_50_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // with_item _loop0_51 + { // with_item _loop0_52 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_50[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_51")); + D(fprintf(stderr, "%*c> _gather_51[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_52")); withitem_ty elem; asdl_seq * seq; if ( (elem = with_item_rule(p)) // with_item && - (seq = _loop0_51_rule(p)) // _loop0_51 + (seq = _loop0_52_rule(p)) // _loop0_52 ) { - D(fprintf(stderr, "%*c+ _gather_50[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_51")); + D(fprintf(stderr, "%*c+ _gather_51[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_52")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_50[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_51")); + D(fprintf(stderr, "%*c%s _gather_51[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_52")); } _res = NULL; done: @@ -26330,9 +26636,9 @@ _gather_50_rule(Parser *p) return _res; } -// _loop0_53: ',' with_item +// _loop0_54: ',' with_item static asdl_seq * -_loop0_53_rule(Parser *p) +_loop0_54_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -26359,7 +26665,7 @@ _loop0_53_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_53[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); + D(fprintf(stderr, "%*c> _loop0_54[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); Token * _literal; withitem_ty elem; while ( @@ -26390,7 +26696,7 @@ _loop0_53_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_53[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_54[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' with_item")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -26403,14 +26709,14 @@ _loop0_53_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_53_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_54_type, _seq); p->level--; return _seq; } -// _gather_52: with_item _loop0_53 +// _gather_53: with_item _loop0_54 static asdl_seq * -_gather_52_rule(Parser *p) +_gather_53_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -26422,27 +26728,27 @@ _gather_52_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // with_item _loop0_53 + { // with_item _loop0_54 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_52[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_53")); + D(fprintf(stderr, "%*c> _gather_53[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_54")); withitem_ty elem; asdl_seq * seq; if ( (elem = with_item_rule(p)) // with_item && - (seq = _loop0_53_rule(p)) // _loop0_53 + (seq = _loop0_54_rule(p)) // _loop0_54 ) { - D(fprintf(stderr, "%*c+ _gather_52[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_53")); + D(fprintf(stderr, "%*c+ _gather_53[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_54")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_52[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_53")); + D(fprintf(stderr, "%*c%s _gather_53[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_54")); } _res = NULL; done: @@ -26450,9 +26756,9 @@ _gather_52_rule(Parser *p) return _res; } -// _loop0_55: ',' with_item +// _loop0_56: ',' with_item static asdl_seq * -_loop0_55_rule(Parser *p) +_loop0_56_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -26479,7 +26785,7 @@ _loop0_55_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_55[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); + D(fprintf(stderr, "%*c> _loop0_56[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); Token * _literal; withitem_ty elem; while ( @@ -26510,7 +26816,7 @@ _loop0_55_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_55[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_56[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' with_item")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -26523,14 +26829,14 @@ _loop0_55_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_55_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_56_type, _seq); p->level--; return _seq; } -// _gather_54: with_item _loop0_55 +// _gather_55: with_item _loop0_56 static asdl_seq * -_gather_54_rule(Parser *p) +_gather_55_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -26542,27 +26848,27 @@ _gather_54_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // with_item _loop0_55 + { // with_item _loop0_56 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_54[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_55")); + D(fprintf(stderr, "%*c> _gather_55[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_56")); withitem_ty elem; asdl_seq * seq; if ( (elem = with_item_rule(p)) // with_item && - (seq = _loop0_55_rule(p)) // _loop0_55 + (seq = _loop0_56_rule(p)) // _loop0_56 ) { - D(fprintf(stderr, "%*c+ _gather_54[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_55")); + D(fprintf(stderr, "%*c+ _gather_55[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_56")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_54[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_55")); + D(fprintf(stderr, "%*c%s _gather_55[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_56")); } _res = NULL; done: @@ -26570,9 +26876,9 @@ _gather_54_rule(Parser *p) return _res; } -// _loop0_57: ',' with_item +// _loop0_58: ',' with_item static asdl_seq * -_loop0_57_rule(Parser *p) +_loop0_58_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -26599,7 +26905,7 @@ _loop0_57_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_57[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); + D(fprintf(stderr, "%*c> _loop0_58[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); Token * _literal; withitem_ty elem; while ( @@ -26630,7 +26936,7 @@ _loop0_57_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_57[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_58[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' with_item")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -26643,14 +26949,14 @@ _loop0_57_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_57_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_58_type, _seq); p->level--; return _seq; } -// _gather_56: with_item _loop0_57 +// _gather_57: with_item _loop0_58 static asdl_seq * -_gather_56_rule(Parser *p) +_gather_57_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -26662,27 +26968,27 @@ _gather_56_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // with_item _loop0_57 + { // with_item _loop0_58 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_56[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_57")); + D(fprintf(stderr, "%*c> _gather_57[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_58")); withitem_ty elem; asdl_seq * seq; if ( (elem = with_item_rule(p)) // with_item && - (seq = _loop0_57_rule(p)) // _loop0_57 + (seq = _loop0_58_rule(p)) // _loop0_58 ) { - D(fprintf(stderr, "%*c+ _gather_56[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_57")); + D(fprintf(stderr, "%*c+ _gather_57[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_58")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_56[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_57")); + D(fprintf(stderr, "%*c%s _gather_57[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_58")); } _res = NULL; done: @@ -26690,9 +26996,9 @@ _gather_56_rule(Parser *p) return _res; } -// _tmp_58: ',' | ')' | ':' +// _tmp_59: ',' | ')' | ':' static void * -_tmp_58_rule(Parser *p) +_tmp_59_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -26709,18 +27015,18 @@ _tmp_58_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_58[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_59[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_58[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_59[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_58[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_59[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } { // ')' @@ -26728,18 +27034,18 @@ _tmp_58_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_58[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_59[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_58[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_59[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_58[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_59[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // ':' @@ -26747,18 +27053,18 @@ _tmp_58_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_58[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_59[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_58[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_59[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_58[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_59[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } _res = NULL; @@ -26767,9 +27073,9 @@ _tmp_58_rule(Parser *p) return _res; } -// _loop1_59: except_block +// _loop1_60: except_block static asdl_seq * -_loop1_59_rule(Parser *p) +_loop1_60_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -26796,7 +27102,7 @@ _loop1_59_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_59[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block")); + D(fprintf(stderr, "%*c> _loop1_60[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block")); excepthandler_ty except_block_var; while ( (except_block_var = except_block_rule(p)) // except_block @@ -26818,7 +27124,7 @@ _loop1_59_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_59[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_60[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_block")); } if (_n == 0 || p->error_indicator) { @@ -26836,14 +27142,14 @@ _loop1_59_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_59_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_60_type, _seq); p->level--; return _seq; } -// _loop1_60: except_star_block +// _loop1_61: except_star_block static asdl_seq * -_loop1_60_rule(Parser *p) +_loop1_61_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -26870,7 +27176,7 @@ _loop1_60_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_60[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block")); + D(fprintf(stderr, "%*c> _loop1_61[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block")); excepthandler_ty except_star_block_var; while ( (except_star_block_var = except_star_block_rule(p)) // except_star_block @@ -26892,7 +27198,7 @@ _loop1_60_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_60[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_61[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_star_block")); } if (_n == 0 || p->error_indicator) { @@ -26910,14 +27216,14 @@ _loop1_60_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_60_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_61_type, _seq); p->level--; return _seq; } -// _tmp_61: 'as' NAME +// _tmp_62: 'as' NAME static void * -_tmp_61_rule(Parser *p) +_tmp_62_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -26934,7 +27240,7 @@ _tmp_61_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_61[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_62[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty z; if ( @@ -26943,7 +27249,7 @@ _tmp_61_rule(Parser *p) (z = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_61[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_62[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -26953,7 +27259,7 @@ _tmp_61_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_61[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_62[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -26962,9 +27268,9 @@ _tmp_61_rule(Parser *p) return _res; } -// _tmp_62: 'as' NAME +// _tmp_63: 'as' NAME static void * -_tmp_62_rule(Parser *p) +_tmp_63_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -26981,7 +27287,7 @@ _tmp_62_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_62[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_63[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty z; if ( @@ -26990,7 +27296,7 @@ _tmp_62_rule(Parser *p) (z = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_62[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_63[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -27000,7 +27306,7 @@ _tmp_62_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_62[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_63[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -27009,9 +27315,9 @@ _tmp_62_rule(Parser *p) return _res; } -// _loop1_63: case_block +// _loop1_64: case_block static asdl_seq * -_loop1_63_rule(Parser *p) +_loop1_64_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -27038,7 +27344,7 @@ _loop1_63_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_63[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "case_block")); + D(fprintf(stderr, "%*c> _loop1_64[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "case_block")); match_case_ty case_block_var; while ( (case_block_var = case_block_rule(p)) // case_block @@ -27060,7 +27366,7 @@ _loop1_63_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_63[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_64[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "case_block")); } if (_n == 0 || p->error_indicator) { @@ -27078,14 +27384,14 @@ _loop1_63_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_63_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_64_type, _seq); p->level--; return _seq; } -// _loop0_65: '|' closed_pattern +// _loop0_66: '|' closed_pattern static asdl_seq * -_loop0_65_rule(Parser *p) +_loop0_66_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -27112,7 +27418,7 @@ _loop0_65_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_65[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'|' closed_pattern")); + D(fprintf(stderr, "%*c> _loop0_66[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'|' closed_pattern")); Token * _literal; pattern_ty elem; while ( @@ -27143,7 +27449,7 @@ _loop0_65_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_65[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_66[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'|' closed_pattern")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -27156,14 +27462,14 @@ _loop0_65_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_65_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_66_type, _seq); p->level--; return _seq; } -// _gather_64: closed_pattern _loop0_65 +// _gather_65: closed_pattern _loop0_66 static asdl_seq * -_gather_64_rule(Parser *p) +_gather_65_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -27175,27 +27481,27 @@ _gather_64_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // closed_pattern _loop0_65 + { // closed_pattern _loop0_66 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_64[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "closed_pattern _loop0_65")); + D(fprintf(stderr, "%*c> _gather_65[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "closed_pattern _loop0_66")); pattern_ty elem; asdl_seq * seq; if ( (elem = closed_pattern_rule(p)) // closed_pattern && - (seq = _loop0_65_rule(p)) // _loop0_65 + (seq = _loop0_66_rule(p)) // _loop0_66 ) { - D(fprintf(stderr, "%*c+ _gather_64[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "closed_pattern _loop0_65")); + D(fprintf(stderr, "%*c+ _gather_65[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "closed_pattern _loop0_66")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_64[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "closed_pattern _loop0_65")); + D(fprintf(stderr, "%*c%s _gather_65[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "closed_pattern _loop0_66")); } _res = NULL; done: @@ -27203,9 +27509,9 @@ _gather_64_rule(Parser *p) return _res; } -// _tmp_66: '+' | '-' +// _tmp_67: '+' | '-' static void * -_tmp_66_rule(Parser *p) +_tmp_67_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -27222,18 +27528,18 @@ _tmp_66_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_66[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+'")); + D(fprintf(stderr, "%*c> _tmp_67[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 14)) // token='+' ) { - D(fprintf(stderr, "%*c+ _tmp_66[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+'")); + D(fprintf(stderr, "%*c+ _tmp_67[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_66[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_67[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'+'")); } { // '-' @@ -27241,18 +27547,18 @@ _tmp_66_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_66[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-'")); + D(fprintf(stderr, "%*c> _tmp_67[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 15)) // token='-' ) { - D(fprintf(stderr, "%*c+ _tmp_66[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-'")); + D(fprintf(stderr, "%*c+ _tmp_67[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_66[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_67[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'-'")); } _res = NULL; @@ -27261,9 +27567,9 @@ _tmp_66_rule(Parser *p) return _res; } -// _tmp_67: '+' | '-' +// _tmp_68: '+' | '-' static void * -_tmp_67_rule(Parser *p) +_tmp_68_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -27280,18 +27586,18 @@ _tmp_67_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_67[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+'")); + D(fprintf(stderr, "%*c> _tmp_68[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 14)) // token='+' ) { - D(fprintf(stderr, "%*c+ _tmp_67[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+'")); + D(fprintf(stderr, "%*c+ _tmp_68[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_67[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_68[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'+'")); } { // '-' @@ -27299,18 +27605,18 @@ _tmp_67_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_67[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-'")); + D(fprintf(stderr, "%*c> _tmp_68[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 15)) // token='-' ) { - D(fprintf(stderr, "%*c+ _tmp_67[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-'")); + D(fprintf(stderr, "%*c+ _tmp_68[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_67[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_68[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'-'")); } _res = NULL; @@ -27319,9 +27625,9 @@ _tmp_67_rule(Parser *p) return _res; } -// _tmp_68: '.' | '(' | '=' +// _tmp_69: '.' | '(' | '=' static void * -_tmp_68_rule(Parser *p) +_tmp_69_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -27338,18 +27644,18 @@ _tmp_68_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_68[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_69[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_68[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_69[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_68[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_69[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '(' @@ -27357,18 +27663,18 @@ _tmp_68_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_68[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c> _tmp_69[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 7)) // token='(' ) { - D(fprintf(stderr, "%*c+ _tmp_68[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c+ _tmp_69[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_68[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_69[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'('")); } { // '=' @@ -27376,18 +27682,18 @@ _tmp_68_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_68[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c> _tmp_69[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_68[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c+ _tmp_69[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_68[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_69[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); } _res = NULL; @@ -27396,9 +27702,9 @@ _tmp_68_rule(Parser *p) return _res; } -// _tmp_69: '.' | '(' | '=' +// _tmp_70: '.' | '(' | '=' static void * -_tmp_69_rule(Parser *p) +_tmp_70_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -27415,18 +27721,18 @@ _tmp_69_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_69[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_70[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_69[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_70[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_69[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_70[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '(' @@ -27434,18 +27740,18 @@ _tmp_69_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_69[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c> _tmp_70[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 7)) // token='(' ) { - D(fprintf(stderr, "%*c+ _tmp_69[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c+ _tmp_70[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_69[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_70[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'('")); } { // '=' @@ -27453,18 +27759,18 @@ _tmp_69_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_69[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c> _tmp_70[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_69[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c+ _tmp_70[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_69[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_70[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); } _res = NULL; @@ -27473,9 +27779,9 @@ _tmp_69_rule(Parser *p) return _res; } -// _loop0_71: ',' maybe_star_pattern +// _loop0_72: ',' maybe_star_pattern static asdl_seq * -_loop0_71_rule(Parser *p) +_loop0_72_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -27502,7 +27808,7 @@ _loop0_71_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_71[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' maybe_star_pattern")); + D(fprintf(stderr, "%*c> _loop0_72[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' maybe_star_pattern")); Token * _literal; pattern_ty elem; while ( @@ -27533,7 +27839,7 @@ _loop0_71_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_71[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_72[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' maybe_star_pattern")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -27546,14 +27852,14 @@ _loop0_71_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_71_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_72_type, _seq); p->level--; return _seq; } -// _gather_70: maybe_star_pattern _loop0_71 +// _gather_71: maybe_star_pattern _loop0_72 static asdl_seq * -_gather_70_rule(Parser *p) +_gather_71_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -27565,27 +27871,27 @@ _gather_70_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // maybe_star_pattern _loop0_71 + { // maybe_star_pattern _loop0_72 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_70[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "maybe_star_pattern _loop0_71")); + D(fprintf(stderr, "%*c> _gather_71[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "maybe_star_pattern _loop0_72")); pattern_ty elem; asdl_seq * seq; if ( (elem = maybe_star_pattern_rule(p)) // maybe_star_pattern && - (seq = _loop0_71_rule(p)) // _loop0_71 + (seq = _loop0_72_rule(p)) // _loop0_72 ) { - D(fprintf(stderr, "%*c+ _gather_70[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "maybe_star_pattern _loop0_71")); + D(fprintf(stderr, "%*c+ _gather_71[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "maybe_star_pattern _loop0_72")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_70[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "maybe_star_pattern _loop0_71")); + D(fprintf(stderr, "%*c%s _gather_71[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "maybe_star_pattern _loop0_72")); } _res = NULL; done: @@ -27593,9 +27899,9 @@ _gather_70_rule(Parser *p) return _res; } -// _loop0_73: ',' key_value_pattern +// _loop0_74: ',' key_value_pattern static asdl_seq * -_loop0_73_rule(Parser *p) +_loop0_74_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -27622,7 +27928,7 @@ _loop0_73_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_73[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' key_value_pattern")); + D(fprintf(stderr, "%*c> _loop0_74[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' key_value_pattern")); Token * _literal; KeyPatternPair* elem; while ( @@ -27653,7 +27959,7 @@ _loop0_73_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_73[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_74[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' key_value_pattern")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -27666,14 +27972,14 @@ _loop0_73_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_73_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_74_type, _seq); p->level--; return _seq; } -// _gather_72: key_value_pattern _loop0_73 +// _gather_73: key_value_pattern _loop0_74 static asdl_seq * -_gather_72_rule(Parser *p) +_gather_73_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -27685,27 +27991,27 @@ _gather_72_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // key_value_pattern _loop0_73 + { // key_value_pattern _loop0_74 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_72[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "key_value_pattern _loop0_73")); + D(fprintf(stderr, "%*c> _gather_73[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "key_value_pattern _loop0_74")); KeyPatternPair* elem; asdl_seq * seq; if ( (elem = key_value_pattern_rule(p)) // key_value_pattern && - (seq = _loop0_73_rule(p)) // _loop0_73 + (seq = _loop0_74_rule(p)) // _loop0_74 ) { - D(fprintf(stderr, "%*c+ _gather_72[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "key_value_pattern _loop0_73")); + D(fprintf(stderr, "%*c+ _gather_73[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "key_value_pattern _loop0_74")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_72[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "key_value_pattern _loop0_73")); + D(fprintf(stderr, "%*c%s _gather_73[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "key_value_pattern _loop0_74")); } _res = NULL; done: @@ -27713,9 +28019,9 @@ _gather_72_rule(Parser *p) return _res; } -// _tmp_74: literal_expr | attr +// _tmp_75: literal_expr | attr static void * -_tmp_74_rule(Parser *p) +_tmp_75_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -27732,18 +28038,18 @@ _tmp_74_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_74[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "literal_expr")); + D(fprintf(stderr, "%*c> _tmp_75[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "literal_expr")); expr_ty literal_expr_var; if ( (literal_expr_var = literal_expr_rule(p)) // literal_expr ) { - D(fprintf(stderr, "%*c+ _tmp_74[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "literal_expr")); + D(fprintf(stderr, "%*c+ _tmp_75[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "literal_expr")); _res = literal_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_74[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_75[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "literal_expr")); } { // attr @@ -27751,18 +28057,18 @@ _tmp_74_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_74[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "attr")); + D(fprintf(stderr, "%*c> _tmp_75[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "attr")); expr_ty attr_var; if ( (attr_var = attr_rule(p)) // attr ) { - D(fprintf(stderr, "%*c+ _tmp_74[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "attr")); + D(fprintf(stderr, "%*c+ _tmp_75[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "attr")); _res = attr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_74[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_75[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "attr")); } _res = NULL; @@ -27771,9 +28077,9 @@ _tmp_74_rule(Parser *p) return _res; } -// _loop0_76: ',' pattern +// _loop0_77: ',' pattern static asdl_seq * -_loop0_76_rule(Parser *p) +_loop0_77_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -27800,7 +28106,7 @@ _loop0_76_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_76[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' pattern")); + D(fprintf(stderr, "%*c> _loop0_77[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' pattern")); Token * _literal; pattern_ty elem; while ( @@ -27831,7 +28137,7 @@ _loop0_76_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_76[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_77[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' pattern")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -27844,14 +28150,14 @@ _loop0_76_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_76_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_77_type, _seq); p->level--; return _seq; } -// _gather_75: pattern _loop0_76 +// _gather_76: pattern _loop0_77 static asdl_seq * -_gather_75_rule(Parser *p) +_gather_76_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -27863,27 +28169,27 @@ _gather_75_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // pattern _loop0_76 + { // pattern _loop0_77 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_75[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "pattern _loop0_76")); + D(fprintf(stderr, "%*c> _gather_76[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "pattern _loop0_77")); pattern_ty elem; asdl_seq * seq; if ( (elem = pattern_rule(p)) // pattern && - (seq = _loop0_76_rule(p)) // _loop0_76 + (seq = _loop0_77_rule(p)) // _loop0_77 ) { - D(fprintf(stderr, "%*c+ _gather_75[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "pattern _loop0_76")); + D(fprintf(stderr, "%*c+ _gather_76[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "pattern _loop0_77")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_75[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "pattern _loop0_76")); + D(fprintf(stderr, "%*c%s _gather_76[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "pattern _loop0_77")); } _res = NULL; done: @@ -27891,9 +28197,9 @@ _gather_75_rule(Parser *p) return _res; } -// _loop0_78: ',' keyword_pattern +// _loop0_79: ',' keyword_pattern static asdl_seq * -_loop0_78_rule(Parser *p) +_loop0_79_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -27920,7 +28226,7 @@ _loop0_78_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_78[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' keyword_pattern")); + D(fprintf(stderr, "%*c> _loop0_79[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' keyword_pattern")); Token * _literal; KeyPatternPair* elem; while ( @@ -27951,7 +28257,7 @@ _loop0_78_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_78[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_79[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' keyword_pattern")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -27964,14 +28270,14 @@ _loop0_78_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_78_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_79_type, _seq); p->level--; return _seq; } -// _gather_77: keyword_pattern _loop0_78 +// _gather_78: keyword_pattern _loop0_79 static asdl_seq * -_gather_77_rule(Parser *p) +_gather_78_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -27983,27 +28289,27 @@ _gather_77_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // keyword_pattern _loop0_78 + { // keyword_pattern _loop0_79 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_77[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "keyword_pattern _loop0_78")); + D(fprintf(stderr, "%*c> _gather_78[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "keyword_pattern _loop0_79")); KeyPatternPair* elem; asdl_seq * seq; if ( (elem = keyword_pattern_rule(p)) // keyword_pattern && - (seq = _loop0_78_rule(p)) // _loop0_78 + (seq = _loop0_79_rule(p)) // _loop0_79 ) { - D(fprintf(stderr, "%*c+ _gather_77[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "keyword_pattern _loop0_78")); + D(fprintf(stderr, "%*c+ _gather_78[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "keyword_pattern _loop0_79")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_77[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "keyword_pattern _loop0_78")); + D(fprintf(stderr, "%*c%s _gather_78[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "keyword_pattern _loop0_79")); } _res = NULL; done: @@ -28011,9 +28317,9 @@ _gather_77_rule(Parser *p) return _res; } -// _loop1_79: (',' expression) +// _loop1_80: (',' expression) static asdl_seq * -_loop1_79_rule(Parser *p) +_loop1_80_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -28040,13 +28346,13 @@ _loop1_79_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_79[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' expression)")); - void *_tmp_220_var; + D(fprintf(stderr, "%*c> _loop1_80[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' expression)")); + void *_tmp_221_var; while ( - (_tmp_220_var = _tmp_220_rule(p)) // ',' expression + (_tmp_221_var = _tmp_221_rule(p)) // ',' expression ) { - _res = _tmp_220_var; + _res = _tmp_221_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -28062,7 +28368,7 @@ _loop1_79_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_79[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_80[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' expression)")); } if (_n == 0 || p->error_indicator) { @@ -28080,14 +28386,14 @@ _loop1_79_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_79_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_80_type, _seq); p->level--; return _seq; } -// _loop1_80: (',' star_expression) +// _loop1_81: (',' star_expression) static asdl_seq * -_loop1_80_rule(Parser *p) +_loop1_81_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -28114,13 +28420,13 @@ _loop1_80_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_80[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_expression)")); - void *_tmp_221_var; + D(fprintf(stderr, "%*c> _loop1_81[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_expression)")); + void *_tmp_222_var; while ( - (_tmp_221_var = _tmp_221_rule(p)) // ',' star_expression + (_tmp_222_var = _tmp_222_rule(p)) // ',' star_expression ) { - _res = _tmp_221_var; + _res = _tmp_222_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -28136,7 +28442,7 @@ _loop1_80_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_80[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_81[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' star_expression)")); } if (_n == 0 || p->error_indicator) { @@ -28154,14 +28460,14 @@ _loop1_80_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_80_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_81_type, _seq); p->level--; return _seq; } -// _loop0_82: ',' star_named_expression +// _loop0_83: ',' star_named_expression static asdl_seq * -_loop0_82_rule(Parser *p) +_loop0_83_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -28188,7 +28494,7 @@ _loop0_82_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_82[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_named_expression")); + D(fprintf(stderr, "%*c> _loop0_83[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_named_expression")); Token * _literal; expr_ty elem; while ( @@ -28219,7 +28525,7 @@ _loop0_82_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_82[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_83[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_named_expression")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -28232,14 +28538,14 @@ _loop0_82_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_82_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_83_type, _seq); p->level--; return _seq; } -// _gather_81: star_named_expression _loop0_82 +// _gather_82: star_named_expression _loop0_83 static asdl_seq * -_gather_81_rule(Parser *p) +_gather_82_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -28251,27 +28557,27 @@ _gather_81_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // star_named_expression _loop0_82 + { // star_named_expression _loop0_83 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_81[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression _loop0_82")); + D(fprintf(stderr, "%*c> _gather_82[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression _loop0_83")); expr_ty elem; asdl_seq * seq; if ( (elem = star_named_expression_rule(p)) // star_named_expression && - (seq = _loop0_82_rule(p)) // _loop0_82 + (seq = _loop0_83_rule(p)) // _loop0_83 ) { - D(fprintf(stderr, "%*c+ _gather_81[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_named_expression _loop0_82")); + D(fprintf(stderr, "%*c+ _gather_82[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_named_expression _loop0_83")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_81[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expression _loop0_82")); + D(fprintf(stderr, "%*c%s _gather_82[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expression _loop0_83")); } _res = NULL; done: @@ -28279,9 +28585,9 @@ _gather_81_rule(Parser *p) return _res; } -// _loop1_83: ('or' conjunction) +// _loop1_84: ('or' conjunction) static asdl_seq * -_loop1_83_rule(Parser *p) +_loop1_84_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -28308,13 +28614,13 @@ _loop1_83_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_83[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('or' conjunction)")); - void *_tmp_222_var; + D(fprintf(stderr, "%*c> _loop1_84[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('or' conjunction)")); + void *_tmp_223_var; while ( - (_tmp_222_var = _tmp_222_rule(p)) // 'or' conjunction + (_tmp_223_var = _tmp_223_rule(p)) // 'or' conjunction ) { - _res = _tmp_222_var; + _res = _tmp_223_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -28330,7 +28636,7 @@ _loop1_83_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_83[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_84[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('or' conjunction)")); } if (_n == 0 || p->error_indicator) { @@ -28348,14 +28654,14 @@ _loop1_83_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_83_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_84_type, _seq); p->level--; return _seq; } -// _loop1_84: ('and' inversion) +// _loop1_85: ('and' inversion) static asdl_seq * -_loop1_84_rule(Parser *p) +_loop1_85_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -28382,13 +28688,13 @@ _loop1_84_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_84[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('and' inversion)")); - void *_tmp_223_var; + D(fprintf(stderr, "%*c> _loop1_85[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('and' inversion)")); + void *_tmp_224_var; while ( - (_tmp_223_var = _tmp_223_rule(p)) // 'and' inversion + (_tmp_224_var = _tmp_224_rule(p)) // 'and' inversion ) { - _res = _tmp_223_var; + _res = _tmp_224_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -28404,7 +28710,7 @@ _loop1_84_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_84[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_85[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('and' inversion)")); } if (_n == 0 || p->error_indicator) { @@ -28422,14 +28728,14 @@ _loop1_84_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_84_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_85_type, _seq); p->level--; return _seq; } -// _loop1_85: compare_op_bitwise_or_pair +// _loop1_86: compare_op_bitwise_or_pair static asdl_seq * -_loop1_85_rule(Parser *p) +_loop1_86_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -28456,7 +28762,7 @@ _loop1_85_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_85[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "compare_op_bitwise_or_pair")); + D(fprintf(stderr, "%*c> _loop1_86[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "compare_op_bitwise_or_pair")); CmpopExprPair* compare_op_bitwise_or_pair_var; while ( (compare_op_bitwise_or_pair_var = compare_op_bitwise_or_pair_rule(p)) // compare_op_bitwise_or_pair @@ -28478,7 +28784,7 @@ _loop1_85_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_85[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_86[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "compare_op_bitwise_or_pair")); } if (_n == 0 || p->error_indicator) { @@ -28496,14 +28802,14 @@ _loop1_85_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_85_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_86_type, _seq); p->level--; return _seq; } -// _tmp_86: '!=' +// _tmp_87: '!=' static void * -_tmp_86_rule(Parser *p) +_tmp_87_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -28520,13 +28826,13 @@ _tmp_86_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_86[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!='")); + D(fprintf(stderr, "%*c> _tmp_87[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!='")); Token * tok; if ( (tok = _PyPegen_expect_token(p, 28)) // token='!=' ) { - D(fprintf(stderr, "%*c+ _tmp_86[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!='")); + D(fprintf(stderr, "%*c+ _tmp_87[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!='")); _res = _PyPegen_check_barry_as_flufl ( p , tok ) ? NULL : tok; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -28536,7 +28842,7 @@ _tmp_86_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_86[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_87[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!='")); } _res = NULL; @@ -28545,9 +28851,9 @@ _tmp_86_rule(Parser *p) return _res; } -// _loop0_88: ',' slice +// _loop0_89: ',' (slice | starred_expression) static asdl_seq * -_loop0_88_rule(Parser *p) +_loop0_89_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -28569,18 +28875,18 @@ _loop0_88_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // ',' slice + { // ',' (slice | starred_expression) if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_88[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' slice")); + D(fprintf(stderr, "%*c> _loop0_89[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (slice | starred_expression)")); Token * _literal; - expr_ty elem; + void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = slice_rule(p)) // slice + (elem = _tmp_225_rule(p)) // slice | starred_expression ) { _res = elem; @@ -28605,8 +28911,8 @@ _loop0_88_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_88[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' slice")); + D(fprintf(stderr, "%*c%s _loop0_89[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (slice | starred_expression)")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -28618,14 +28924,14 @@ _loop0_88_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_88_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_89_type, _seq); p->level--; return _seq; } -// _gather_87: slice _loop0_88 +// _gather_88: (slice | starred_expression) _loop0_89 static asdl_seq * -_gather_87_rule(Parser *p) +_gather_88_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -28637,27 +28943,27 @@ _gather_87_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // slice _loop0_88 + { // (slice | starred_expression) _loop0_89 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_87[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slice _loop0_88")); - expr_ty elem; + D(fprintf(stderr, "%*c> _gather_88[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(slice | starred_expression) _loop0_89")); + void *elem; asdl_seq * seq; if ( - (elem = slice_rule(p)) // slice + (elem = _tmp_225_rule(p)) // slice | starred_expression && - (seq = _loop0_88_rule(p)) // _loop0_88 + (seq = _loop0_89_rule(p)) // _loop0_89 ) { - D(fprintf(stderr, "%*c+ _gather_87[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slice _loop0_88")); + D(fprintf(stderr, "%*c+ _gather_88[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(slice | starred_expression) _loop0_89")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_87[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slice _loop0_88")); + D(fprintf(stderr, "%*c%s _gather_88[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(slice | starred_expression) _loop0_89")); } _res = NULL; done: @@ -28665,9 +28971,9 @@ _gather_87_rule(Parser *p) return _res; } -// _tmp_89: ':' expression? +// _tmp_90: ':' expression? static void * -_tmp_89_rule(Parser *p) +_tmp_90_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -28684,7 +28990,7 @@ _tmp_89_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_89[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':' expression?")); + D(fprintf(stderr, "%*c> _tmp_90[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':' expression?")); Token * _literal; void *d; if ( @@ -28693,7 +28999,7 @@ _tmp_89_rule(Parser *p) (d = expression_rule(p), !p->error_indicator) // expression? ) { - D(fprintf(stderr, "%*c+ _tmp_89[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':' expression?")); + D(fprintf(stderr, "%*c+ _tmp_90[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':' expression?")); _res = d; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -28703,7 +29009,7 @@ _tmp_89_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_89[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_90[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':' expression?")); } _res = NULL; @@ -28712,9 +29018,9 @@ _tmp_89_rule(Parser *p) return _res; } -// _tmp_90: tuple | group | genexp +// _tmp_91: tuple | group | genexp static void * -_tmp_90_rule(Parser *p) +_tmp_91_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -28731,18 +29037,18 @@ _tmp_90_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_90[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple")); + D(fprintf(stderr, "%*c> _tmp_91[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple")); expr_ty tuple_var; if ( (tuple_var = tuple_rule(p)) // tuple ) { - D(fprintf(stderr, "%*c+ _tmp_90[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tuple")); + D(fprintf(stderr, "%*c+ _tmp_91[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tuple")); _res = tuple_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_90[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_91[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "tuple")); } { // group @@ -28750,18 +29056,18 @@ _tmp_90_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_90[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "group")); + D(fprintf(stderr, "%*c> _tmp_91[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "group")); expr_ty group_var; if ( (group_var = group_rule(p)) // group ) { - D(fprintf(stderr, "%*c+ _tmp_90[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "group")); + D(fprintf(stderr, "%*c+ _tmp_91[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "group")); _res = group_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_90[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_91[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "group")); } { // genexp @@ -28769,18 +29075,18 @@ _tmp_90_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_90[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "genexp")); + D(fprintf(stderr, "%*c> _tmp_91[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "genexp")); expr_ty genexp_var; if ( (genexp_var = genexp_rule(p)) // genexp ) { - D(fprintf(stderr, "%*c+ _tmp_90[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "genexp")); + D(fprintf(stderr, "%*c+ _tmp_91[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "genexp")); _res = genexp_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_90[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_91[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "genexp")); } _res = NULL; @@ -28789,9 +29095,9 @@ _tmp_90_rule(Parser *p) return _res; } -// _tmp_91: list | listcomp +// _tmp_92: list | listcomp static void * -_tmp_91_rule(Parser *p) +_tmp_92_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -28808,18 +29114,18 @@ _tmp_91_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_91[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list")); + D(fprintf(stderr, "%*c> _tmp_92[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list")); expr_ty list_var; if ( (list_var = list_rule(p)) // list ) { - D(fprintf(stderr, "%*c+ _tmp_91[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "list")); + D(fprintf(stderr, "%*c+ _tmp_92[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "list")); _res = list_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_91[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_92[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "list")); } { // listcomp @@ -28827,18 +29133,18 @@ _tmp_91_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_91[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "listcomp")); + D(fprintf(stderr, "%*c> _tmp_92[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "listcomp")); expr_ty listcomp_var; if ( (listcomp_var = listcomp_rule(p)) // listcomp ) { - D(fprintf(stderr, "%*c+ _tmp_91[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "listcomp")); + D(fprintf(stderr, "%*c+ _tmp_92[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "listcomp")); _res = listcomp_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_91[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_92[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "listcomp")); } _res = NULL; @@ -28847,9 +29153,9 @@ _tmp_91_rule(Parser *p) return _res; } -// _tmp_92: dict | set | dictcomp | setcomp +// _tmp_93: dict | set | dictcomp | setcomp static void * -_tmp_92_rule(Parser *p) +_tmp_93_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -28866,18 +29172,18 @@ _tmp_92_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_92[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dict")); + D(fprintf(stderr, "%*c> _tmp_93[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dict")); expr_ty dict_var; if ( (dict_var = dict_rule(p)) // dict ) { - D(fprintf(stderr, "%*c+ _tmp_92[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dict")); + D(fprintf(stderr, "%*c+ _tmp_93[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dict")); _res = dict_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_92[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_93[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dict")); } { // set @@ -28885,18 +29191,18 @@ _tmp_92_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_92[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "set")); + D(fprintf(stderr, "%*c> _tmp_93[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "set")); expr_ty set_var; if ( (set_var = set_rule(p)) // set ) { - D(fprintf(stderr, "%*c+ _tmp_92[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "set")); + D(fprintf(stderr, "%*c+ _tmp_93[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "set")); _res = set_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_92[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_93[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "set")); } { // dictcomp @@ -28904,18 +29210,18 @@ _tmp_92_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_92[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dictcomp")); + D(fprintf(stderr, "%*c> _tmp_93[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dictcomp")); expr_ty dictcomp_var; if ( (dictcomp_var = dictcomp_rule(p)) // dictcomp ) { - D(fprintf(stderr, "%*c+ _tmp_92[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dictcomp")); + D(fprintf(stderr, "%*c+ _tmp_93[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dictcomp")); _res = dictcomp_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_92[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_93[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dictcomp")); } { // setcomp @@ -28923,18 +29229,18 @@ _tmp_92_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_92[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "setcomp")); + D(fprintf(stderr, "%*c> _tmp_93[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "setcomp")); expr_ty setcomp_var; if ( (setcomp_var = setcomp_rule(p)) // setcomp ) { - D(fprintf(stderr, "%*c+ _tmp_92[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "setcomp")); + D(fprintf(stderr, "%*c+ _tmp_93[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "setcomp")); _res = setcomp_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_92[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_93[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "setcomp")); } _res = NULL; @@ -28943,9 +29249,9 @@ _tmp_92_rule(Parser *p) return _res; } -// _tmp_93: yield_expr | named_expression +// _tmp_94: yield_expr | named_expression static void * -_tmp_93_rule(Parser *p) +_tmp_94_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -28962,18 +29268,18 @@ _tmp_93_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_93[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_94[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); expr_ty yield_expr_var; if ( (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_93[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_94[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_93[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_94[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // named_expression @@ -28981,18 +29287,18 @@ _tmp_93_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_93[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "named_expression")); + D(fprintf(stderr, "%*c> _tmp_94[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "named_expression")); expr_ty named_expression_var; if ( (named_expression_var = named_expression_rule(p)) // named_expression ) { - D(fprintf(stderr, "%*c+ _tmp_93[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "named_expression")); + D(fprintf(stderr, "%*c+ _tmp_94[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "named_expression")); _res = named_expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_93[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_94[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "named_expression")); } _res = NULL; @@ -29001,9 +29307,9 @@ _tmp_93_rule(Parser *p) return _res; } -// _loop0_94: lambda_param_no_default +// _loop0_95: lambda_param_no_default static asdl_seq * -_loop0_94_rule(Parser *p) +_loop0_95_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -29030,7 +29336,7 @@ _loop0_94_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_94[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop0_95[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; while ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default @@ -29052,7 +29358,7 @@ _loop0_94_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_94[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_95[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -29065,14 +29371,14 @@ _loop0_94_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_94_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_95_type, _seq); p->level--; return _seq; } -// _loop0_95: lambda_param_with_default +// _loop0_96: lambda_param_with_default static asdl_seq * -_loop0_95_rule(Parser *p) +_loop0_96_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -29099,7 +29405,7 @@ _loop0_95_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_95[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c> _loop0_96[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); NameDefaultPair* lambda_param_with_default_var; while ( (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default @@ -29121,7 +29427,7 @@ _loop0_95_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_95[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_96[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -29134,14 +29440,14 @@ _loop0_95_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_95_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_96_type, _seq); p->level--; return _seq; } -// _loop0_96: lambda_param_with_default +// _loop0_97: lambda_param_with_default static asdl_seq * -_loop0_96_rule(Parser *p) +_loop0_97_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -29168,7 +29474,7 @@ _loop0_96_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_96[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c> _loop0_97[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); NameDefaultPair* lambda_param_with_default_var; while ( (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default @@ -29190,7 +29496,7 @@ _loop0_96_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_96[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_97[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -29203,14 +29509,14 @@ _loop0_96_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_96_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_97_type, _seq); p->level--; return _seq; } -// _loop1_97: lambda_param_no_default +// _loop1_98: lambda_param_no_default static asdl_seq * -_loop1_97_rule(Parser *p) +_loop1_98_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -29237,7 +29543,7 @@ _loop1_97_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_97[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop1_98[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; while ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default @@ -29259,7 +29565,7 @@ _loop1_97_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_97[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_98[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } if (_n == 0 || p->error_indicator) { @@ -29277,14 +29583,14 @@ _loop1_97_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_97_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_98_type, _seq); p->level--; return _seq; } -// _loop0_98: lambda_param_with_default +// _loop0_99: lambda_param_with_default static asdl_seq * -_loop0_98_rule(Parser *p) +_loop0_99_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -29311,7 +29617,7 @@ _loop0_98_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_98[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c> _loop0_99[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); NameDefaultPair* lambda_param_with_default_var; while ( (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default @@ -29333,7 +29639,7 @@ _loop0_98_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_98[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_99[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -29346,14 +29652,14 @@ _loop0_98_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_98_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_99_type, _seq); p->level--; return _seq; } -// _loop1_99: lambda_param_with_default +// _loop1_100: lambda_param_with_default static asdl_seq * -_loop1_99_rule(Parser *p) +_loop1_100_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -29380,7 +29686,7 @@ _loop1_99_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_99[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c> _loop1_100[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); NameDefaultPair* lambda_param_with_default_var; while ( (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default @@ -29402,7 +29708,7 @@ _loop1_99_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_99[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_100[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } if (_n == 0 || p->error_indicator) { @@ -29420,14 +29726,14 @@ _loop1_99_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_99_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_100_type, _seq); p->level--; return _seq; } -// _loop1_100: lambda_param_no_default +// _loop1_101: lambda_param_no_default static asdl_seq * -_loop1_100_rule(Parser *p) +_loop1_101_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -29454,7 +29760,7 @@ _loop1_100_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_100[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop1_101[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; while ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default @@ -29476,7 +29782,7 @@ _loop1_100_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_100[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_101[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } if (_n == 0 || p->error_indicator) { @@ -29494,14 +29800,14 @@ _loop1_100_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_100_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_101_type, _seq); p->level--; return _seq; } -// _loop1_101: lambda_param_no_default +// _loop1_102: lambda_param_no_default static asdl_seq * -_loop1_101_rule(Parser *p) +_loop1_102_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -29528,7 +29834,7 @@ _loop1_101_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_101[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop1_102[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; while ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default @@ -29550,7 +29856,7 @@ _loop1_101_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_101[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_102[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } if (_n == 0 || p->error_indicator) { @@ -29568,14 +29874,14 @@ _loop1_101_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_101_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_102_type, _seq); p->level--; return _seq; } -// _loop0_102: lambda_param_no_default +// _loop0_103: lambda_param_no_default static asdl_seq * -_loop0_102_rule(Parser *p) +_loop0_103_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -29602,7 +29908,7 @@ _loop0_102_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_102[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop0_103[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; while ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default @@ -29624,7 +29930,7 @@ _loop0_102_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_102[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_103[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -29637,14 +29943,14 @@ _loop0_102_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_102_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_103_type, _seq); p->level--; return _seq; } -// _loop1_103: lambda_param_with_default +// _loop1_104: lambda_param_with_default static asdl_seq * -_loop1_103_rule(Parser *p) +_loop1_104_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -29671,7 +29977,7 @@ _loop1_103_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_103[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c> _loop1_104[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); NameDefaultPair* lambda_param_with_default_var; while ( (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default @@ -29693,7 +29999,7 @@ _loop1_103_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_103[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_104[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } if (_n == 0 || p->error_indicator) { @@ -29711,14 +30017,14 @@ _loop1_103_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_103_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_104_type, _seq); p->level--; return _seq; } -// _loop0_104: lambda_param_no_default +// _loop0_105: lambda_param_no_default static asdl_seq * -_loop0_104_rule(Parser *p) +_loop0_105_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -29745,7 +30051,7 @@ _loop0_104_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_104[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop0_105[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; while ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default @@ -29767,7 +30073,7 @@ _loop0_104_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_104[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_105[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -29780,14 +30086,14 @@ _loop0_104_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_104_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_105_type, _seq); p->level--; return _seq; } -// _loop1_105: lambda_param_with_default +// _loop1_106: lambda_param_with_default static asdl_seq * -_loop1_105_rule(Parser *p) +_loop1_106_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -29814,7 +30120,7 @@ _loop1_105_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_105[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c> _loop1_106[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); NameDefaultPair* lambda_param_with_default_var; while ( (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default @@ -29836,7 +30142,7 @@ _loop1_105_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_105[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_106[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } if (_n == 0 || p->error_indicator) { @@ -29854,14 +30160,14 @@ _loop1_105_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_105_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_106_type, _seq); p->level--; return _seq; } -// _loop0_106: lambda_param_maybe_default +// _loop0_107: lambda_param_maybe_default static asdl_seq * -_loop0_106_rule(Parser *p) +_loop0_107_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -29888,7 +30194,7 @@ _loop0_106_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_106[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_107[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); NameDefaultPair* lambda_param_maybe_default_var; while ( (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default @@ -29910,7 +30216,7 @@ _loop0_106_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_106[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_107[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -29923,14 +30229,14 @@ _loop0_106_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_106_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_107_type, _seq); p->level--; return _seq; } -// _loop1_107: lambda_param_maybe_default +// _loop1_108: lambda_param_maybe_default static asdl_seq * -_loop1_107_rule(Parser *p) +_loop1_108_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -29957,7 +30263,7 @@ _loop1_107_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_107[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c> _loop1_108[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); NameDefaultPair* lambda_param_maybe_default_var; while ( (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default @@ -29979,7 +30285,7 @@ _loop1_107_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_107[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_108[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } if (_n == 0 || p->error_indicator) { @@ -29997,14 +30303,14 @@ _loop1_107_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_107_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_108_type, _seq); p->level--; return _seq; } -// _loop1_108: STRING +// _loop1_109: STRING static asdl_seq * -_loop1_108_rule(Parser *p) +_loop1_109_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -30031,7 +30337,7 @@ _loop1_108_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_108[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "STRING")); + D(fprintf(stderr, "%*c> _loop1_109[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "STRING")); expr_ty string_var; while ( (string_var = _PyPegen_string_token(p)) // STRING @@ -30053,7 +30359,7 @@ _loop1_108_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_108[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_109[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "STRING")); } if (_n == 0 || p->error_indicator) { @@ -30071,14 +30377,14 @@ _loop1_108_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_108_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_109_type, _seq); p->level--; return _seq; } -// _tmp_109: star_named_expression ',' star_named_expressions? +// _tmp_110: star_named_expression ',' star_named_expressions? static void * -_tmp_109_rule(Parser *p) +_tmp_110_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -30095,7 +30401,7 @@ _tmp_109_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_109[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions?")); + D(fprintf(stderr, "%*c> _tmp_110[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions?")); Token * _literal; expr_ty y; void *z; @@ -30107,7 +30413,7 @@ _tmp_109_rule(Parser *p) (z = star_named_expressions_rule(p), !p->error_indicator) // star_named_expressions? ) { - D(fprintf(stderr, "%*c+ _tmp_109[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions?")); + D(fprintf(stderr, "%*c+ _tmp_110[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions?")); _res = _PyPegen_seq_insert_in_front ( p , y , z ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -30117,7 +30423,7 @@ _tmp_109_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_109[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_110[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expression ',' star_named_expressions?")); } _res = NULL; @@ -30126,9 +30432,9 @@ _tmp_109_rule(Parser *p) return _res; } -// _loop0_111: ',' double_starred_kvpair +// _loop0_112: ',' double_starred_kvpair static asdl_seq * -_loop0_111_rule(Parser *p) +_loop0_112_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -30155,7 +30461,7 @@ _loop0_111_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_111[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair")); + D(fprintf(stderr, "%*c> _loop0_112[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair")); Token * _literal; KeyValuePair* elem; while ( @@ -30186,7 +30492,7 @@ _loop0_111_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_111[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_112[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' double_starred_kvpair")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -30199,14 +30505,14 @@ _loop0_111_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_111_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_112_type, _seq); p->level--; return _seq; } -// _gather_110: double_starred_kvpair _loop0_111 +// _gather_111: double_starred_kvpair _loop0_112 static asdl_seq * -_gather_110_rule(Parser *p) +_gather_111_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -30218,27 +30524,27 @@ _gather_110_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // double_starred_kvpair _loop0_111 + { // double_starred_kvpair _loop0_112 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_110[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_111")); + D(fprintf(stderr, "%*c> _gather_111[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_112")); KeyValuePair* elem; asdl_seq * seq; if ( (elem = double_starred_kvpair_rule(p)) // double_starred_kvpair && - (seq = _loop0_111_rule(p)) // _loop0_111 + (seq = _loop0_112_rule(p)) // _loop0_112 ) { - D(fprintf(stderr, "%*c+ _gather_110[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_111")); + D(fprintf(stderr, "%*c+ _gather_111[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_112")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_110[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_111")); + D(fprintf(stderr, "%*c%s _gather_111[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_112")); } _res = NULL; done: @@ -30246,9 +30552,9 @@ _gather_110_rule(Parser *p) return _res; } -// _loop1_112: for_if_clause +// _loop1_113: for_if_clause static asdl_seq * -_loop1_112_rule(Parser *p) +_loop1_113_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -30275,7 +30581,7 @@ _loop1_112_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_112[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "for_if_clause")); + D(fprintf(stderr, "%*c> _loop1_113[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "for_if_clause")); comprehension_ty for_if_clause_var; while ( (for_if_clause_var = for_if_clause_rule(p)) // for_if_clause @@ -30297,7 +30603,7 @@ _loop1_112_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_112[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_113[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "for_if_clause")); } if (_n == 0 || p->error_indicator) { @@ -30315,14 +30621,14 @@ _loop1_112_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_112_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_113_type, _seq); p->level--; return _seq; } -// _loop0_113: ('if' disjunction) +// _loop0_114: ('if' disjunction) static asdl_seq * -_loop0_113_rule(Parser *p) +_loop0_114_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -30349,13 +30655,13 @@ _loop0_113_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_113[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); - void *_tmp_224_var; + D(fprintf(stderr, "%*c> _loop0_114[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); + void *_tmp_226_var; while ( - (_tmp_224_var = _tmp_224_rule(p)) // 'if' disjunction + (_tmp_226_var = _tmp_226_rule(p)) // 'if' disjunction ) { - _res = _tmp_224_var; + _res = _tmp_226_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -30371,7 +30677,7 @@ _loop0_113_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_113[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_114[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('if' disjunction)")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -30384,14 +30690,14 @@ _loop0_113_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_113_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_114_type, _seq); p->level--; return _seq; } -// _loop0_114: ('if' disjunction) +// _loop0_115: ('if' disjunction) static asdl_seq * -_loop0_114_rule(Parser *p) +_loop0_115_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -30418,13 +30724,13 @@ _loop0_114_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_114[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); - void *_tmp_225_var; + D(fprintf(stderr, "%*c> _loop0_115[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); + void *_tmp_227_var; while ( - (_tmp_225_var = _tmp_225_rule(p)) // 'if' disjunction + (_tmp_227_var = _tmp_227_rule(p)) // 'if' disjunction ) { - _res = _tmp_225_var; + _res = _tmp_227_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -30440,7 +30746,7 @@ _loop0_114_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_114[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_115[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('if' disjunction)")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -30453,14 +30759,14 @@ _loop0_114_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_114_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_115_type, _seq); p->level--; return _seq; } -// _tmp_115: assignment_expression | expression !':=' +// _tmp_116: assignment_expression | expression !':=' static void * -_tmp_115_rule(Parser *p) +_tmp_116_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -30477,18 +30783,18 @@ _tmp_115_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_115[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + D(fprintf(stderr, "%*c> _tmp_116[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); expr_ty assignment_expression_var; if ( (assignment_expression_var = assignment_expression_rule(p)) // assignment_expression ) { - D(fprintf(stderr, "%*c+ _tmp_115[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + D(fprintf(stderr, "%*c+ _tmp_116[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression")); _res = assignment_expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_115[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_116[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "assignment_expression")); } { // expression !':=' @@ -30496,7 +30802,7 @@ _tmp_115_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_115[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); + D(fprintf(stderr, "%*c> _tmp_116[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); expr_ty expression_var; if ( (expression_var = expression_rule(p)) // expression @@ -30504,12 +30810,12 @@ _tmp_115_rule(Parser *p) _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 53) // token=':=' ) { - D(fprintf(stderr, "%*c+ _tmp_115[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); + D(fprintf(stderr, "%*c+ _tmp_116[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); _res = expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_115[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_116[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression !':='")); } _res = NULL; @@ -30518,9 +30824,9 @@ _tmp_115_rule(Parser *p) return _res; } -// _loop0_117: ',' (starred_expression | (assignment_expression | expression !':=') !'=') +// _loop0_118: ',' (starred_expression | (assignment_expression | expression !':=') !'=') static asdl_seq * -_loop0_117_rule(Parser *p) +_loop0_118_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -30547,13 +30853,13 @@ _loop0_117_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_117[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (starred_expression | (assignment_expression | expression !':=') !'=')")); + D(fprintf(stderr, "%*c> _loop0_118[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (starred_expression | (assignment_expression | expression !':=') !'=')")); Token * _literal; void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_226_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' + (elem = _tmp_228_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' ) { _res = elem; @@ -30578,7 +30884,7 @@ _loop0_117_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_117[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_118[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (starred_expression | (assignment_expression | expression !':=') !'=')")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -30591,15 +30897,15 @@ _loop0_117_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_117_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_118_type, _seq); p->level--; return _seq; } -// _gather_116: -// | (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_117 +// _gather_117: +// | (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_118 static asdl_seq * -_gather_116_rule(Parser *p) +_gather_117_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -30611,27 +30917,27 @@ _gather_116_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_117 + { // (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_118 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_116[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_117")); + D(fprintf(stderr, "%*c> _gather_117[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_118")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_226_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' + (elem = _tmp_228_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' && - (seq = _loop0_117_rule(p)) // _loop0_117 + (seq = _loop0_118_rule(p)) // _loop0_118 ) { - D(fprintf(stderr, "%*c+ _gather_116[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_117")); + D(fprintf(stderr, "%*c+ _gather_117[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_118")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_116[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_117")); + D(fprintf(stderr, "%*c%s _gather_117[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_118")); } _res = NULL; done: @@ -30639,9 +30945,9 @@ _gather_116_rule(Parser *p) return _res; } -// _tmp_118: ',' kwargs +// _tmp_119: ',' kwargs static void * -_tmp_118_rule(Parser *p) +_tmp_119_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -30658,7 +30964,7 @@ _tmp_118_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_118[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwargs")); + D(fprintf(stderr, "%*c> _tmp_119[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwargs")); Token * _literal; asdl_seq* k; if ( @@ -30667,7 +30973,7 @@ _tmp_118_rule(Parser *p) (k = kwargs_rule(p)) // kwargs ) { - D(fprintf(stderr, "%*c+ _tmp_118[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' kwargs")); + D(fprintf(stderr, "%*c+ _tmp_119[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' kwargs")); _res = k; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -30677,7 +30983,7 @@ _tmp_118_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_118[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_119[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwargs")); } _res = NULL; @@ -30686,9 +30992,9 @@ _tmp_118_rule(Parser *p) return _res; } -// _loop0_120: ',' kwarg_or_starred +// _loop0_121: ',' kwarg_or_starred static asdl_seq * -_loop0_120_rule(Parser *p) +_loop0_121_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -30715,7 +31021,7 @@ _loop0_120_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_120[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_starred")); + D(fprintf(stderr, "%*c> _loop0_121[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_starred")); Token * _literal; KeywordOrStarred* elem; while ( @@ -30746,7 +31052,7 @@ _loop0_120_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_120[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_121[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_starred")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -30759,14 +31065,14 @@ _loop0_120_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_120_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_121_type, _seq); p->level--; return _seq; } -// _gather_119: kwarg_or_starred _loop0_120 +// _gather_120: kwarg_or_starred _loop0_121 static asdl_seq * -_gather_119_rule(Parser *p) +_gather_120_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -30778,27 +31084,27 @@ _gather_119_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // kwarg_or_starred _loop0_120 + { // kwarg_or_starred _loop0_121 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_119[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_120")); + D(fprintf(stderr, "%*c> _gather_120[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_121")); KeywordOrStarred* elem; asdl_seq * seq; if ( (elem = kwarg_or_starred_rule(p)) // kwarg_or_starred && - (seq = _loop0_120_rule(p)) // _loop0_120 + (seq = _loop0_121_rule(p)) // _loop0_121 ) { - D(fprintf(stderr, "%*c+ _gather_119[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_120")); + D(fprintf(stderr, "%*c+ _gather_120[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_121")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_119[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_starred _loop0_120")); + D(fprintf(stderr, "%*c%s _gather_120[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_starred _loop0_121")); } _res = NULL; done: @@ -30806,9 +31112,9 @@ _gather_119_rule(Parser *p) return _res; } -// _loop0_122: ',' kwarg_or_double_starred +// _loop0_123: ',' kwarg_or_double_starred static asdl_seq * -_loop0_122_rule(Parser *p) +_loop0_123_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -30835,7 +31141,7 @@ _loop0_122_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_122[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_double_starred")); + D(fprintf(stderr, "%*c> _loop0_123[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_double_starred")); Token * _literal; KeywordOrStarred* elem; while ( @@ -30866,7 +31172,7 @@ _loop0_122_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_122[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_123[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_double_starred")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -30879,14 +31185,14 @@ _loop0_122_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_122_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_123_type, _seq); p->level--; return _seq; } -// _gather_121: kwarg_or_double_starred _loop0_122 +// _gather_122: kwarg_or_double_starred _loop0_123 static asdl_seq * -_gather_121_rule(Parser *p) +_gather_122_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -30898,27 +31204,27 @@ _gather_121_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // kwarg_or_double_starred _loop0_122 + { // kwarg_or_double_starred _loop0_123 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_121[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_122")); + D(fprintf(stderr, "%*c> _gather_122[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_123")); KeywordOrStarred* elem; asdl_seq * seq; if ( (elem = kwarg_or_double_starred_rule(p)) // kwarg_or_double_starred && - (seq = _loop0_122_rule(p)) // _loop0_122 + (seq = _loop0_123_rule(p)) // _loop0_123 ) { - D(fprintf(stderr, "%*c+ _gather_121[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_122")); + D(fprintf(stderr, "%*c+ _gather_122[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_123")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_121[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_double_starred _loop0_122")); + D(fprintf(stderr, "%*c%s _gather_122[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_double_starred _loop0_123")); } _res = NULL; done: @@ -30926,9 +31232,9 @@ _gather_121_rule(Parser *p) return _res; } -// _loop0_124: ',' kwarg_or_starred +// _loop0_125: ',' kwarg_or_starred static asdl_seq * -_loop0_124_rule(Parser *p) +_loop0_125_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -30955,7 +31261,7 @@ _loop0_124_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_124[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_starred")); + D(fprintf(stderr, "%*c> _loop0_125[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_starred")); Token * _literal; KeywordOrStarred* elem; while ( @@ -30986,7 +31292,7 @@ _loop0_124_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_124[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_125[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_starred")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -30999,14 +31305,14 @@ _loop0_124_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_124_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_125_type, _seq); p->level--; return _seq; } -// _gather_123: kwarg_or_starred _loop0_124 +// _gather_124: kwarg_or_starred _loop0_125 static asdl_seq * -_gather_123_rule(Parser *p) +_gather_124_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -31018,27 +31324,27 @@ _gather_123_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // kwarg_or_starred _loop0_124 + { // kwarg_or_starred _loop0_125 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_123[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_124")); + D(fprintf(stderr, "%*c> _gather_124[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_125")); KeywordOrStarred* elem; asdl_seq * seq; if ( (elem = kwarg_or_starred_rule(p)) // kwarg_or_starred && - (seq = _loop0_124_rule(p)) // _loop0_124 + (seq = _loop0_125_rule(p)) // _loop0_125 ) { - D(fprintf(stderr, "%*c+ _gather_123[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_124")); + D(fprintf(stderr, "%*c+ _gather_124[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_125")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_123[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_starred _loop0_124")); + D(fprintf(stderr, "%*c%s _gather_124[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_starred _loop0_125")); } _res = NULL; done: @@ -31046,9 +31352,9 @@ _gather_123_rule(Parser *p) return _res; } -// _loop0_126: ',' kwarg_or_double_starred +// _loop0_127: ',' kwarg_or_double_starred static asdl_seq * -_loop0_126_rule(Parser *p) +_loop0_127_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -31075,7 +31381,7 @@ _loop0_126_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_126[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_double_starred")); + D(fprintf(stderr, "%*c> _loop0_127[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_double_starred")); Token * _literal; KeywordOrStarred* elem; while ( @@ -31106,7 +31412,7 @@ _loop0_126_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_126[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_127[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_double_starred")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31119,14 +31425,14 @@ _loop0_126_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_126_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_127_type, _seq); p->level--; return _seq; } -// _gather_125: kwarg_or_double_starred _loop0_126 +// _gather_126: kwarg_or_double_starred _loop0_127 static asdl_seq * -_gather_125_rule(Parser *p) +_gather_126_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -31138,27 +31444,27 @@ _gather_125_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // kwarg_or_double_starred _loop0_126 + { // kwarg_or_double_starred _loop0_127 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_125[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_126")); + D(fprintf(stderr, "%*c> _gather_126[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_127")); KeywordOrStarred* elem; asdl_seq * seq; if ( (elem = kwarg_or_double_starred_rule(p)) // kwarg_or_double_starred && - (seq = _loop0_126_rule(p)) // _loop0_126 + (seq = _loop0_127_rule(p)) // _loop0_127 ) { - D(fprintf(stderr, "%*c+ _gather_125[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_126")); + D(fprintf(stderr, "%*c+ _gather_126[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_127")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_125[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_double_starred _loop0_126")); + D(fprintf(stderr, "%*c%s _gather_126[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_double_starred _loop0_127")); } _res = NULL; done: @@ -31166,9 +31472,9 @@ _gather_125_rule(Parser *p) return _res; } -// _loop0_127: (',' star_target) +// _loop0_128: (',' star_target) static asdl_seq * -_loop0_127_rule(Parser *p) +_loop0_128_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -31195,13 +31501,13 @@ _loop0_127_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_127[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); - void *_tmp_227_var; + D(fprintf(stderr, "%*c> _loop0_128[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); + void *_tmp_229_var; while ( - (_tmp_227_var = _tmp_227_rule(p)) // ',' star_target + (_tmp_229_var = _tmp_229_rule(p)) // ',' star_target ) { - _res = _tmp_227_var; + _res = _tmp_229_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -31217,7 +31523,7 @@ _loop0_127_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_127[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_128[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' star_target)")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31230,14 +31536,14 @@ _loop0_127_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_127_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_128_type, _seq); p->level--; return _seq; } -// _loop0_129: ',' star_target +// _loop0_130: ',' star_target static asdl_seq * -_loop0_129_rule(Parser *p) +_loop0_130_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -31264,7 +31570,7 @@ _loop0_129_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_129[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c> _loop0_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); Token * _literal; expr_ty elem; while ( @@ -31295,7 +31601,7 @@ _loop0_129_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_129[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_130[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31308,14 +31614,14 @@ _loop0_129_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_129_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_130_type, _seq); p->level--; return _seq; } -// _gather_128: star_target _loop0_129 +// _gather_129: star_target _loop0_130 static asdl_seq * -_gather_128_rule(Parser *p) +_gather_129_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -31327,27 +31633,27 @@ _gather_128_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // star_target _loop0_129 + { // star_target _loop0_130 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_128[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target _loop0_129")); + D(fprintf(stderr, "%*c> _gather_129[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target _loop0_130")); expr_ty elem; asdl_seq * seq; if ( (elem = star_target_rule(p)) // star_target && - (seq = _loop0_129_rule(p)) // _loop0_129 + (seq = _loop0_130_rule(p)) // _loop0_130 ) { - D(fprintf(stderr, "%*c+ _gather_128[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_target _loop0_129")); + D(fprintf(stderr, "%*c+ _gather_129[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_target _loop0_130")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_128[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_target _loop0_129")); + D(fprintf(stderr, "%*c%s _gather_129[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_target _loop0_130")); } _res = NULL; done: @@ -31355,9 +31661,9 @@ _gather_128_rule(Parser *p) return _res; } -// _loop1_130: (',' star_target) +// _loop1_131: (',' star_target) static asdl_seq * -_loop1_130_rule(Parser *p) +_loop1_131_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -31384,13 +31690,13 @@ _loop1_130_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); - void *_tmp_228_var; + D(fprintf(stderr, "%*c> _loop1_131[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); + void *_tmp_230_var; while ( - (_tmp_228_var = _tmp_228_rule(p)) // ',' star_target + (_tmp_230_var = _tmp_230_rule(p)) // ',' star_target ) { - _res = _tmp_228_var; + _res = _tmp_230_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -31406,7 +31712,7 @@ _loop1_130_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_130[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_131[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' star_target)")); } if (_n == 0 || p->error_indicator) { @@ -31424,14 +31730,14 @@ _loop1_130_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_130_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_131_type, _seq); p->level--; return _seq; } -// _tmp_131: !'*' star_target +// _tmp_132: !'*' star_target static void * -_tmp_131_rule(Parser *p) +_tmp_132_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -31448,7 +31754,7 @@ _tmp_131_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_131[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "!'*' star_target")); + D(fprintf(stderr, "%*c> _tmp_132[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "!'*' star_target")); expr_ty star_target_var; if ( _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 16) // token='*' @@ -31456,12 +31762,12 @@ _tmp_131_rule(Parser *p) (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_131[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!'*' star_target")); + D(fprintf(stderr, "%*c+ _tmp_132[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!'*' star_target")); _res = star_target_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_131[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_132[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "!'*' star_target")); } _res = NULL; @@ -31470,9 +31776,9 @@ _tmp_131_rule(Parser *p) return _res; } -// _loop0_133: ',' del_target +// _loop0_134: ',' del_target static asdl_seq * -_loop0_133_rule(Parser *p) +_loop0_134_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -31499,7 +31805,7 @@ _loop0_133_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_133[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' del_target")); + D(fprintf(stderr, "%*c> _loop0_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' del_target")); Token * _literal; expr_ty elem; while ( @@ -31530,7 +31836,7 @@ _loop0_133_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_133[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_134[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' del_target")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31543,14 +31849,14 @@ _loop0_133_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_133_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_134_type, _seq); p->level--; return _seq; } -// _gather_132: del_target _loop0_133 +// _gather_133: del_target _loop0_134 static asdl_seq * -_gather_132_rule(Parser *p) +_gather_133_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -31562,27 +31868,27 @@ _gather_132_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // del_target _loop0_133 + { // del_target _loop0_134 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_132[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "del_target _loop0_133")); + D(fprintf(stderr, "%*c> _gather_133[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "del_target _loop0_134")); expr_ty elem; asdl_seq * seq; if ( (elem = del_target_rule(p)) // del_target && - (seq = _loop0_133_rule(p)) // _loop0_133 + (seq = _loop0_134_rule(p)) // _loop0_134 ) { - D(fprintf(stderr, "%*c+ _gather_132[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "del_target _loop0_133")); + D(fprintf(stderr, "%*c+ _gather_133[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "del_target _loop0_134")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_132[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "del_target _loop0_133")); + D(fprintf(stderr, "%*c%s _gather_133[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "del_target _loop0_134")); } _res = NULL; done: @@ -31590,9 +31896,9 @@ _gather_132_rule(Parser *p) return _res; } -// _loop0_135: ',' expression +// _loop0_136: ',' expression static asdl_seq * -_loop0_135_rule(Parser *p) +_loop0_136_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -31619,7 +31925,7 @@ _loop0_135_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c> _loop0_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); Token * _literal; expr_ty elem; while ( @@ -31650,7 +31956,7 @@ _loop0_135_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_135[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_136[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31663,14 +31969,14 @@ _loop0_135_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_135_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_136_type, _seq); p->level--; return _seq; } -// _gather_134: expression _loop0_135 +// _gather_135: expression _loop0_136 static asdl_seq * -_gather_134_rule(Parser *p) +_gather_135_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -31682,27 +31988,27 @@ _gather_134_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // expression _loop0_135 + { // expression _loop0_136 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_135")); + D(fprintf(stderr, "%*c> _gather_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_136")); expr_ty elem; asdl_seq * seq; if ( (elem = expression_rule(p)) // expression && - (seq = _loop0_135_rule(p)) // _loop0_135 + (seq = _loop0_136_rule(p)) // _loop0_136 ) { - D(fprintf(stderr, "%*c+ _gather_134[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_135")); + D(fprintf(stderr, "%*c+ _gather_135[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_136")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_134[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_135")); + D(fprintf(stderr, "%*c%s _gather_135[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_136")); } _res = NULL; done: @@ -31710,9 +32016,9 @@ _gather_134_rule(Parser *p) return _res; } -// _loop0_137: ',' expression +// _loop0_138: ',' expression static asdl_seq * -_loop0_137_rule(Parser *p) +_loop0_138_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -31739,7 +32045,7 @@ _loop0_137_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c> _loop0_138[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); Token * _literal; expr_ty elem; while ( @@ -31770,7 +32076,7 @@ _loop0_137_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_137[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_138[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31783,14 +32089,14 @@ _loop0_137_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_137_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_138_type, _seq); p->level--; return _seq; } -// _gather_136: expression _loop0_137 +// _gather_137: expression _loop0_138 static asdl_seq * -_gather_136_rule(Parser *p) +_gather_137_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -31802,27 +32108,27 @@ _gather_136_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // expression _loop0_137 + { // expression _loop0_138 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_137")); + D(fprintf(stderr, "%*c> _gather_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_138")); expr_ty elem; asdl_seq * seq; if ( (elem = expression_rule(p)) // expression && - (seq = _loop0_137_rule(p)) // _loop0_137 + (seq = _loop0_138_rule(p)) // _loop0_138 ) { - D(fprintf(stderr, "%*c+ _gather_136[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_137")); + D(fprintf(stderr, "%*c+ _gather_137[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_138")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_136[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_137")); + D(fprintf(stderr, "%*c%s _gather_137[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_138")); } _res = NULL; done: @@ -31830,9 +32136,9 @@ _gather_136_rule(Parser *p) return _res; } -// _loop0_139: ',' expression +// _loop0_140: ',' expression static asdl_seq * -_loop0_139_rule(Parser *p) +_loop0_140_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -31859,7 +32165,7 @@ _loop0_139_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_139[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c> _loop0_140[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); Token * _literal; expr_ty elem; while ( @@ -31890,7 +32196,7 @@ _loop0_139_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_139[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_140[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31903,14 +32209,14 @@ _loop0_139_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_139_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_140_type, _seq); p->level--; return _seq; } -// _gather_138: expression _loop0_139 +// _gather_139: expression _loop0_140 static asdl_seq * -_gather_138_rule(Parser *p) +_gather_139_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -31922,27 +32228,27 @@ _gather_138_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // expression _loop0_139 + { // expression _loop0_140 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_138[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_139")); + D(fprintf(stderr, "%*c> _gather_139[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_140")); expr_ty elem; asdl_seq * seq; if ( (elem = expression_rule(p)) // expression && - (seq = _loop0_139_rule(p)) // _loop0_139 + (seq = _loop0_140_rule(p)) // _loop0_140 ) { - D(fprintf(stderr, "%*c+ _gather_138[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_139")); + D(fprintf(stderr, "%*c+ _gather_139[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_140")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_138[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_139")); + D(fprintf(stderr, "%*c%s _gather_139[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_140")); } _res = NULL; done: @@ -31950,9 +32256,9 @@ _gather_138_rule(Parser *p) return _res; } -// _loop0_141: ',' expression +// _loop0_142: ',' expression static asdl_seq * -_loop0_141_rule(Parser *p) +_loop0_142_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -31979,7 +32285,7 @@ _loop0_141_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_141[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c> _loop0_142[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); Token * _literal; expr_ty elem; while ( @@ -32010,7 +32316,7 @@ _loop0_141_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_141[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_142[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -32023,14 +32329,14 @@ _loop0_141_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_141_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_142_type, _seq); p->level--; return _seq; } -// _gather_140: expression _loop0_141 +// _gather_141: expression _loop0_142 static asdl_seq * -_gather_140_rule(Parser *p) +_gather_141_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -32042,27 +32348,27 @@ _gather_140_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // expression _loop0_141 + { // expression _loop0_142 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_140[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_141")); + D(fprintf(stderr, "%*c> _gather_141[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_142")); expr_ty elem; asdl_seq * seq; if ( (elem = expression_rule(p)) // expression && - (seq = _loop0_141_rule(p)) // _loop0_141 + (seq = _loop0_142_rule(p)) // _loop0_142 ) { - D(fprintf(stderr, "%*c+ _gather_140[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_141")); + D(fprintf(stderr, "%*c+ _gather_141[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_142")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_140[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_141")); + D(fprintf(stderr, "%*c%s _gather_141[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_142")); } _res = NULL; done: @@ -32070,9 +32376,9 @@ _gather_140_rule(Parser *p) return _res; } -// _tmp_142: NEWLINE INDENT +// _tmp_143: NEWLINE INDENT static void * -_tmp_142_rule(Parser *p) +_tmp_143_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -32089,7 +32395,7 @@ _tmp_142_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_142[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT")); + D(fprintf(stderr, "%*c> _tmp_143[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT")); Token * indent_var; Token * newline_var; if ( @@ -32098,12 +32404,12 @@ _tmp_142_rule(Parser *p) (indent_var = _PyPegen_expect_token(p, INDENT)) // token='INDENT' ) { - D(fprintf(stderr, "%*c+ _tmp_142[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT")); + D(fprintf(stderr, "%*c+ _tmp_143[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT")); _res = _PyPegen_dummy_name(p, newline_var, indent_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_142[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_143[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE INDENT")); } _res = NULL; @@ -32112,9 +32418,9 @@ _tmp_142_rule(Parser *p) return _res; } -// _tmp_143: args | expression for_if_clauses +// _tmp_144: args | expression for_if_clauses static void * -_tmp_143_rule(Parser *p) +_tmp_144_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -32131,18 +32437,18 @@ _tmp_143_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_143[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args")); + D(fprintf(stderr, "%*c> _tmp_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args")); expr_ty args_var; if ( (args_var = args_rule(p)) // args ) { - D(fprintf(stderr, "%*c+ _tmp_143[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args")); + D(fprintf(stderr, "%*c+ _tmp_144[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args")); _res = args_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_143[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_144[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "args")); } { // expression for_if_clauses @@ -32150,7 +32456,7 @@ _tmp_143_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_143[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); + D(fprintf(stderr, "%*c> _tmp_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); expr_ty expression_var; asdl_comprehension_seq* for_if_clauses_var; if ( @@ -32159,12 +32465,12 @@ _tmp_143_rule(Parser *p) (for_if_clauses_var = for_if_clauses_rule(p)) // for_if_clauses ) { - D(fprintf(stderr, "%*c+ _tmp_143[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); + D(fprintf(stderr, "%*c+ _tmp_144[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); _res = _PyPegen_dummy_name(p, expression_var, for_if_clauses_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_143[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_144[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression for_if_clauses")); } _res = NULL; @@ -32173,9 +32479,9 @@ _tmp_143_rule(Parser *p) return _res; } -// _tmp_144: 'True' | 'False' | 'None' +// _tmp_145: 'True' | 'False' | 'None' static void * -_tmp_144_rule(Parser *p) +_tmp_145_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -32192,18 +32498,18 @@ _tmp_144_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); + D(fprintf(stderr, "%*c> _tmp_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 600)) // token='True' ) { - D(fprintf(stderr, "%*c+ _tmp_144[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); + D(fprintf(stderr, "%*c+ _tmp_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_144[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_145[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'True'")); } { // 'False' @@ -32211,18 +32517,18 @@ _tmp_144_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); + D(fprintf(stderr, "%*c> _tmp_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 602)) // token='False' ) { - D(fprintf(stderr, "%*c+ _tmp_144[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); + D(fprintf(stderr, "%*c+ _tmp_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_144[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_145[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'False'")); } { // 'None' @@ -32230,18 +32536,18 @@ _tmp_144_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); + D(fprintf(stderr, "%*c> _tmp_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 601)) // token='None' ) { - D(fprintf(stderr, "%*c+ _tmp_144[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); + D(fprintf(stderr, "%*c+ _tmp_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_144[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_145[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'None'")); } _res = NULL; @@ -32250,9 +32556,9 @@ _tmp_144_rule(Parser *p) return _res; } -// _tmp_145: NAME '=' +// _tmp_146: NAME '=' static void * -_tmp_145_rule(Parser *p) +_tmp_146_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -32269,7 +32575,7 @@ _tmp_145_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '='")); + D(fprintf(stderr, "%*c> _tmp_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '='")); Token * _literal; expr_ty name_var; if ( @@ -32278,12 +32584,12 @@ _tmp_145_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '='")); + D(fprintf(stderr, "%*c+ _tmp_146[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '='")); _res = _PyPegen_dummy_name(p, name_var, _literal); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_145[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_146[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME '='")); } _res = NULL; @@ -32292,9 +32598,9 @@ _tmp_145_rule(Parser *p) return _res; } -// _tmp_146: NAME STRING | SOFT_KEYWORD +// _tmp_147: NAME STRING | SOFT_KEYWORD static void * -_tmp_146_rule(Parser *p) +_tmp_147_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -32311,7 +32617,7 @@ _tmp_146_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME STRING")); + D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME STRING")); expr_ty name_var; expr_ty string_var; if ( @@ -32320,12 +32626,12 @@ _tmp_146_rule(Parser *p) (string_var = _PyPegen_string_token(p)) // STRING ) { - D(fprintf(stderr, "%*c+ _tmp_146[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME STRING")); + D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME STRING")); _res = _PyPegen_dummy_name(p, name_var, string_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_146[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME STRING")); } { // SOFT_KEYWORD @@ -32333,18 +32639,18 @@ _tmp_146_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD")); + D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD")); expr_ty soft_keyword_var; if ( (soft_keyword_var = _PyPegen_soft_keyword_token(p)) // SOFT_KEYWORD ) { - D(fprintf(stderr, "%*c+ _tmp_146[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD")); + D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD")); _res = soft_keyword_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_146[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "SOFT_KEYWORD")); } _res = NULL; @@ -32353,9 +32659,9 @@ _tmp_146_rule(Parser *p) return _res; } -// _tmp_147: 'else' | ':' +// _tmp_148: 'else' | ':' static void * -_tmp_147_rule(Parser *p) +_tmp_148_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -32372,18 +32678,18 @@ _tmp_147_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'else'")); + D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'else'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 637)) // token='else' ) { - D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'else'")); + D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'else'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_148[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'else'")); } { // ':' @@ -32391,18 +32697,18 @@ _tmp_147_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_148[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } _res = NULL; @@ -32411,9 +32717,9 @@ _tmp_147_rule(Parser *p) return _res; } -// _tmp_148: '=' | ':=' +// _tmp_149: '=' | ':=' static void * -_tmp_148_rule(Parser *p) +_tmp_149_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -32430,18 +32736,18 @@ _tmp_148_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c> _tmp_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c+ _tmp_149[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_148[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_149[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); } { // ':=' @@ -32449,18 +32755,18 @@ _tmp_148_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); + D(fprintf(stderr, "%*c> _tmp_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 53)) // token=':=' ) { - D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='")); + D(fprintf(stderr, "%*c+ _tmp_149[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_148[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_149[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':='")); } _res = NULL; @@ -32469,9 +32775,9 @@ _tmp_148_rule(Parser *p) return _res; } -// _tmp_149: list | tuple | genexp | 'True' | 'None' | 'False' +// _tmp_150: list | tuple | genexp | 'True' | 'None' | 'False' static void * -_tmp_149_rule(Parser *p) +_tmp_150_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -32488,18 +32794,18 @@ _tmp_149_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list")); + D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list")); expr_ty list_var; if ( (list_var = list_rule(p)) // list ) { - D(fprintf(stderr, "%*c+ _tmp_149[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "list")); + D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "list")); _res = list_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_149[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "list")); } { // tuple @@ -32507,18 +32813,18 @@ _tmp_149_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple")); + D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple")); expr_ty tuple_var; if ( (tuple_var = tuple_rule(p)) // tuple ) { - D(fprintf(stderr, "%*c+ _tmp_149[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tuple")); + D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tuple")); _res = tuple_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_149[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "tuple")); } { // genexp @@ -32526,18 +32832,18 @@ _tmp_149_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "genexp")); + D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "genexp")); expr_ty genexp_var; if ( (genexp_var = genexp_rule(p)) // genexp ) { - D(fprintf(stderr, "%*c+ _tmp_149[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "genexp")); + D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "genexp")); _res = genexp_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_149[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "genexp")); } { // 'True' @@ -32545,18 +32851,18 @@ _tmp_149_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); + D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 600)) // token='True' ) { - D(fprintf(stderr, "%*c+ _tmp_149[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); + D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_149[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'True'")); } { // 'None' @@ -32564,18 +32870,18 @@ _tmp_149_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); + D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 601)) // token='None' ) { - D(fprintf(stderr, "%*c+ _tmp_149[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); + D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_149[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'None'")); } { // 'False' @@ -32583,18 +32889,18 @@ _tmp_149_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); + D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 602)) // token='False' ) { - D(fprintf(stderr, "%*c+ _tmp_149[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); + D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_149[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'False'")); } _res = NULL; @@ -32603,9 +32909,9 @@ _tmp_149_rule(Parser *p) return _res; } -// _tmp_150: '=' | ':=' +// _tmp_151: '=' | ':=' static void * -_tmp_150_rule(Parser *p) +_tmp_151_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -32622,18 +32928,18 @@ _tmp_150_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); } { // ':=' @@ -32641,18 +32947,18 @@ _tmp_150_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); + D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 53)) // token=':=' ) { - D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='")); + D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':='")); } _res = NULL; @@ -32661,9 +32967,9 @@ _tmp_150_rule(Parser *p) return _res; } -// _loop0_151: star_named_expressions +// _loop0_152: star_named_expressions static asdl_seq * -_loop0_151_rule(Parser *p) +_loop0_152_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -32690,7 +32996,7 @@ _loop0_151_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expressions")); + D(fprintf(stderr, "%*c> _loop0_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expressions")); asdl_expr_seq* star_named_expressions_var; while ( (star_named_expressions_var = star_named_expressions_rule(p)) // star_named_expressions @@ -32712,7 +33018,7 @@ _loop0_151_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_151[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_152[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expressions")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -32725,14 +33031,14 @@ _loop0_151_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_151_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_152_type, _seq); p->level--; return _seq; } -// _loop0_152: (star_targets '=') +// _loop0_153: (star_targets '=') static asdl_seq * -_loop0_152_rule(Parser *p) +_loop0_153_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -32759,13 +33065,13 @@ _loop0_152_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_229_var; + D(fprintf(stderr, "%*c> _loop0_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); + void *_tmp_231_var; while ( - (_tmp_229_var = _tmp_229_rule(p)) // star_targets '=' + (_tmp_231_var = _tmp_231_rule(p)) // star_targets '=' ) { - _res = _tmp_229_var; + _res = _tmp_231_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -32781,7 +33087,7 @@ _loop0_152_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_152[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_153[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -32794,14 +33100,14 @@ _loop0_152_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_152_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_153_type, _seq); p->level--; return _seq; } -// _loop0_153: (star_targets '=') +// _loop0_154: (star_targets '=') static asdl_seq * -_loop0_153_rule(Parser *p) +_loop0_154_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -32828,13 +33134,13 @@ _loop0_153_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_230_var; + D(fprintf(stderr, "%*c> _loop0_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); + void *_tmp_232_var; while ( - (_tmp_230_var = _tmp_230_rule(p)) // star_targets '=' + (_tmp_232_var = _tmp_232_rule(p)) // star_targets '=' ) { - _res = _tmp_230_var; + _res = _tmp_232_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -32850,7 +33156,7 @@ _loop0_153_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_153[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_154[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -32863,14 +33169,14 @@ _loop0_153_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_153_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_154_type, _seq); p->level--; return _seq; } -// _tmp_154: yield_expr | star_expressions +// _tmp_155: yield_expr | star_expressions static void * -_tmp_154_rule(Parser *p) +_tmp_155_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -32887,18 +33193,18 @@ _tmp_154_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); expr_ty yield_expr_var; if ( (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_155[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_154[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_155[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // star_expressions @@ -32906,18 +33212,18 @@ _tmp_154_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); expr_ty star_expressions_var; if ( (star_expressions_var = star_expressions_rule(p)) // star_expressions ) { - D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c+ _tmp_155[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); _res = star_expressions_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_154[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_155[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; @@ -32926,9 +33232,9 @@ _tmp_154_rule(Parser *p) return _res; } -// _tmp_155: '[' | '(' | '{' +// _tmp_156: '[' | '(' | '{' static void * -_tmp_155_rule(Parser *p) +_tmp_156_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -32945,18 +33251,18 @@ _tmp_155_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 9)) // token='[' ) { - D(fprintf(stderr, "%*c+ _tmp_155[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_155[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); } { // '(' @@ -32964,18 +33270,18 @@ _tmp_155_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 7)) // token='(' ) { - D(fprintf(stderr, "%*c+ _tmp_155[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_155[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'('")); } { // '{' @@ -32983,18 +33289,18 @@ _tmp_155_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' ) { - D(fprintf(stderr, "%*c+ _tmp_155[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_155[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); } _res = NULL; @@ -33003,9 +33309,9 @@ _tmp_155_rule(Parser *p) return _res; } -// _tmp_156: '[' | '{' +// _tmp_157: '[' | '{' static void * -_tmp_156_rule(Parser *p) +_tmp_157_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33022,18 +33328,18 @@ _tmp_156_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 9)) // token='[' ) { - D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); } { // '{' @@ -33041,18 +33347,18 @@ _tmp_156_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' ) { - D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); } _res = NULL; @@ -33061,9 +33367,9 @@ _tmp_156_rule(Parser *p) return _res; } -// _tmp_157: '[' | '{' +// _tmp_158: '[' | '{' static void * -_tmp_157_rule(Parser *p) +_tmp_158_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33080,18 +33386,18 @@ _tmp_157_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 9)) // token='[' ) { - D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); } { // '{' @@ -33099,18 +33405,18 @@ _tmp_157_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 25)) // token='{' ) { - D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); } _res = NULL; @@ -33119,9 +33425,9 @@ _tmp_157_rule(Parser *p) return _res; } -// _loop0_158: param_no_default +// _loop0_159: param_no_default static asdl_seq * -_loop0_158_rule(Parser *p) +_loop0_159_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33148,7 +33454,7 @@ _loop0_158_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _loop0_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; while ( (param_no_default_var = param_no_default_rule(p)) // param_no_default @@ -33170,7 +33476,7 @@ _loop0_158_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_158[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_159[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -33183,14 +33489,14 @@ _loop0_158_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_158_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_159_type, _seq); p->level--; return _seq; } -// _loop0_159: param_no_default +// _loop0_160: param_no_default static asdl_seq * -_loop0_159_rule(Parser *p) +_loop0_160_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33217,7 +33523,7 @@ _loop0_159_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _loop0_160[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; while ( (param_no_default_var = param_no_default_rule(p)) // param_no_default @@ -33239,7 +33545,7 @@ _loop0_159_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_159[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_160[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -33252,14 +33558,14 @@ _loop0_159_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_159_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_160_type, _seq); p->level--; return _seq; } -// _loop1_160: param_no_default +// _loop1_161: param_no_default static asdl_seq * -_loop1_160_rule(Parser *p) +_loop1_161_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33286,7 +33592,7 @@ _loop1_160_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_160[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _loop1_161[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; while ( (param_no_default_var = param_no_default_rule(p)) // param_no_default @@ -33308,7 +33614,7 @@ _loop1_160_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_160[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_161[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } if (_n == 0 || p->error_indicator) { @@ -33326,14 +33632,14 @@ _loop1_160_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_160_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_161_type, _seq); p->level--; return _seq; } -// _tmp_161: slash_no_default | slash_with_default +// _tmp_162: slash_no_default | slash_with_default static void * -_tmp_161_rule(Parser *p) +_tmp_162_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33350,18 +33656,18 @@ _tmp_161_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_161[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + D(fprintf(stderr, "%*c> _tmp_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default")); asdl_arg_seq* slash_no_default_var; if ( (slash_no_default_var = slash_no_default_rule(p)) // slash_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_161[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + D(fprintf(stderr, "%*c+ _tmp_162[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default")); _res = slash_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_161[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_162[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_no_default")); } { // slash_with_default @@ -33369,18 +33675,18 @@ _tmp_161_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_161[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + D(fprintf(stderr, "%*c> _tmp_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); SlashWithDefault* slash_with_default_var; if ( (slash_with_default_var = slash_with_default_rule(p)) // slash_with_default ) { - D(fprintf(stderr, "%*c+ _tmp_161[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + D(fprintf(stderr, "%*c+ _tmp_162[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); _res = slash_with_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_161[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_162[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default")); } _res = NULL; @@ -33389,9 +33695,9 @@ _tmp_161_rule(Parser *p) return _res; } -// _loop0_162: param_maybe_default +// _loop0_163: param_maybe_default static asdl_seq * -_loop0_162_rule(Parser *p) +_loop0_163_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33418,7 +33724,7 @@ _loop0_162_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); NameDefaultPair* param_maybe_default_var; while ( (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default @@ -33440,7 +33746,7 @@ _loop0_162_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_162[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_163[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -33453,14 +33759,14 @@ _loop0_162_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_162_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_163_type, _seq); p->level--; return _seq; } -// _tmp_163: slash_no_default | slash_with_default +// _tmp_164: slash_no_default | slash_with_default static void * -_tmp_163_rule(Parser *p) +_tmp_164_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33477,18 +33783,18 @@ _tmp_163_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + D(fprintf(stderr, "%*c> _tmp_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default")); asdl_arg_seq* slash_no_default_var; if ( (slash_no_default_var = slash_no_default_rule(p)) // slash_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_163[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + D(fprintf(stderr, "%*c+ _tmp_164[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default")); _res = slash_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_163[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_164[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_no_default")); } { // slash_with_default @@ -33496,18 +33802,18 @@ _tmp_163_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + D(fprintf(stderr, "%*c> _tmp_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); SlashWithDefault* slash_with_default_var; if ( (slash_with_default_var = slash_with_default_rule(p)) // slash_with_default ) { - D(fprintf(stderr, "%*c+ _tmp_163[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + D(fprintf(stderr, "%*c+ _tmp_164[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); _res = slash_with_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_163[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_164[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default")); } _res = NULL; @@ -33516,9 +33822,9 @@ _tmp_163_rule(Parser *p) return _res; } -// _loop0_164: param_maybe_default +// _loop0_165: param_maybe_default static asdl_seq * -_loop0_164_rule(Parser *p) +_loop0_165_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33545,7 +33851,7 @@ _loop0_164_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); NameDefaultPair* param_maybe_default_var; while ( (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default @@ -33567,7 +33873,7 @@ _loop0_164_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_164[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_165[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -33580,14 +33886,14 @@ _loop0_164_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_164_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_165_type, _seq); p->level--; return _seq; } -// _tmp_165: ',' | param_no_default +// _tmp_166: ',' | param_no_default static void * -_tmp_165_rule(Parser *p) +_tmp_166_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33604,18 +33910,18 @@ _tmp_165_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_166[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_165[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_166[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } { // param_no_default @@ -33623,18 +33929,18 @@ _tmp_165_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _tmp_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; if ( (param_no_default_var = param_no_default_rule(p)) // param_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c+ _tmp_166[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); _res = param_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_165[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_166[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } _res = NULL; @@ -33643,9 +33949,9 @@ _tmp_165_rule(Parser *p) return _res; } -// _loop0_166: param_maybe_default +// _loop0_167: param_maybe_default static asdl_seq * -_loop0_166_rule(Parser *p) +_loop0_167_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33672,7 +33978,7 @@ _loop0_166_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); NameDefaultPair* param_maybe_default_var; while ( (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default @@ -33694,7 +34000,7 @@ _loop0_166_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_166[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_167[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -33707,14 +34013,14 @@ _loop0_166_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_166_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_167_type, _seq); p->level--; return _seq; } -// _loop1_167: param_maybe_default +// _loop1_168: param_maybe_default static asdl_seq * -_loop1_167_rule(Parser *p) +_loop1_168_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33741,7 +34047,7 @@ _loop1_167_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c> _loop1_168[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); NameDefaultPair* param_maybe_default_var; while ( (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default @@ -33763,7 +34069,7 @@ _loop1_167_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_167[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_168[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } if (_n == 0 || p->error_indicator) { @@ -33781,14 +34087,14 @@ _loop1_167_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_167_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_168_type, _seq); p->level--; return _seq; } -// _tmp_168: ')' | ',' +// _tmp_169: ')' | ',' static void * -_tmp_168_rule(Parser *p) +_tmp_169_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33805,18 +34111,18 @@ _tmp_168_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_168[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_169[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_168[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_169[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_168[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_169[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // ',' @@ -33824,18 +34130,18 @@ _tmp_168_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_168[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_169[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_168[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_169[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_168[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_169[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -33844,9 +34150,9 @@ _tmp_168_rule(Parser *p) return _res; } -// _tmp_169: ')' | ',' (')' | '**') +// _tmp_170: ')' | ',' (')' | '**') static void * -_tmp_169_rule(Parser *p) +_tmp_170_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33863,18 +34169,18 @@ _tmp_169_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_169[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_170[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_169[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_170[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_169[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_170[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // ',' (')' | '**') @@ -33882,21 +34188,21 @@ _tmp_169_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_169[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); + D(fprintf(stderr, "%*c> _tmp_170[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); Token * _literal; - void *_tmp_231_var; + void *_tmp_233_var; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_tmp_231_var = _tmp_231_rule(p)) // ')' | '**' + (_tmp_233_var = _tmp_233_rule(p)) // ')' | '**' ) { - D(fprintf(stderr, "%*c+ _tmp_169[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_231_var); + D(fprintf(stderr, "%*c+ _tmp_170[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); + _res = _PyPegen_dummy_name(p, _literal, _tmp_233_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_169[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_170[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (')' | '**')")); } _res = NULL; @@ -33905,9 +34211,9 @@ _tmp_169_rule(Parser *p) return _res; } -// _tmp_170: param_no_default | ',' +// _tmp_171: param_no_default | ',' static void * -_tmp_170_rule(Parser *p) +_tmp_171_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33924,18 +34230,18 @@ _tmp_170_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_170[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _tmp_171[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; if ( (param_no_default_var = param_no_default_rule(p)) // param_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_170[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c+ _tmp_171[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); _res = param_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_170[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_171[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } { // ',' @@ -33943,18 +34249,18 @@ _tmp_170_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_170[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_171[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_170[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_171[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_170[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_171[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -33963,9 +34269,9 @@ _tmp_170_rule(Parser *p) return _res; } -// _loop0_171: param_maybe_default +// _loop0_172: param_maybe_default static asdl_seq * -_loop0_171_rule(Parser *p) +_loop0_172_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -33992,7 +34298,7 @@ _loop0_171_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_171[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_172[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); NameDefaultPair* param_maybe_default_var; while ( (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default @@ -34014,7 +34320,7 @@ _loop0_171_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_171[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_172[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -34027,14 +34333,14 @@ _loop0_171_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_171_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_172_type, _seq); p->level--; return _seq; } -// _tmp_172: param_no_default | ',' +// _tmp_173: param_no_default | ',' static void * -_tmp_172_rule(Parser *p) +_tmp_173_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34051,18 +34357,18 @@ _tmp_172_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_172[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _tmp_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; if ( (param_no_default_var = param_no_default_rule(p)) // param_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_172[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c+ _tmp_173[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); _res = param_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_172[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_173[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } { // ',' @@ -34070,18 +34376,18 @@ _tmp_172_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_172[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_172[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_173[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_172[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_173[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -34090,9 +34396,9 @@ _tmp_172_rule(Parser *p) return _res; } -// _tmp_173: '*' | '**' | '/' +// _tmp_174: '*' | '**' | '/' static void * -_tmp_173_rule(Parser *p) +_tmp_174_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34109,18 +34415,18 @@ _tmp_173_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); + D(fprintf(stderr, "%*c> _tmp_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' ) { - D(fprintf(stderr, "%*c+ _tmp_173[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); + D(fprintf(stderr, "%*c+ _tmp_174[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_173[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_174[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*'")); } { // '**' @@ -34128,18 +34434,18 @@ _tmp_173_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_173[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_174[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_173[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_174[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } { // '/' @@ -34147,18 +34453,18 @@ _tmp_173_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); + D(fprintf(stderr, "%*c> _tmp_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 17)) // token='/' ) { - D(fprintf(stderr, "%*c+ _tmp_173[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); + D(fprintf(stderr, "%*c+ _tmp_174[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_173[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_174[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'/'")); } _res = NULL; @@ -34167,9 +34473,9 @@ _tmp_173_rule(Parser *p) return _res; } -// _loop1_174: param_with_default +// _loop1_175: param_with_default static asdl_seq * -_loop1_174_rule(Parser *p) +_loop1_175_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34196,7 +34502,7 @@ _loop1_174_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); + D(fprintf(stderr, "%*c> _loop1_175[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); NameDefaultPair* param_with_default_var; while ( (param_with_default_var = param_with_default_rule(p)) // param_with_default @@ -34218,7 +34524,7 @@ _loop1_174_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_174[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_175[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); } if (_n == 0 || p->error_indicator) { @@ -34236,14 +34542,14 @@ _loop1_174_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_174_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_175_type, _seq); p->level--; return _seq; } -// _loop0_175: lambda_param_no_default +// _loop0_176: lambda_param_no_default static asdl_seq * -_loop0_175_rule(Parser *p) +_loop0_176_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34270,7 +34576,7 @@ _loop0_175_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_175[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop0_176[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; while ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default @@ -34292,7 +34598,7 @@ _loop0_175_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_175[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_176[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -34305,14 +34611,14 @@ _loop0_175_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_175_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_176_type, _seq); p->level--; return _seq; } -// _loop0_176: lambda_param_no_default +// _loop0_177: lambda_param_no_default static asdl_seq * -_loop0_176_rule(Parser *p) +_loop0_177_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34339,7 +34645,7 @@ _loop0_176_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_176[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop0_177[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; while ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default @@ -34361,7 +34667,7 @@ _loop0_176_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_176[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_177[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -34374,14 +34680,14 @@ _loop0_176_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_176_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_177_type, _seq); p->level--; return _seq; } -// _loop0_178: ',' lambda_param +// _loop0_179: ',' lambda_param static asdl_seq * -_loop0_178_rule(Parser *p) +_loop0_179_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34408,7 +34714,7 @@ _loop0_178_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' lambda_param")); + D(fprintf(stderr, "%*c> _loop0_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' lambda_param")); Token * _literal; arg_ty elem; while ( @@ -34439,7 +34745,7 @@ _loop0_178_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_178[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_179[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' lambda_param")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -34452,14 +34758,14 @@ _loop0_178_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_178_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_179_type, _seq); p->level--; return _seq; } -// _gather_177: lambda_param _loop0_178 +// _gather_178: lambda_param _loop0_179 static asdl_seq * -_gather_177_rule(Parser *p) +_gather_178_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34471,27 +34777,27 @@ _gather_177_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // lambda_param _loop0_178 + { // lambda_param _loop0_179 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_177[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_178")); + D(fprintf(stderr, "%*c> _gather_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_179")); arg_ty elem; asdl_seq * seq; if ( (elem = lambda_param_rule(p)) // lambda_param && - (seq = _loop0_178_rule(p)) // _loop0_178 + (seq = _loop0_179_rule(p)) // _loop0_179 ) { - D(fprintf(stderr, "%*c+ _gather_177[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_178")); + D(fprintf(stderr, "%*c+ _gather_178[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_179")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_177[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param _loop0_178")); + D(fprintf(stderr, "%*c%s _gather_178[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param _loop0_179")); } _res = NULL; done: @@ -34499,9 +34805,9 @@ _gather_177_rule(Parser *p) return _res; } -// _tmp_179: lambda_slash_no_default | lambda_slash_with_default +// _tmp_180: lambda_slash_no_default | lambda_slash_with_default static void * -_tmp_179_rule(Parser *p) +_tmp_180_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34518,18 +34824,18 @@ _tmp_179_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + D(fprintf(stderr, "%*c> _tmp_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); asdl_arg_seq* lambda_slash_no_default_var; if ( (lambda_slash_no_default_var = lambda_slash_no_default_rule(p)) // lambda_slash_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_179[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + D(fprintf(stderr, "%*c+ _tmp_180[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); _res = lambda_slash_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_179[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_180[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_no_default")); } { // lambda_slash_with_default @@ -34537,18 +34843,18 @@ _tmp_179_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + D(fprintf(stderr, "%*c> _tmp_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); SlashWithDefault* lambda_slash_with_default_var; if ( (lambda_slash_with_default_var = lambda_slash_with_default_rule(p)) // lambda_slash_with_default ) { - D(fprintf(stderr, "%*c+ _tmp_179[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + D(fprintf(stderr, "%*c+ _tmp_180[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); _res = lambda_slash_with_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_179[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_180[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default")); } _res = NULL; @@ -34557,9 +34863,9 @@ _tmp_179_rule(Parser *p) return _res; } -// _loop0_180: lambda_param_maybe_default +// _loop0_181: lambda_param_maybe_default static asdl_seq * -_loop0_180_rule(Parser *p) +_loop0_181_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34586,7 +34892,7 @@ _loop0_180_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); NameDefaultPair* lambda_param_maybe_default_var; while ( (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default @@ -34608,7 +34914,7 @@ _loop0_180_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_180[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_181[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -34621,14 +34927,14 @@ _loop0_180_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_180_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_181_type, _seq); p->level--; return _seq; } -// _tmp_181: lambda_slash_no_default | lambda_slash_with_default +// _tmp_182: lambda_slash_no_default | lambda_slash_with_default static void * -_tmp_181_rule(Parser *p) +_tmp_182_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34645,18 +34951,18 @@ _tmp_181_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + D(fprintf(stderr, "%*c> _tmp_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); asdl_arg_seq* lambda_slash_no_default_var; if ( (lambda_slash_no_default_var = lambda_slash_no_default_rule(p)) // lambda_slash_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_181[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + D(fprintf(stderr, "%*c+ _tmp_182[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); _res = lambda_slash_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_181[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_182[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_no_default")); } { // lambda_slash_with_default @@ -34664,18 +34970,18 @@ _tmp_181_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + D(fprintf(stderr, "%*c> _tmp_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); SlashWithDefault* lambda_slash_with_default_var; if ( (lambda_slash_with_default_var = lambda_slash_with_default_rule(p)) // lambda_slash_with_default ) { - D(fprintf(stderr, "%*c+ _tmp_181[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + D(fprintf(stderr, "%*c+ _tmp_182[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); _res = lambda_slash_with_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_181[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_182[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default")); } _res = NULL; @@ -34684,9 +34990,9 @@ _tmp_181_rule(Parser *p) return _res; } -// _loop0_182: lambda_param_maybe_default +// _loop0_183: lambda_param_maybe_default static asdl_seq * -_loop0_182_rule(Parser *p) +_loop0_183_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34713,7 +35019,7 @@ _loop0_182_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); NameDefaultPair* lambda_param_maybe_default_var; while ( (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default @@ -34735,7 +35041,7 @@ _loop0_182_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_182[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_183[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -34748,14 +35054,14 @@ _loop0_182_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_182_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_183_type, _seq); p->level--; return _seq; } -// _tmp_183: ',' | lambda_param_no_default +// _tmp_184: ',' | lambda_param_no_default static void * -_tmp_183_rule(Parser *p) +_tmp_184_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34772,18 +35078,18 @@ _tmp_183_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_184[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_184[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_183[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_184[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } { // lambda_param_no_default @@ -34791,18 +35097,18 @@ _tmp_183_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _tmp_184[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; if ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c+ _tmp_184[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); _res = lambda_param_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_183[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_184[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } _res = NULL; @@ -34811,9 +35117,9 @@ _tmp_183_rule(Parser *p) return _res; } -// _loop0_184: lambda_param_maybe_default +// _loop0_185: lambda_param_maybe_default static asdl_seq * -_loop0_184_rule(Parser *p) +_loop0_185_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34840,7 +35146,7 @@ _loop0_184_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_184[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_185[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); NameDefaultPair* lambda_param_maybe_default_var; while ( (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default @@ -34862,7 +35168,7 @@ _loop0_184_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_184[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_185[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -34875,14 +35181,14 @@ _loop0_184_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_184_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_185_type, _seq); p->level--; return _seq; } -// _loop1_185: lambda_param_maybe_default +// _loop1_186: lambda_param_maybe_default static asdl_seq * -_loop1_185_rule(Parser *p) +_loop1_186_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34909,7 +35215,7 @@ _loop1_185_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_185[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c> _loop1_186[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); NameDefaultPair* lambda_param_maybe_default_var; while ( (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default @@ -34931,7 +35237,7 @@ _loop1_185_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_185[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_186[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } if (_n == 0 || p->error_indicator) { @@ -34949,14 +35255,14 @@ _loop1_185_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_185_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_186_type, _seq); p->level--; return _seq; } -// _loop1_186: lambda_param_with_default +// _loop1_187: lambda_param_with_default static asdl_seq * -_loop1_186_rule(Parser *p) +_loop1_187_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -34983,7 +35289,7 @@ _loop1_186_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_186[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c> _loop1_187[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); NameDefaultPair* lambda_param_with_default_var; while ( (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default @@ -35005,7 +35311,7 @@ _loop1_186_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_186[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_187[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } if (_n == 0 || p->error_indicator) { @@ -35023,14 +35329,14 @@ _loop1_186_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_186_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_187_type, _seq); p->level--; return _seq; } -// _tmp_187: ':' | ',' (':' | '**') +// _tmp_188: ':' | ',' (':' | '**') static void * -_tmp_187_rule(Parser *p) +_tmp_188_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35047,18 +35353,18 @@ _tmp_187_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_187[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_188[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_187[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_188[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_187[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_188[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // ',' (':' | '**') @@ -35066,21 +35372,21 @@ _tmp_187_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_187[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); + D(fprintf(stderr, "%*c> _tmp_188[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); Token * _literal; - void *_tmp_232_var; + void *_tmp_234_var; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_tmp_232_var = _tmp_232_rule(p)) // ':' | '**' + (_tmp_234_var = _tmp_234_rule(p)) // ':' | '**' ) { - D(fprintf(stderr, "%*c+ _tmp_187[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_232_var); + D(fprintf(stderr, "%*c+ _tmp_188[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); + _res = _PyPegen_dummy_name(p, _literal, _tmp_234_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_187[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_188[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (':' | '**')")); } _res = NULL; @@ -35089,9 +35395,9 @@ _tmp_187_rule(Parser *p) return _res; } -// _tmp_188: lambda_param_no_default | ',' +// _tmp_189: lambda_param_no_default | ',' static void * -_tmp_188_rule(Parser *p) +_tmp_189_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35108,18 +35414,18 @@ _tmp_188_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_188[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _tmp_189[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; if ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_188[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c+ _tmp_189[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); _res = lambda_param_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_188[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_189[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } { // ',' @@ -35127,18 +35433,18 @@ _tmp_188_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_188[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_189[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_188[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_189[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_188[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_189[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -35147,9 +35453,9 @@ _tmp_188_rule(Parser *p) return _res; } -// _loop0_189: lambda_param_maybe_default +// _loop0_190: lambda_param_maybe_default static asdl_seq * -_loop0_189_rule(Parser *p) +_loop0_190_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35176,7 +35482,7 @@ _loop0_189_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_189[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_190[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); NameDefaultPair* lambda_param_maybe_default_var; while ( (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default @@ -35198,7 +35504,7 @@ _loop0_189_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_189[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_190[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -35211,14 +35517,14 @@ _loop0_189_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_189_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_190_type, _seq); p->level--; return _seq; } -// _tmp_190: lambda_param_no_default | ',' +// _tmp_191: lambda_param_no_default | ',' static void * -_tmp_190_rule(Parser *p) +_tmp_191_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35235,18 +35541,18 @@ _tmp_190_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_190[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _tmp_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; if ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_190[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c+ _tmp_191[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); _res = lambda_param_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_190[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_191[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } { // ',' @@ -35254,18 +35560,18 @@ _tmp_190_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_190[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_190[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_191[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_190[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_191[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -35274,9 +35580,9 @@ _tmp_190_rule(Parser *p) return _res; } -// _tmp_191: '*' | '**' | '/' +// _tmp_192: '*' | '**' | '/' static void * -_tmp_191_rule(Parser *p) +_tmp_192_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35293,18 +35599,18 @@ _tmp_191_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); + D(fprintf(stderr, "%*c> _tmp_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' ) { - D(fprintf(stderr, "%*c+ _tmp_191[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); + D(fprintf(stderr, "%*c+ _tmp_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_191[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_192[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*'")); } { // '**' @@ -35312,18 +35618,18 @@ _tmp_191_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_191[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_191[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_192[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } { // '/' @@ -35331,18 +35637,18 @@ _tmp_191_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); + D(fprintf(stderr, "%*c> _tmp_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 17)) // token='/' ) { - D(fprintf(stderr, "%*c+ _tmp_191[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); + D(fprintf(stderr, "%*c+ _tmp_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_191[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_192[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'/'")); } _res = NULL; @@ -35351,9 +35657,9 @@ _tmp_191_rule(Parser *p) return _res; } -// _tmp_192: ',' | ')' | ':' +// _tmp_193: ',' | ')' | ':' static void * -_tmp_192_rule(Parser *p) +_tmp_193_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35370,18 +35676,18 @@ _tmp_192_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_193[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_193[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_192[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_193[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } { // ')' @@ -35389,18 +35695,18 @@ _tmp_192_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_193[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_193[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_192[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_193[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // ':' @@ -35408,18 +35714,18 @@ _tmp_192_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_193[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_193[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_192[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_193[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } _res = NULL; @@ -35428,9 +35734,9 @@ _tmp_192_rule(Parser *p) return _res; } -// _loop0_194: ',' (expression ['as' star_target]) +// _loop0_195: ',' (expression ['as' star_target]) static asdl_seq * -_loop0_194_rule(Parser *p) +_loop0_195_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35457,13 +35763,13 @@ _loop0_194_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_194[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); + D(fprintf(stderr, "%*c> _loop0_195[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); Token * _literal; void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_233_rule(p)) // expression ['as' star_target] + (elem = _tmp_235_rule(p)) // expression ['as' star_target] ) { _res = elem; @@ -35488,7 +35794,7 @@ _loop0_194_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_194[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_195[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expression ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -35501,14 +35807,14 @@ _loop0_194_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_194_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_195_type, _seq); p->level--; return _seq; } -// _gather_193: (expression ['as' star_target]) _loop0_194 +// _gather_194: (expression ['as' star_target]) _loop0_195 static asdl_seq * -_gather_193_rule(Parser *p) +_gather_194_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35520,27 +35826,27 @@ _gather_193_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // (expression ['as' star_target]) _loop0_194 + { // (expression ['as' star_target]) _loop0_195 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_193[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_194")); + D(fprintf(stderr, "%*c> _gather_194[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_195")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_233_rule(p)) // expression ['as' star_target] + (elem = _tmp_235_rule(p)) // expression ['as' star_target] && - (seq = _loop0_194_rule(p)) // _loop0_194 + (seq = _loop0_195_rule(p)) // _loop0_195 ) { - D(fprintf(stderr, "%*c+ _gather_193[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_194")); + D(fprintf(stderr, "%*c+ _gather_194[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_195")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_193[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_194")); + D(fprintf(stderr, "%*c%s _gather_194[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_195")); } _res = NULL; done: @@ -35548,9 +35854,9 @@ _gather_193_rule(Parser *p) return _res; } -// _loop0_196: ',' (expressions ['as' star_target]) +// _loop0_197: ',' (expressions ['as' star_target]) static asdl_seq * -_loop0_196_rule(Parser *p) +_loop0_197_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35577,13 +35883,13 @@ _loop0_196_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_196[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); + D(fprintf(stderr, "%*c> _loop0_197[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); Token * _literal; void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_234_rule(p)) // expressions ['as' star_target] + (elem = _tmp_236_rule(p)) // expressions ['as' star_target] ) { _res = elem; @@ -35608,7 +35914,7 @@ _loop0_196_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_196[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_197[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expressions ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -35621,14 +35927,14 @@ _loop0_196_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_196_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_197_type, _seq); p->level--; return _seq; } -// _gather_195: (expressions ['as' star_target]) _loop0_196 +// _gather_196: (expressions ['as' star_target]) _loop0_197 static asdl_seq * -_gather_195_rule(Parser *p) +_gather_196_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35640,27 +35946,27 @@ _gather_195_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // (expressions ['as' star_target]) _loop0_196 + { // (expressions ['as' star_target]) _loop0_197 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_195[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_196")); + D(fprintf(stderr, "%*c> _gather_196[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_197")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_234_rule(p)) // expressions ['as' star_target] + (elem = _tmp_236_rule(p)) // expressions ['as' star_target] && - (seq = _loop0_196_rule(p)) // _loop0_196 + (seq = _loop0_197_rule(p)) // _loop0_197 ) { - D(fprintf(stderr, "%*c+ _gather_195[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_196")); + D(fprintf(stderr, "%*c+ _gather_196[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_197")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_195[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_196")); + D(fprintf(stderr, "%*c%s _gather_196[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_197")); } _res = NULL; done: @@ -35668,9 +35974,9 @@ _gather_195_rule(Parser *p) return _res; } -// _loop0_198: ',' (expression ['as' star_target]) +// _loop0_199: ',' (expression ['as' star_target]) static asdl_seq * -_loop0_198_rule(Parser *p) +_loop0_199_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35697,13 +36003,13 @@ _loop0_198_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_198[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); + D(fprintf(stderr, "%*c> _loop0_199[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); Token * _literal; void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_235_rule(p)) // expression ['as' star_target] + (elem = _tmp_237_rule(p)) // expression ['as' star_target] ) { _res = elem; @@ -35728,7 +36034,7 @@ _loop0_198_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_198[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_199[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expression ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -35741,14 +36047,14 @@ _loop0_198_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_198_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_199_type, _seq); p->level--; return _seq; } -// _gather_197: (expression ['as' star_target]) _loop0_198 +// _gather_198: (expression ['as' star_target]) _loop0_199 static asdl_seq * -_gather_197_rule(Parser *p) +_gather_198_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35760,27 +36066,27 @@ _gather_197_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // (expression ['as' star_target]) _loop0_198 + { // (expression ['as' star_target]) _loop0_199 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_197[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_198")); + D(fprintf(stderr, "%*c> _gather_198[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_199")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_235_rule(p)) // expression ['as' star_target] + (elem = _tmp_237_rule(p)) // expression ['as' star_target] && - (seq = _loop0_198_rule(p)) // _loop0_198 + (seq = _loop0_199_rule(p)) // _loop0_199 ) { - D(fprintf(stderr, "%*c+ _gather_197[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_198")); + D(fprintf(stderr, "%*c+ _gather_198[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_199")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_197[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_198")); + D(fprintf(stderr, "%*c%s _gather_198[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_199")); } _res = NULL; done: @@ -35788,9 +36094,9 @@ _gather_197_rule(Parser *p) return _res; } -// _loop0_200: ',' (expressions ['as' star_target]) +// _loop0_201: ',' (expressions ['as' star_target]) static asdl_seq * -_loop0_200_rule(Parser *p) +_loop0_201_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35817,13 +36123,13 @@ _loop0_200_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); + D(fprintf(stderr, "%*c> _loop0_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); Token * _literal; void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_236_rule(p)) // expressions ['as' star_target] + (elem = _tmp_238_rule(p)) // expressions ['as' star_target] ) { _res = elem; @@ -35848,7 +36154,7 @@ _loop0_200_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_200[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_201[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expressions ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -35861,14 +36167,14 @@ _loop0_200_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_200_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_201_type, _seq); p->level--; return _seq; } -// _gather_199: (expressions ['as' star_target]) _loop0_200 +// _gather_200: (expressions ['as' star_target]) _loop0_201 static asdl_seq * -_gather_199_rule(Parser *p) +_gather_200_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35880,27 +36186,27 @@ _gather_199_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // (expressions ['as' star_target]) _loop0_200 + { // (expressions ['as' star_target]) _loop0_201 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_199[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_200")); + D(fprintf(stderr, "%*c> _gather_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_201")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_236_rule(p)) // expressions ['as' star_target] + (elem = _tmp_238_rule(p)) // expressions ['as' star_target] && - (seq = _loop0_200_rule(p)) // _loop0_200 + (seq = _loop0_201_rule(p)) // _loop0_201 ) { - D(fprintf(stderr, "%*c+ _gather_199[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_200")); + D(fprintf(stderr, "%*c+ _gather_200[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_201")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_199[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_200")); + D(fprintf(stderr, "%*c%s _gather_200[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_201")); } _res = NULL; done: @@ -35908,9 +36214,9 @@ _gather_199_rule(Parser *p) return _res; } -// _tmp_201: 'except' | 'finally' +// _tmp_202: 'except' | 'finally' static void * -_tmp_201_rule(Parser *p) +_tmp_202_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35927,18 +36233,18 @@ _tmp_201_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except'")); + D(fprintf(stderr, "%*c> _tmp_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 629)) // token='except' ) { - D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except'")); + D(fprintf(stderr, "%*c+ _tmp_202[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_202[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except'")); } { // 'finally' @@ -35946,18 +36252,18 @@ _tmp_201_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally'")); + D(fprintf(stderr, "%*c> _tmp_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally'")); Token * _keyword; if ( (_keyword = _PyPegen_expect_token(p, 625)) // token='finally' ) { - D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally'")); + D(fprintf(stderr, "%*c+ _tmp_202[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally'")); _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_202[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'finally'")); } _res = NULL; @@ -35966,9 +36272,9 @@ _tmp_201_rule(Parser *p) return _res; } -// _loop0_202: block +// _loop0_203: block static asdl_seq * -_loop0_202_rule(Parser *p) +_loop0_203_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -35995,7 +36301,7 @@ _loop0_202_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); + D(fprintf(stderr, "%*c> _loop0_203[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); asdl_stmt_seq* block_var; while ( (block_var = block_rule(p)) // block @@ -36017,7 +36323,7 @@ _loop0_202_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_202[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_203[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "block")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -36030,14 +36336,14 @@ _loop0_202_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_202_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_203_type, _seq); p->level--; return _seq; } -// _tmp_203: (except_block+ except_star_block) | (except_star_block+ except_block) +// _tmp_204: (except_block+ except_star_block) | (except_star_block+ except_block) static void * -_tmp_203_rule(Parser *p) +_tmp_204_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -36054,18 +36360,18 @@ _tmp_203_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_203[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(except_block+ except_star_block)")); - void *_tmp_237_var; + D(fprintf(stderr, "%*c> _tmp_204[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(except_block+ except_star_block)")); + void *_tmp_239_var; if ( - (_tmp_237_var = _tmp_237_rule(p)) // except_block+ except_star_block + (_tmp_239_var = _tmp_239_rule(p)) // except_block+ except_star_block ) { - D(fprintf(stderr, "%*c+ _tmp_203[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(except_block+ except_star_block)")); - _res = _tmp_237_var; + D(fprintf(stderr, "%*c+ _tmp_204[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(except_block+ except_star_block)")); + _res = _tmp_239_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_203[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_204[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(except_block+ except_star_block)")); } { // (except_star_block+ except_block) @@ -36073,18 +36379,18 @@ _tmp_203_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_203[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(except_star_block+ except_block)")); - void *_tmp_238_var; + D(fprintf(stderr, "%*c> _tmp_204[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(except_star_block+ except_block)")); + void *_tmp_240_var; if ( - (_tmp_238_var = _tmp_238_rule(p)) // except_star_block+ except_block + (_tmp_240_var = _tmp_240_rule(p)) // except_star_block+ except_block ) { - D(fprintf(stderr, "%*c+ _tmp_203[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(except_star_block+ except_block)")); - _res = _tmp_238_var; + D(fprintf(stderr, "%*c+ _tmp_204[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(except_star_block+ except_block)")); + _res = _tmp_240_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_203[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_204[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(except_star_block+ except_block)")); } _res = NULL; @@ -36093,9 +36399,9 @@ _tmp_203_rule(Parser *p) return _res; } -// _loop0_204: block +// _loop0_205: block static asdl_seq * -_loop0_204_rule(Parser *p) +_loop0_205_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -36122,7 +36428,7 @@ _loop0_204_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_204[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); + D(fprintf(stderr, "%*c> _loop0_205[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); asdl_stmt_seq* block_var; while ( (block_var = block_rule(p)) // block @@ -36144,7 +36450,7 @@ _loop0_204_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_204[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_205[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "block")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -36157,14 +36463,14 @@ _loop0_204_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_204_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_205_type, _seq); p->level--; return _seq; } -// _tmp_205: 'as' NAME +// _tmp_206: 'as' NAME static void * -_tmp_205_rule(Parser *p) +_tmp_206_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -36181,7 +36487,7 @@ _tmp_205_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_205[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_206[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( @@ -36190,12 +36496,12 @@ _tmp_205_rule(Parser *p) (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_205[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_206[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_205[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_206[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -36204,9 +36510,9 @@ _tmp_205_rule(Parser *p) return _res; } -// _tmp_206: 'as' NAME +// _tmp_207: 'as' NAME static void * -_tmp_206_rule(Parser *p) +_tmp_207_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -36223,7 +36529,7 @@ _tmp_206_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_206[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_207[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( @@ -36232,12 +36538,12 @@ _tmp_206_rule(Parser *p) (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_206[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_207[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_206[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_207[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -36246,9 +36552,9 @@ _tmp_206_rule(Parser *p) return _res; } -// _tmp_207: NEWLINE | ':' +// _tmp_208: NEWLINE | ':' static void * -_tmp_207_rule(Parser *p) +_tmp_208_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -36265,18 +36571,18 @@ _tmp_207_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_207[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE")); + D(fprintf(stderr, "%*c> _tmp_208[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE")); Token * newline_var; if ( (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) { - D(fprintf(stderr, "%*c+ _tmp_207[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE")); + D(fprintf(stderr, "%*c+ _tmp_208[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE")); _res = newline_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_207[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_208[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE")); } { // ':' @@ -36284,18 +36590,18 @@ _tmp_207_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_207[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_208[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_207[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_208[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_207[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_208[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } _res = NULL; @@ -36304,9 +36610,9 @@ _tmp_207_rule(Parser *p) return _res; } -// _tmp_208: 'as' NAME +// _tmp_209: 'as' NAME static void * -_tmp_208_rule(Parser *p) +_tmp_209_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -36323,7 +36629,7 @@ _tmp_208_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_208[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_209[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( @@ -36332,12 +36638,12 @@ _tmp_208_rule(Parser *p) (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_208[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_209[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_208[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_209[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -36346,9 +36652,9 @@ _tmp_208_rule(Parser *p) return _res; } -// _tmp_209: 'as' NAME +// _tmp_210: 'as' NAME static void * -_tmp_209_rule(Parser *p) +_tmp_210_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -36365,7 +36671,7 @@ _tmp_209_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_209[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_210[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( @@ -36374,12 +36680,12 @@ _tmp_209_rule(Parser *p) (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_209[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_210[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_209[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_210[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -36388,9 +36694,9 @@ _tmp_209_rule(Parser *p) return _res; } -// _tmp_210: positional_patterns ',' +// _tmp_211: positional_patterns ',' static void * -_tmp_210_rule(Parser *p) +_tmp_211_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -36407,7 +36713,7 @@ _tmp_210_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_210[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); + D(fprintf(stderr, "%*c> _tmp_211[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); Token * _literal; asdl_pattern_seq* positional_patterns_var; if ( @@ -36416,12 +36722,12 @@ _tmp_210_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_210[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); + D(fprintf(stderr, "%*c+ _tmp_211[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); _res = _PyPegen_dummy_name(p, positional_patterns_var, _literal); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_210[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_211[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "positional_patterns ','")); } _res = NULL; @@ -36430,9 +36736,9 @@ _tmp_210_rule(Parser *p) return _res; } -// _tmp_211: '->' expression +// _tmp_212: '->' expression static void * -_tmp_211_rule(Parser *p) +_tmp_212_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -36449,7 +36755,7 @@ _tmp_211_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_211[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); + D(fprintf(stderr, "%*c> _tmp_212[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); Token * _literal; expr_ty expression_var; if ( @@ -36458,12 +36764,12 @@ _tmp_211_rule(Parser *p) (expression_var = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ _tmp_211[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'->' expression")); + D(fprintf(stderr, "%*c+ _tmp_212[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'->' expression")); _res = _PyPegen_dummy_name(p, _literal, expression_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_211[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_212[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'->' expression")); } _res = NULL; @@ -36472,9 +36778,9 @@ _tmp_211_rule(Parser *p) return _res; } -// _tmp_212: '(' arguments? ')' +// _tmp_213: '(' arguments? ')' static void * -_tmp_212_rule(Parser *p) +_tmp_213_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -36491,7 +36797,7 @@ _tmp_212_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_212[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + D(fprintf(stderr, "%*c> _tmp_213[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); Token * _literal; Token * _literal_1; void *_opt_var; @@ -36504,12 +36810,12 @@ _tmp_212_rule(Parser *p) (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_212[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + D(fprintf(stderr, "%*c+ _tmp_213[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); _res = _PyPegen_dummy_name(p, _literal, _opt_var, _literal_1); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_212[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_213[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' arguments? ')'")); } _res = NULL; @@ -36518,9 +36824,9 @@ _tmp_212_rule(Parser *p) return _res; } -// _loop0_214: ',' double_starred_kvpair +// _loop0_215: ',' double_starred_kvpair static asdl_seq * -_loop0_214_rule(Parser *p) +_loop0_215_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -36547,7 +36853,7 @@ _loop0_214_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_214[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair")); + D(fprintf(stderr, "%*c> _loop0_215[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair")); Token * _literal; KeyValuePair* elem; while ( @@ -36578,7 +36884,7 @@ _loop0_214_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_214[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_215[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' double_starred_kvpair")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -36591,14 +36897,14 @@ _loop0_214_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_214_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop0_215_type, _seq); p->level--; return _seq; } -// _gather_213: double_starred_kvpair _loop0_214 +// _gather_214: double_starred_kvpair _loop0_215 static asdl_seq * -_gather_213_rule(Parser *p) +_gather_214_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -36610,27 +36916,27 @@ _gather_213_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // double_starred_kvpair _loop0_214 + { // double_starred_kvpair _loop0_215 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_213[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_214")); + D(fprintf(stderr, "%*c> _gather_214[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_215")); KeyValuePair* elem; asdl_seq * seq; if ( (elem = double_starred_kvpair_rule(p)) // double_starred_kvpair && - (seq = _loop0_214_rule(p)) // _loop0_214 + (seq = _loop0_215_rule(p)) // _loop0_215 ) { - D(fprintf(stderr, "%*c+ _gather_213[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_214")); + D(fprintf(stderr, "%*c+ _gather_214[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_215")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_213[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_214")); + D(fprintf(stderr, "%*c%s _gather_214[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_215")); } _res = NULL; done: @@ -36638,9 +36944,9 @@ _gather_213_rule(Parser *p) return _res; } -// _tmp_215: '}' | ',' +// _tmp_216: '}' | ',' static void * -_tmp_215_rule(Parser *p) +_tmp_216_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -36657,18 +36963,18 @@ _tmp_215_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_215[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c> _tmp_216[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 26)) // token='}' ) { - D(fprintf(stderr, "%*c+ _tmp_215[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c+ _tmp_216[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_215[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_216[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); } { // ',' @@ -36676,18 +36982,18 @@ _tmp_215_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_215[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_216[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_215[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_216[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_215[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_216[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -36696,9 +37002,9 @@ _tmp_215_rule(Parser *p) return _res; } -// _tmp_216: star_targets '=' +// _tmp_217: star_targets '=' static void * -_tmp_216_rule(Parser *p) +_tmp_217_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -36715,7 +37021,7 @@ _tmp_216_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_216[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_217[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty z; if ( @@ -36724,7 +37030,7 @@ _tmp_216_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_216[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_217[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -36734,7 +37040,7 @@ _tmp_216_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_216[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_217[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; @@ -36743,9 +37049,9 @@ _tmp_216_rule(Parser *p) return _res; } -// _tmp_217: '.' | '...' +// _tmp_218: '.' | '...' static void * -_tmp_217_rule(Parser *p) +_tmp_218_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -36762,18 +37068,18 @@ _tmp_217_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_217[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_218[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_217[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_218[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_217[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_218[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '...' @@ -36781,18 +37087,18 @@ _tmp_217_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_217[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c> _tmp_218[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 52)) // token='...' ) { - D(fprintf(stderr, "%*c+ _tmp_217[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c+ _tmp_218[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_217[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_218[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'")); } _res = NULL; @@ -36801,9 +37107,9 @@ _tmp_217_rule(Parser *p) return _res; } -// _tmp_218: '.' | '...' +// _tmp_219: '.' | '...' static void * -_tmp_218_rule(Parser *p) +_tmp_219_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -36820,18 +37126,18 @@ _tmp_218_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_218[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_219[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_218[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_219[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_218[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_219[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '...' @@ -36839,18 +37145,18 @@ _tmp_218_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_218[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c> _tmp_219[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 52)) // token='...' ) { - D(fprintf(stderr, "%*c+ _tmp_218[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c+ _tmp_219[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_218[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_219[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'")); } _res = NULL; @@ -36859,9 +37165,9 @@ _tmp_218_rule(Parser *p) return _res; } -// _tmp_219: '@' named_expression NEWLINE +// _tmp_220: '@' named_expression NEWLINE static void * -_tmp_219_rule(Parser *p) +_tmp_220_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -36878,7 +37184,7 @@ _tmp_219_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_219[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); + D(fprintf(stderr, "%*c> _tmp_220[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); Token * _literal; expr_ty f; Token * newline_var; @@ -36890,7 +37196,7 @@ _tmp_219_rule(Parser *p) (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) { - D(fprintf(stderr, "%*c+ _tmp_219[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); + D(fprintf(stderr, "%*c+ _tmp_220[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); _res = f; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -36900,7 +37206,7 @@ _tmp_219_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_219[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_220[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'@' named_expression NEWLINE")); } _res = NULL; @@ -36909,9 +37215,9 @@ _tmp_219_rule(Parser *p) return _res; } -// _tmp_220: ',' expression +// _tmp_221: ',' expression static void * -_tmp_220_rule(Parser *p) +_tmp_221_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -36928,7 +37234,7 @@ _tmp_220_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_220[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c> _tmp_221[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); Token * _literal; expr_ty c; if ( @@ -36937,7 +37243,7 @@ _tmp_220_rule(Parser *p) (c = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ _tmp_220[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c+ _tmp_221[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -36947,7 +37253,7 @@ _tmp_220_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_220[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_221[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } _res = NULL; @@ -36956,9 +37262,9 @@ _tmp_220_rule(Parser *p) return _res; } -// _tmp_221: ',' star_expression +// _tmp_222: ',' star_expression static void * -_tmp_221_rule(Parser *p) +_tmp_222_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -36975,7 +37281,7 @@ _tmp_221_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_221[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression")); + D(fprintf(stderr, "%*c> _tmp_222[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression")); Token * _literal; expr_ty c; if ( @@ -36984,7 +37290,7 @@ _tmp_221_rule(Parser *p) (c = star_expression_rule(p)) // star_expression ) { - D(fprintf(stderr, "%*c+ _tmp_221[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression")); + D(fprintf(stderr, "%*c+ _tmp_222[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -36994,7 +37300,7 @@ _tmp_221_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_221[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_222[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_expression")); } _res = NULL; @@ -37003,9 +37309,9 @@ _tmp_221_rule(Parser *p) return _res; } -// _tmp_222: 'or' conjunction +// _tmp_223: 'or' conjunction static void * -_tmp_222_rule(Parser *p) +_tmp_223_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -37022,7 +37328,7 @@ _tmp_222_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_222[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); + D(fprintf(stderr, "%*c> _tmp_223[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); Token * _keyword; expr_ty c; if ( @@ -37031,7 +37337,7 @@ _tmp_222_rule(Parser *p) (c = conjunction_rule(p)) // conjunction ) { - D(fprintf(stderr, "%*c+ _tmp_222[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); + D(fprintf(stderr, "%*c+ _tmp_223[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -37041,7 +37347,7 @@ _tmp_222_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_222[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_223[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'or' conjunction")); } _res = NULL; @@ -37050,9 +37356,9 @@ _tmp_222_rule(Parser *p) return _res; } -// _tmp_223: 'and' inversion +// _tmp_224: 'and' inversion static void * -_tmp_223_rule(Parser *p) +_tmp_224_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -37069,7 +37375,7 @@ _tmp_223_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_223[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion")); + D(fprintf(stderr, "%*c> _tmp_224[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion")); Token * _keyword; expr_ty c; if ( @@ -37078,7 +37384,7 @@ _tmp_223_rule(Parser *p) (c = inversion_rule(p)) // inversion ) { - D(fprintf(stderr, "%*c+ _tmp_223[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion")); + D(fprintf(stderr, "%*c+ _tmp_224[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -37088,7 +37394,7 @@ _tmp_223_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_223[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_224[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'and' inversion")); } _res = NULL; @@ -37097,9 +37403,67 @@ _tmp_223_rule(Parser *p) return _res; } -// _tmp_224: 'if' disjunction +// _tmp_225: slice | starred_expression static void * -_tmp_224_rule(Parser *p) +_tmp_225_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + p->error_indicator = 1; + PyErr_NoMemory(); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // slice + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_225[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slice")); + expr_ty slice_var; + if ( + (slice_var = slice_rule(p)) // slice + ) + { + D(fprintf(stderr, "%*c+ _tmp_225[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slice")); + _res = slice_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_225[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slice")); + } + { // starred_expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_225[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); + expr_ty starred_expression_var; + if ( + (starred_expression_var = starred_expression_rule(p)) // starred_expression + ) + { + D(fprintf(stderr, "%*c+ _tmp_225[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); + _res = starred_expression_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_225[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_226: 'if' disjunction +static void * +_tmp_226_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -37116,7 +37480,7 @@ _tmp_224_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_224[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c> _tmp_226[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); Token * _keyword; expr_ty z; if ( @@ -37125,7 +37489,7 @@ _tmp_224_rule(Parser *p) (z = disjunction_rule(p)) // disjunction ) { - D(fprintf(stderr, "%*c+ _tmp_224[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c+ _tmp_226[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -37135,7 +37499,7 @@ _tmp_224_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_224[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_226[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction")); } _res = NULL; @@ -37144,9 +37508,9 @@ _tmp_224_rule(Parser *p) return _res; } -// _tmp_225: 'if' disjunction +// _tmp_227: 'if' disjunction static void * -_tmp_225_rule(Parser *p) +_tmp_227_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -37163,7 +37527,7 @@ _tmp_225_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_225[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c> _tmp_227[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); Token * _keyword; expr_ty z; if ( @@ -37172,7 +37536,7 @@ _tmp_225_rule(Parser *p) (z = disjunction_rule(p)) // disjunction ) { - D(fprintf(stderr, "%*c+ _tmp_225[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c+ _tmp_227[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -37182,7 +37546,7 @@ _tmp_225_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_225[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_227[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction")); } _res = NULL; @@ -37191,9 +37555,9 @@ _tmp_225_rule(Parser *p) return _res; } -// _tmp_226: starred_expression | (assignment_expression | expression !':=') !'=' +// _tmp_228: starred_expression | (assignment_expression | expression !':=') !'=' static void * -_tmp_226_rule(Parser *p) +_tmp_228_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -37210,18 +37574,18 @@ _tmp_226_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_226[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); + D(fprintf(stderr, "%*c> _tmp_228[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); expr_ty starred_expression_var; if ( (starred_expression_var = starred_expression_rule(p)) // starred_expression ) { - D(fprintf(stderr, "%*c+ _tmp_226[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); + D(fprintf(stderr, "%*c+ _tmp_228[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); _res = starred_expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_226[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_228[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression")); } { // (assignment_expression | expression !':=') !'=' @@ -37229,20 +37593,20 @@ _tmp_226_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_226[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); - void *_tmp_239_var; + D(fprintf(stderr, "%*c> _tmp_228[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); + void *_tmp_241_var; if ( - (_tmp_239_var = _tmp_239_rule(p)) // assignment_expression | expression !':=' + (_tmp_241_var = _tmp_241_rule(p)) // assignment_expression | expression !':=' && _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 22) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_226[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); - _res = _tmp_239_var; + D(fprintf(stderr, "%*c+ _tmp_228[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); + _res = _tmp_241_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_226[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_228[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(assignment_expression | expression !':=') !'='")); } _res = NULL; @@ -37251,9 +37615,9 @@ _tmp_226_rule(Parser *p) return _res; } -// _tmp_227: ',' star_target +// _tmp_229: ',' star_target static void * -_tmp_227_rule(Parser *p) +_tmp_229_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -37270,7 +37634,7 @@ _tmp_227_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_227[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c> _tmp_229[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); Token * _literal; expr_ty c; if ( @@ -37279,7 +37643,7 @@ _tmp_227_rule(Parser *p) (c = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_227[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c+ _tmp_229[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -37289,7 +37653,7 @@ _tmp_227_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_227[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_229[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target")); } _res = NULL; @@ -37298,9 +37662,9 @@ _tmp_227_rule(Parser *p) return _res; } -// _tmp_228: ',' star_target +// _tmp_230: ',' star_target static void * -_tmp_228_rule(Parser *p) +_tmp_230_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -37317,7 +37681,7 @@ _tmp_228_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_228[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c> _tmp_230[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); Token * _literal; expr_ty c; if ( @@ -37326,7 +37690,7 @@ _tmp_228_rule(Parser *p) (c = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_228[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c+ _tmp_230[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -37336,7 +37700,7 @@ _tmp_228_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_228[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_230[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target")); } _res = NULL; @@ -37345,9 +37709,9 @@ _tmp_228_rule(Parser *p) return _res; } -// _tmp_229: star_targets '=' +// _tmp_231: star_targets '=' static void * -_tmp_229_rule(Parser *p) +_tmp_231_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -37364,7 +37728,7 @@ _tmp_229_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_229[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_231[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty star_targets_var; if ( @@ -37373,12 +37737,12 @@ _tmp_229_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_229[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_231[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); _res = _PyPegen_dummy_name(p, star_targets_var, _literal); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_229[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_231[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; @@ -37387,9 +37751,9 @@ _tmp_229_rule(Parser *p) return _res; } -// _tmp_230: star_targets '=' +// _tmp_232: star_targets '=' static void * -_tmp_230_rule(Parser *p) +_tmp_232_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -37406,7 +37770,7 @@ _tmp_230_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_230[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_232[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty star_targets_var; if ( @@ -37415,12 +37779,12 @@ _tmp_230_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_230[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_232[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); _res = _PyPegen_dummy_name(p, star_targets_var, _literal); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_230[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_232[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; @@ -37429,9 +37793,9 @@ _tmp_230_rule(Parser *p) return _res; } -// _tmp_231: ')' | '**' +// _tmp_233: ')' | '**' static void * -_tmp_231_rule(Parser *p) +_tmp_233_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -37448,18 +37812,18 @@ _tmp_231_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_231[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_233[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_231[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_233[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_231[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_233[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // '**' @@ -37467,18 +37831,18 @@ _tmp_231_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_231[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_233[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_231[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_233[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_231[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_233[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } _res = NULL; @@ -37487,9 +37851,9 @@ _tmp_231_rule(Parser *p) return _res; } -// _tmp_232: ':' | '**' +// _tmp_234: ':' | '**' static void * -_tmp_232_rule(Parser *p) +_tmp_234_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -37506,18 +37870,18 @@ _tmp_232_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_232[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_232[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_232[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // '**' @@ -37525,18 +37889,18 @@ _tmp_232_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_232[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_232[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_232[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } _res = NULL; @@ -37545,9 +37909,9 @@ _tmp_232_rule(Parser *p) return _res; } -// _tmp_233: expression ['as' star_target] +// _tmp_235: expression ['as' star_target] static void * -_tmp_233_rule(Parser *p) +_tmp_235_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -37564,22 +37928,22 @@ _tmp_233_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_233[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty expression_var; if ( (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_240_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_242_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_233[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); _res = _PyPegen_dummy_name(p, expression_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_233[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_235[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' star_target]")); } _res = NULL; @@ -37588,9 +37952,9 @@ _tmp_233_rule(Parser *p) return _res; } -// _tmp_234: expressions ['as' star_target] +// _tmp_236: expressions ['as' star_target] static void * -_tmp_234_rule(Parser *p) +_tmp_236_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -37607,22 +37971,22 @@ _tmp_234_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty expressions_var; if ( (expressions_var = expressions_rule(p)) // expressions && - (_opt_var = _tmp_241_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_243_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); _res = _PyPegen_dummy_name(p, expressions_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_236[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expressions ['as' star_target]")); } _res = NULL; @@ -37631,9 +37995,9 @@ _tmp_234_rule(Parser *p) return _res; } -// _tmp_235: expression ['as' star_target] +// _tmp_237: expression ['as' star_target] static void * -_tmp_235_rule(Parser *p) +_tmp_237_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -37650,22 +38014,22 @@ _tmp_235_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty expression_var; if ( (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_242_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_244_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); _res = _PyPegen_dummy_name(p, expression_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_235[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_237[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' star_target]")); } _res = NULL; @@ -37674,9 +38038,9 @@ _tmp_235_rule(Parser *p) return _res; } -// _tmp_236: expressions ['as' star_target] +// _tmp_238: expressions ['as' star_target] static void * -_tmp_236_rule(Parser *p) +_tmp_238_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -37693,22 +38057,22 @@ _tmp_236_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_238[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty expressions_var; if ( (expressions_var = expressions_rule(p)) // expressions && - (_opt_var = _tmp_243_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_245_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_238[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); _res = _PyPegen_dummy_name(p, expressions_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_236[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_238[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expressions ['as' star_target]")); } _res = NULL; @@ -37717,9 +38081,9 @@ _tmp_236_rule(Parser *p) return _res; } -// _tmp_237: except_block+ except_star_block +// _tmp_239: except_block+ except_star_block static void * -_tmp_237_rule(Parser *p) +_tmp_239_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -37736,21 +38100,21 @@ _tmp_237_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block+ except_star_block")); - asdl_seq * _loop1_244_var; + D(fprintf(stderr, "%*c> _tmp_239[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block+ except_star_block")); + asdl_seq * _loop1_246_var; excepthandler_ty except_star_block_var; if ( - (_loop1_244_var = _loop1_244_rule(p)) // except_block+ + (_loop1_246_var = _loop1_246_rule(p)) // except_block+ && (except_star_block_var = except_star_block_rule(p)) // except_star_block ) { - D(fprintf(stderr, "%*c+ _tmp_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "except_block+ except_star_block")); - _res = _PyPegen_dummy_name(p, _loop1_244_var, except_star_block_var); + D(fprintf(stderr, "%*c+ _tmp_239[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "except_block+ except_star_block")); + _res = _PyPegen_dummy_name(p, _loop1_246_var, except_star_block_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_237[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_239[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_block+ except_star_block")); } _res = NULL; @@ -37759,9 +38123,9 @@ _tmp_237_rule(Parser *p) return _res; } -// _tmp_238: except_star_block+ except_block +// _tmp_240: except_star_block+ except_block static void * -_tmp_238_rule(Parser *p) +_tmp_240_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -37778,21 +38142,21 @@ _tmp_238_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_238[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block+ except_block")); - asdl_seq * _loop1_245_var; + D(fprintf(stderr, "%*c> _tmp_240[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block+ except_block")); + asdl_seq * _loop1_247_var; excepthandler_ty except_block_var; if ( - (_loop1_245_var = _loop1_245_rule(p)) // except_star_block+ + (_loop1_247_var = _loop1_247_rule(p)) // except_star_block+ && (except_block_var = except_block_rule(p)) // except_block ) { - D(fprintf(stderr, "%*c+ _tmp_238[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "except_star_block+ except_block")); - _res = _PyPegen_dummy_name(p, _loop1_245_var, except_block_var); + D(fprintf(stderr, "%*c+ _tmp_240[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "except_star_block+ except_block")); + _res = _PyPegen_dummy_name(p, _loop1_247_var, except_block_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_238[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_240[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_star_block+ except_block")); } _res = NULL; @@ -37801,9 +38165,9 @@ _tmp_238_rule(Parser *p) return _res; } -// _tmp_239: assignment_expression | expression !':=' +// _tmp_241: assignment_expression | expression !':=' static void * -_tmp_239_rule(Parser *p) +_tmp_241_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -37820,18 +38184,18 @@ _tmp_239_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_239[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + D(fprintf(stderr, "%*c> _tmp_241[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); expr_ty assignment_expression_var; if ( (assignment_expression_var = assignment_expression_rule(p)) // assignment_expression ) { - D(fprintf(stderr, "%*c+ _tmp_239[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + D(fprintf(stderr, "%*c+ _tmp_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression")); _res = assignment_expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_239[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_241[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "assignment_expression")); } { // expression !':=' @@ -37839,7 +38203,7 @@ _tmp_239_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_239[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); + D(fprintf(stderr, "%*c> _tmp_241[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); expr_ty expression_var; if ( (expression_var = expression_rule(p)) // expression @@ -37847,12 +38211,12 @@ _tmp_239_rule(Parser *p) _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 53) // token=':=' ) { - D(fprintf(stderr, "%*c+ _tmp_239[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); + D(fprintf(stderr, "%*c+ _tmp_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); _res = expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_239[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_241[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression !':='")); } _res = NULL; @@ -37861,9 +38225,9 @@ _tmp_239_rule(Parser *p) return _res; } -// _tmp_240: 'as' star_target +// _tmp_242: 'as' star_target static void * -_tmp_240_rule(Parser *p) +_tmp_242_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -37880,7 +38244,7 @@ _tmp_240_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_240[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_242[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( @@ -37889,12 +38253,12 @@ _tmp_240_rule(Parser *p) (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_240[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_242[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); _res = _PyPegen_dummy_name(p, _keyword, star_target_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_240[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_242[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; @@ -37903,9 +38267,9 @@ _tmp_240_rule(Parser *p) return _res; } -// _tmp_241: 'as' star_target +// _tmp_243: 'as' star_target static void * -_tmp_241_rule(Parser *p) +_tmp_243_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -37922,7 +38286,7 @@ _tmp_241_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_241[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_243[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( @@ -37931,12 +38295,12 @@ _tmp_241_rule(Parser *p) (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_243[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); _res = _PyPegen_dummy_name(p, _keyword, star_target_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_241[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_243[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; @@ -37945,9 +38309,9 @@ _tmp_241_rule(Parser *p) return _res; } -// _tmp_242: 'as' star_target +// _tmp_244: 'as' star_target static void * -_tmp_242_rule(Parser *p) +_tmp_244_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -37964,7 +38328,7 @@ _tmp_242_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_242[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_244[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( @@ -37973,12 +38337,12 @@ _tmp_242_rule(Parser *p) (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_242[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_244[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); _res = _PyPegen_dummy_name(p, _keyword, star_target_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_242[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_244[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; @@ -37987,9 +38351,9 @@ _tmp_242_rule(Parser *p) return _res; } -// _tmp_243: 'as' star_target +// _tmp_245: 'as' star_target static void * -_tmp_243_rule(Parser *p) +_tmp_245_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -38006,7 +38370,7 @@ _tmp_243_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_243[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_245[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( @@ -38015,12 +38379,12 @@ _tmp_243_rule(Parser *p) (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_243[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_245[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); _res = _PyPegen_dummy_name(p, _keyword, star_target_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_243[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_245[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; @@ -38029,9 +38393,9 @@ _tmp_243_rule(Parser *p) return _res; } -// _loop1_244: except_block +// _loop1_246: except_block static asdl_seq * -_loop1_244_rule(Parser *p) +_loop1_246_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -38058,7 +38422,7 @@ _loop1_244_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_244[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block")); + D(fprintf(stderr, "%*c> _loop1_246[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block")); excepthandler_ty except_block_var; while ( (except_block_var = except_block_rule(p)) // except_block @@ -38080,7 +38444,7 @@ _loop1_244_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_244[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_246[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_block")); } if (_n == 0 || p->error_indicator) { @@ -38098,14 +38462,14 @@ _loop1_244_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_244_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_246_type, _seq); p->level--; return _seq; } -// _loop1_245: except_star_block +// _loop1_247: except_star_block static asdl_seq * -_loop1_245_rule(Parser *p) +_loop1_247_rule(Parser *p) { if (p->level++ == MAXSTACK) { p->error_indicator = 1; @@ -38132,7 +38496,7 @@ _loop1_245_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_245[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block")); + D(fprintf(stderr, "%*c> _loop1_247[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block")); excepthandler_ty except_star_block_var; while ( (except_star_block_var = except_star_block_rule(p)) // except_star_block @@ -38154,7 +38518,7 @@ _loop1_245_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_245[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_247[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_star_block")); } if (_n == 0 || p->error_indicator) { @@ -38172,7 +38536,7 @@ _loop1_245_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_245_type, _seq); + _PyPegen_insert_memo(p, _start_mark, _loop1_247_type, _seq); p->level--; return _seq; } diff --git a/Python/ast_unparse.c b/Python/ast_unparse.c index f148e99865259..6565b6b33ebd5 100644 --- a/Python/ast_unparse.c +++ b/Python/ast_unparse.c @@ -786,19 +786,8 @@ static int append_ast_subscript(_PyUnicodeWriter *writer, expr_ty e) { APPEND_EXPR(e->v.Subscript.value, PR_ATOM); - int level = PR_TUPLE; - expr_ty slice = e->v.Subscript.slice; - if (slice->kind == Tuple_kind) { - for (Py_ssize_t i = 0; i < asdl_seq_LEN(slice->v.Tuple.elts); i++) { - expr_ty element = asdl_seq_GET(slice->v.Tuple.elts, i); - if (element->kind == Starred_kind) { - ++level; - break; - } - } - } APPEND_STR("["); - APPEND_EXPR(e->v.Subscript.slice, level); + APPEND_EXPR(e->v.Subscript.slice, PR_TUPLE); APPEND_STR_FINISH("]"); } diff --git a/Python/compile.c b/Python/compile.c index e24f425229b6a..06edcf1810e64 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -2335,10 +2335,20 @@ compiler_visit_argannotation(struct compiler *c, identifier id, Py_DECREF(mangled); if (c->c_future->ff_features & CO_FUTURE_ANNOTATIONS) { - VISIT(c, annexpr, annotation) + VISIT(c, annexpr, annotation); } else { - VISIT(c, expr, annotation); + if (annotation->kind == Starred_kind) { + // *args: *Ts (where Ts is a TypeVarTuple). + // Do [annotation_value] = [*Ts]. + // (Note that in theory we could end up here even for an argument + // other than *args, but in practice the grammar doesn't allow it.) + VISIT(c, expr, annotation->v.Starred.value); + ADDOP_I(c, UNPACK_SEQUENCE, (Py_ssize_t) 1); + } + else { + VISIT(c, expr, annotation); + } } *annotations_len += 2; return 1; From webhook-mailer at python.org Sat Mar 26 14:26:13 2022 From: webhook-mailer at python.org (pablogsal) Date: Sat, 26 Mar 2022 18:26:13 -0000 Subject: [Python-checkins] [3.10] bpo-47117: Don't crash if we fail to decode characters when the tokenizer buffers are uninitialized (GH-32129) (GH-32130) Message-ID: https://github.com/python/cpython/commit/27ee43183437c473725eba00def0ea7647688926 commit: 27ee43183437c473725eba00def0ea7647688926 branch: 3.10 author: Pablo Galindo Salgado committer: pablogsal date: 2022-03-26T18:26:05Z summary: [3.10] bpo-47117: Don't crash if we fail to decode characters when the tokenizer buffers are uninitialized (GH-32129) (GH-32130) Automerge-Triggered-By: GH:pablogsal. (cherry picked from commit 26cca8067bf5306e372c0e90036d832c5021fd90) Co-authored-by: Pablo Galindo Salgado files: A Misc/NEWS.d/next/Core and Builtins/2022-03-26-15-45-57.bpo-47117.60W6GQ.rst M Parser/pegen.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-26-15-45-57.bpo-47117.60W6GQ.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-26-15-45-57.bpo-47117.60W6GQ.rst new file mode 100644 index 0000000000000..5098ed86d0793 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-26-15-45-57.bpo-47117.60W6GQ.rst @@ -0,0 +1,2 @@ +Fix a crash if we fail to decode characters in interactive mode if the +tokenizer buffers are uninitialized. Patch by Pablo Galindo. diff --git a/Parser/pegen.c b/Parser/pegen.c index df17476013447..90a6ab98cf42e 100644 --- a/Parser/pegen.c +++ b/Parser/pegen.c @@ -435,7 +435,12 @@ get_error_line(Parser *p, Py_ssize_t lineno) assert((p->tok->fp == NULL && p->tok->str != NULL) || p->tok->fp == stdin); char *cur_line = p->tok->fp_interactive ? p->tok->interactive_src_start : p->tok->str; - assert(cur_line != NULL); + if (cur_line == NULL) { + assert(p->tok->fp_interactive); + // We can reach this point if the tokenizer buffers for interactive source have not been + // initialized because we failed to decode the original source with the given locale. + return PyUnicode_FromStringAndSize("", 0); + } const char* buf_end = p->tok->fp_interactive ? p->tok->interactive_src_end : p->tok->inp; Py_ssize_t relative_lineno = p->starting_lineno ? lineno - p->starting_lineno + 1 : lineno; @@ -495,7 +500,7 @@ _PyPegen_raise_error_known_location(Parser *p, PyObject *errtype, goto error; } - if (p->tok->fp_interactive) { + if (p->tok->fp_interactive && p->tok->interactive_src_start != NULL) { error_line = get_error_line(p, lineno); } else if (p->start_rule == Py_file_input) { From webhook-mailer at python.org Sat Mar 26 15:47:47 2022 From: webhook-mailer at python.org (sweeneyde) Date: Sat, 26 Mar 2022 19:47:47 -0000 Subject: [Python-checkins] bpo-47116: use _PyLong_FromUnsignedChar instead of PyLong_FromLong (GH-32110) Message-ID: https://github.com/python/cpython/commit/c23ddf5ec229b7302437a1cf32d366df5cc5b837 commit: c23ddf5ec229b7302437a1cf32d366df5cc5b837 branch: main author: Pieter Eendebak committer: sweeneyde <36520290+sweeneyde at users.noreply.github.com> date: 2022-03-26T15:47:38-04:00 summary: bpo-47116: use _PyLong_FromUnsignedChar instead of PyLong_FromLong (GH-32110) files: M Objects/bytearrayobject.c M Objects/bytesobject.c diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index cbe673acd0a3a9..74267cffcc9a3c 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -396,7 +396,7 @@ bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i) PyErr_SetString(PyExc_IndexError, "bytearray index out of range"); return NULL; } - return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i])); + return _PyLong_FromUnsignedChar((unsigned char)(self->ob_start[i])); } static PyObject * @@ -415,7 +415,7 @@ bytearray_subscript(PyByteArrayObject *self, PyObject *index) PyErr_SetString(PyExc_IndexError, "bytearray index out of range"); return NULL; } - return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i])); + return _PyLong_FromUnsignedChar((unsigned char)(self->ob_start[i])); } else if (PySlice_Check(index)) { Py_ssize_t start, stop, step, slicelength, i; @@ -1841,7 +1841,7 @@ bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index) if (PyByteArray_Resize((PyObject *)self, n - 1) < 0) return NULL; - return PyLong_FromLong((unsigned char)value); + return _PyLong_FromUnsignedChar((unsigned char)value); } /*[clinic input] diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 003953244a885a..56c941a44bfd54 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -1487,7 +1487,7 @@ bytes_item(PyBytesObject *a, Py_ssize_t i) PyErr_SetString(PyExc_IndexError, "index out of range"); return NULL; } - return PyLong_FromLong((unsigned char)a->ob_sval[i]); + return _PyLong_FromUnsignedChar((unsigned char)a->ob_sval[i]); } static int @@ -1595,7 +1595,7 @@ bytes_subscript(PyBytesObject* self, PyObject* item) "index out of range"); return NULL; } - return PyLong_FromLong((unsigned char)self->ob_sval[i]); + return _PyLong_FromUnsignedChar((unsigned char)self->ob_sval[i]); } else if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength, i; From webhook-mailer at python.org Sat Mar 26 15:52:33 2022 From: webhook-mailer at python.org (tiran) Date: Sat, 26 Mar 2022 19:52:33 -0000 Subject: [Python-checkins] bpo-47095: Use libb2 to provide blake2 implementation (GH-32059) Message-ID: https://github.com/python/cpython/commit/b16b6bb8dacc41e9e569783890b0c88fcd3b24e8 commit: b16b6bb8dacc41e9e569783890b0c88fcd3b24e8 branch: main author: Christian Heimes committer: tiran date: 2022-03-26T20:52:24+01:00 summary: bpo-47095: Use libb2 to provide blake2 implementation (GH-32059) files: A Misc/NEWS.d/next/Library/2022-03-23-12-07-26.bpo-47095.P3YTrh.rst A Modules/_blake2/blake2module.h D Modules/_blake2/blake2ns.h D Modules/_blake2/impl/blake2-dispatch.c D Modules/_blake2/impl/blake2-kat.h D Modules/_blake2/impl/blake2b-test.c D Modules/_blake2/impl/blake2bp-test.c D Modules/_blake2/impl/blake2bp.c D Modules/_blake2/impl/blake2s-test.c D Modules/_blake2/impl/blake2sp-test.c D Modules/_blake2/impl/blake2sp.c M .github/workflows/posix-deps-apt.sh M Doc/whatsnew/3.11.rst M Makefile.pre.in M Modules/_blake2/blake2b_impl.c M Modules/_blake2/blake2module.c M Modules/_blake2/blake2s_impl.c M configure M configure.ac M pyconfig.h.in diff --git a/.github/workflows/posix-deps-apt.sh b/.github/workflows/posix-deps-apt.sh index fc4aaba552ad20..a220896f2cd7be 100755 --- a/.github/workflows/posix-deps-apt.sh +++ b/.github/workflows/posix-deps-apt.sh @@ -7,6 +7,7 @@ apt-get -yq install \ ccache \ gdb \ lcov \ + libb2-dev \ libbz2-dev \ libffi-dev \ libgdbm-dev \ diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 2c09d3583ea151..9a137f3ca99d84 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -245,6 +245,12 @@ fractions that an ``isinstance(some_fraction, typing.SupportsInt)`` check passes. (Contributed by Mark Dickinson in :issue:`44547`.) +hashlib +------- + +* :func:`hashlib.blake2b` and :func:`hashlib.blake2s` now prefer `libb2`_ + over Python's vendored copy. + (Contributed by Christian Heimes in :issue:`47095`.) IDLE and idlelib ---------------- @@ -1066,6 +1072,9 @@ Porting to Python 3.11 `__ to get these functions on old Python functions. +* Distributors are encouraged to build Python with the optimized Blake2 + library `libb2`_. + Deprecated ---------- @@ -1145,3 +1154,6 @@ Removed * Remove the ``HAVE_PY_SET_53BIT_PRECISION`` macro (moved to the internal C API). (Contributed by Victor Stinner in :issue:`45412`.) + + +.. _libb2: https://www.blake2.net/ diff --git a/Makefile.pre.in b/Makefile.pre.in index 8eab27ccf9dc37..ff7442af316e53 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -2482,7 +2482,7 @@ MODULE_CMATH_DEPS=$(srcdir)/Modules/_math.h MODULE_MATH_DEPS=$(srcdir)/Modules/_math.h MODULE_PYEXPAT_DEPS=$(LIBEXPAT_HEADERS) @LIBEXPAT_INTERNAL@ MODULE_UNICODEDATA_DEPS=$(srcdir)/Modules/unicodedata_db.h $(srcdir)/Modules/unicodename_db.h -MODULE__BLAKE2_DEPS=$(srcdir)/Modules/_blake2/impl/blake2-config.h $(srcdir)/Modules/_blake2/impl/blake2-dispatch.c $(srcdir)/Modules/_blake2/impl/blake2-impl.h $(srcdir)/Modules/_blake2/impl/blake2-kat.h $(srcdir)/Modules/_blake2/impl/blake2.h $(srcdir)/Modules/_blake2/impl/blake2b-load-sse2.h $(srcdir)/Modules/_blake2/impl/blake2b-load-sse41.h $(srcdir)/Modules/_blake2/impl/blake2b-ref.c $(srcdir)/Modules/_blake2/impl/blake2b-round.h $(srcdir)/Modules/_blake2/impl/blake2b-test.c $(srcdir)/Modules/_blake2/impl/blake2b.c $(srcdir)/Modules/_blake2/impl/blake2bp-test.c $(srcdir)/Modules/_blake2/impl/blake2bp.c $(srcdir)/Modules/_blake2/impl/blake2s-load-sse2.h $(srcdir)/Modules/_blake2/impl/blake2s-load-sse41.h $(srcdir)/Modules/_blake2/impl/blake2s-load-xop.h $(srcdir)/Modules/_blake2/impl/blake2s-ref.c $(srcdir)/Modules/_blake2/impl/blake2s-round.h $(srcdir)/Modules/_blake2/impl/blake2s-test.c $(srcdir)/Modules/_blake2/impl/blake2s.c $(srcdir)/Modules/_blake2/impl/blake2sp-test.c $(srcdir)/Modules/_blake2/impl/blake2sp.c $(srcdir)/Modules/hashlib.h +MODULE__BLAKE2_DEPS=$(srcdir)/Modules/_blake2/impl/blake2-config.h $(srcdir)/Modules/_blake2/impl/blake2-impl.h $(srcdir)/Modules/_blake2/impl/blake2.h $(srcdir)/Modules/_blake2/impl/blake2b-load-sse2.h $(srcdir)/Modules/_blake2/impl/blake2b-load-sse41.h $(srcdir)/Modules/_blake2/impl/blake2b-ref.c $(srcdir)/Modules/_blake2/impl/blake2b-round.h $(srcdir)/Modules/_blake2/impl/blake2b.c $(srcdir)/Modules/_blake2/impl/blake2s-load-sse2.h $(srcdir)/Modules/_blake2/impl/blake2s-load-sse41.h $(srcdir)/Modules/_blake2/impl/blake2s-load-xop.h $(srcdir)/Modules/_blake2/impl/blake2s-ref.c $(srcdir)/Modules/_blake2/impl/blake2s-round.h $(srcdir)/Modules/_blake2/impl/blake2s.c $(srcdir)/Modules/_blake2/blake2module.h $(srcdir)/Modules/hashlib.h MODULE__CTYPES_DEPS=$(srcdir)/Modules/_ctypes/ctypes.h MODULE__DECIMAL_DEPS=$(srcdir)/Modules/_decimal/docstrings.h $(LIBMPDEC_HEADERS) @LIBMPDEC_INTERNAL@ MODULE__ELEMENTTREE_DEPS=$(srcdir)/Modules/pyexpat.c $(LIBEXPAT_HEADERS) @LIBEXPAT_INTERNAL@ diff --git a/Misc/NEWS.d/next/Library/2022-03-23-12-07-26.bpo-47095.P3YTrh.rst b/Misc/NEWS.d/next/Library/2022-03-23-12-07-26.bpo-47095.P3YTrh.rst new file mode 100644 index 00000000000000..2df0086e0f550a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-23-12-07-26.bpo-47095.P3YTrh.rst @@ -0,0 +1,2 @@ +:mod:`hashlib`'s internal ``_blake2`` module now prefers ``libb2`` from +https://www.blake2.net/ over Python's vendored copy of blake2. diff --git a/Modules/_blake2/blake2b_impl.c b/Modules/_blake2/blake2b_impl.c index e1421dd8ff8b82..c2cac98c7529eb 100644 --- a/Modules/_blake2/blake2b_impl.c +++ b/Modules/_blake2/blake2b_impl.c @@ -21,14 +21,9 @@ #include "pycore_strhex.h" // _Py_strhex() #include "../hashlib.h" -#include "blake2ns.h" - -#define HAVE_BLAKE2B 1 -#define BLAKE2_LOCAL_INLINE(type) Py_LOCAL_INLINE(type) - -#include "impl/blake2.h" -#include "impl/blake2-impl.h" /* for secure_zero_memory() and store48() */ +#include "blake2module.h" +#ifndef HAVE_LIBB2 /* pure SSE2 implementation is very slow, so only use the more optimized SSSE3+ * https://bugs.python.org/issue31834 */ #if defined(__SSSE3__) || defined(__SSE4_1__) || defined(__AVX__) || defined(__XOP__) @@ -36,10 +31,13 @@ #else #include "impl/blake2b-ref.c" #endif +#endif // !HAVE_LIBB2 +#define HAVE_BLAKE2B 1 extern PyType_Spec blake2b_type_spec; + typedef struct { PyObject_HEAD blake2b_param param; diff --git a/Modules/_blake2/blake2module.c b/Modules/_blake2/blake2module.c index 3b6bba277a3139..44d783b40d0453 100644 --- a/Modules/_blake2/blake2module.c +++ b/Modules/_blake2/blake2module.c @@ -13,8 +13,7 @@ #endif #include "Python.h" - -#include "impl/blake2.h" +#include "blake2module.h" extern PyType_Spec blake2b_type_spec; extern PyType_Spec blake2s_type_spec; diff --git a/Modules/_blake2/blake2ns.h b/Modules/_blake2/blake2module.h similarity index 77% rename from Modules/_blake2/blake2ns.h rename to Modules/_blake2/blake2module.h index 53bce8e0fcd066..aa8f281178eadc 100644 --- a/Modules/_blake2/blake2ns.h +++ b/Modules/_blake2/blake2module.h @@ -1,9 +1,13 @@ -/* Prefix all public blake2 symbols with PyBlake2_ - */ +#ifndef Py_BLAKE2MODULE_H +#define Py_BLAKE2MODULE_H -#ifndef Py_BLAKE2_NS -#define Py_BLAKE2_NS +#ifdef HAVE_LIBB2 +#include +#else +// use vendored copy of blake2 + +// Prefix all public blake2 symbols with PyBlake2_ #define blake2b PyBlake2_blake2b #define blake2b_compress PyBlake2_blake2b_compress #define blake2b_final PyBlake2_blake2b_final @@ -29,4 +33,11 @@ #define blake2sp_init_key PyBlake2_blake2sp_init_key #define blake2sp_update PyBlake2_blake2sp_update -#endif /* Py_BLAKE2_NS */ +#include "impl/blake2.h" + +#endif // HAVE_LIBB2 + +// for secure_zero_memory(), store32(), store48(), and store64() +#include "impl/blake2-impl.h" + +#endif // Py_BLAKE2MODULE_H diff --git a/Modules/_blake2/blake2s_impl.c b/Modules/_blake2/blake2s_impl.c index 4812730bd8ef43..1c47328ece13e8 100644 --- a/Modules/_blake2/blake2s_impl.c +++ b/Modules/_blake2/blake2s_impl.c @@ -21,14 +21,9 @@ #include "pycore_strhex.h" // _Py_strhex() #include "../hashlib.h" -#include "blake2ns.h" - -#define HAVE_BLAKE2S 1 -#define BLAKE2_LOCAL_INLINE(type) Py_LOCAL_INLINE(type) - -#include "impl/blake2.h" -#include "impl/blake2-impl.h" /* for secure_zero_memory() and store48() */ +#include "blake2module.h" +#ifndef HAVE_LIBB2 /* pure SSE2 implementation is very slow, so only use the more optimized SSSE3+ * https://bugs.python.org/issue31834 */ #if defined(__SSSE3__) || defined(__SSE4_1__) || defined(__AVX__) || defined(__XOP__) @@ -36,10 +31,13 @@ #else #include "impl/blake2s-ref.c" #endif +#endif // !HAVE_LIBB2 +#define HAVE_BLAKE2S 1 extern PyType_Spec blake2s_type_spec; + typedef struct { PyObject_HEAD blake2s_param param; diff --git a/Modules/_blake2/impl/blake2-dispatch.c b/Modules/_blake2/impl/blake2-dispatch.c deleted file mode 100644 index 96bb3408bb1e20..00000000000000 --- a/Modules/_blake2/impl/blake2-dispatch.c +++ /dev/null @@ -1,577 +0,0 @@ -/* - BLAKE2 reference source code package - optimized C implementations - - Written in 2012 by Samuel Neves - - To the extent possible under law, the author(s) have dedicated all copyright - and related and neighboring rights to this software to the public domain - worldwide. This software is distributed without any warranty. - - You should have received a copy of the CC0 Public Domain Dedication along with - this software. If not, see . -*/ -#include -#if defined(WIN32) -#include -#endif -#include "blake2.h" - -#if defined(__x86_64__) || defined(__i386__) || defined(_M_IX86) || defined(_M_X64) -#define HAVE_X86 -#endif - -typedef enum -{ - NONE = 0, -#if defined(HAVE_X86) - SSE2 = 1, - SSSE3 = 2, - SSE41 = 3, - AVX = 4, - XOP = 5, - /* AVX2 = 6, */ -#endif -} cpu_feature_t; - -static const char feature_names[][8] = -{ - "none", -#if defined(HAVE_X86) - "sse2", - "ssse3", - "sse41", - "avx", - "xop", - /* "avx2" */ -#endif -}; - -#if defined(HAVE_X86) - -#if defined(__GNUC__) -static inline void cpuid( uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx ) -{ - __asm__ __volatile__( -#if defined(__i386__) /* This is needed for -fPIC to work on i386 */ - "movl %%ebx, %%esi\n\t" -#endif - "cpuid\n\t" -#if defined(__i386__) - "xchgl %%ebx, %%esi\n\t" - : "=a"( *eax ), "=S"( *ebx ), "=c"( *ecx ), "=d"( *edx ) : "a"( *eax ) ); -#else - : "=a"( *eax ), "=b"( *ebx ), "=c"( *ecx ), "=d"( *edx ) : "a"( *eax ) ); -#endif -} - -static inline uint64_t xgetbv(uint32_t xcr) -{ - uint32_t a, d; - __asm__ __volatile__( - "xgetbv" - : "=a"(a),"=d"(d) - : "c"(xcr) - ); - return ((uint64_t)d << 32) | a; -} - -#elif defined(_MSC_VER) -#include -static inline void cpuid( uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx ) -{ - int regs[4]; - __cpuid( regs, *eax ); - *eax = regs[0]; - *ebx = regs[1]; - *ecx = regs[2]; - *edx = regs[3]; -} -#else -#error "Don't know how to call cpuid on this compiler!" -#endif - -#endif /* HAVE_X86 */ - -static inline cpu_feature_t get_cpu_features( void ) -{ -#if defined(HAVE_X86) - static volatile int initialized = 0; - static cpu_feature_t feature = NONE; // Safe default - uint32_t eax, ecx, edx, ebx; - - if( initialized ) - return feature; - - eax = 1; - cpuid( &eax, &ebx, &ecx, &edx ); - - if( 1 & ( edx >> 26 ) ) - feature = SSE2; - - if( 1 & ( ecx >> 9 ) ) - feature = SSSE3; - - if( 1 & ( ecx >> 19 ) ) - feature = SSE41; - -#if defined(WIN32) /* Work around the fact that Windows <7 does NOT support AVX... */ - if( IsProcessorFeaturePresent(17) ) /* Some environments don't know about PF_XSAVE_ENABLED */ -#endif - { - /* check for AVX and OSXSAVE bits */ - if( 1 & ( ecx >> 28 ) & (ecx >> 27) ) { -#if !defined(WIN32) /* Already checked for this in WIN32 */ - if( (xgetbv(0) & 6) == 6 ) /* XCR0 */ -#endif - feature = AVX; - } - - - eax = 0x80000001; - cpuid( &eax, &ebx, &ecx, &edx ); - - if( 1 & ( ecx >> 11 ) ) - feature = XOP; - } - - /* For future architectures */ - /* - eax = 7; ecx = 0; - cpuid(&eax, &ebx, &ecx, &edx); - - if(1&(ebx >> 5)) - feature = AVX2; - */ - /* fprintf( stderr, "Using %s engine\n", feature_names[feature] ); */ - initialized = 1; - return feature; -#else - return NONE; -#endif -} - - - -#if defined(__cplusplus) -extern "C" { -#endif - int blake2b_init_ref( blake2b_state *S, size_t outlen ); - int blake2b_init_key_ref( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2b_init_param_ref( blake2b_state *S, const blake2b_param *P ); - int blake2b_update_ref( blake2b_state *S, const uint8_t *in, size_t inlen ); - int blake2b_final_ref( blake2b_state *S, uint8_t *out, size_t outlen ); - int blake2b_ref( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - -#if defined(HAVE_X86) - - int blake2b_init_sse2( blake2b_state *S, size_t outlen ); - int blake2b_init_key_sse2( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2b_init_param_sse2( blake2b_state *S, const blake2b_param *P ); - int blake2b_update_sse2( blake2b_state *S, const uint8_t *in, size_t inlen ); - int blake2b_final_sse2( blake2b_state *S, uint8_t *out, size_t outlen ); - int blake2b_sse2( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - - int blake2b_init_ssse3( blake2b_state *S, size_t outlen ); - int blake2b_init_key_ssse3( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2b_init_param_ssse3( blake2b_state *S, const blake2b_param *P ); - int blake2b_update_ssse3( blake2b_state *S, const uint8_t *in, size_t inlen ); - int blake2b_final_ssse3( blake2b_state *S, uint8_t *out, size_t outlen ); - int blake2b_ssse3( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - - int blake2b_init_sse41( blake2b_state *S, size_t outlen ); - int blake2b_init_key_sse41( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2b_init_param_sse41( blake2b_state *S, const blake2b_param *P ); - int blake2b_update_sse41( blake2b_state *S, const uint8_t *in, size_t inlen ); - int blake2b_final_sse41( blake2b_state *S, uint8_t *out, size_t outlen ); - int blake2b_sse41( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - - int blake2b_init_avx( blake2b_state *S, size_t outlen ); - int blake2b_init_key_avx( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2b_init_param_avx( blake2b_state *S, const blake2b_param *P ); - int blake2b_update_avx( blake2b_state *S, const uint8_t *in, size_t inlen ); - int blake2b_final_avx( blake2b_state *S, uint8_t *out, size_t outlen ); - int blake2b_avx( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - - int blake2b_init_xop( blake2b_state *S, size_t outlen ); - int blake2b_init_key_xop( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2b_init_param_xop( blake2b_state *S, const blake2b_param *P ); - int blake2b_update_xop( blake2b_state *S, const uint8_t *in, size_t inlen ); - int blake2b_final_xop( blake2b_state *S, uint8_t *out, size_t outlen ); - int blake2b_xop( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - -#endif /* HAVE_X86 */ - - int blake2s_init_ref( blake2s_state *S, size_t outlen ); - int blake2s_init_key_ref( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2s_init_param_ref( blake2s_state *S, const blake2s_param *P ); - int blake2s_update_ref( blake2s_state *S, const uint8_t *in, size_t inlen ); - int blake2s_final_ref( blake2s_state *S, uint8_t *out, size_t outlen ); - int blake2s_ref( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - -#if defined(HAVE_X86) - - int blake2s_init_sse2( blake2s_state *S, size_t outlen ); - int blake2s_init_key_sse2( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2s_init_param_sse2( blake2s_state *S, const blake2s_param *P ); - int blake2s_update_sse2( blake2s_state *S, const uint8_t *in, size_t inlen ); - int blake2s_final_sse2( blake2s_state *S, uint8_t *out, size_t outlen ); - int blake2s_sse2( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - - int blake2s_init_ssse3( blake2s_state *S, size_t outlen ); - int blake2s_init_key_ssse3( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2s_init_param_ssse3( blake2s_state *S, const blake2s_param *P ); - int blake2s_update_ssse3( blake2s_state *S, const uint8_t *in, size_t inlen ); - int blake2s_final_ssse3( blake2s_state *S, uint8_t *out, size_t outlen ); - int blake2s_ssse3( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - - int blake2s_init_sse41( blake2s_state *S, size_t outlen ); - int blake2s_init_key_sse41( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2s_init_param_sse41( blake2s_state *S, const blake2s_param *P ); - int blake2s_update_sse41( blake2s_state *S, const uint8_t *in, size_t inlen ); - int blake2s_final_sse41( blake2s_state *S, uint8_t *out, size_t outlen ); - int blake2s_sse41( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - - int blake2s_init_avx( blake2s_state *S, size_t outlen ); - int blake2s_init_key_avx( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2s_init_param_avx( blake2s_state *S, const blake2s_param *P ); - int blake2s_update_avx( blake2s_state *S, const uint8_t *in, size_t inlen ); - int blake2s_final_avx( blake2s_state *S, uint8_t *out, size_t outlen ); - int blake2s_avx( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - - int blake2s_init_xop( blake2s_state *S, size_t outlen ); - int blake2s_init_key_xop( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2s_init_param_xop( blake2s_state *S, const blake2s_param *P ); - int blake2s_update_xop( blake2s_state *S, const uint8_t *in, size_t inlen ); - int blake2s_final_xop( blake2s_state *S, uint8_t *out, size_t outlen ); - int blake2s_xop( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - -#endif /* HAVE_X86 */ - -#if defined(__cplusplus) -} -#endif - -typedef int ( *blake2b_init_fn )( blake2b_state *, size_t ); -typedef int ( *blake2b_init_key_fn )( blake2b_state *, size_t, const void *, size_t ); -typedef int ( *blake2b_init_param_fn )( blake2b_state *, const blake2b_param * ); -typedef int ( *blake2b_update_fn )( blake2b_state *, const uint8_t *, size_t ); -typedef int ( *blake2b_final_fn )( blake2b_state *, uint8_t *, size_t ); -typedef int ( *blake2b_fn )( uint8_t *, const void *, const void *, size_t, size_t, size_t ); - -typedef int ( *blake2s_init_fn )( blake2s_state *, size_t ); -typedef int ( *blake2s_init_key_fn )( blake2s_state *, size_t, const void *, size_t ); -typedef int ( *blake2s_init_param_fn )( blake2s_state *, const blake2s_param * ); -typedef int ( *blake2s_update_fn )( blake2s_state *, const uint8_t *, size_t ); -typedef int ( *blake2s_final_fn )( blake2s_state *, uint8_t *, size_t ); -typedef int ( *blake2s_fn )( uint8_t *, const void *, const void *, size_t, size_t, size_t ); - -static const blake2b_init_fn blake2b_init_table[] = -{ - blake2b_init_ref, -#if defined(HAVE_X86) - blake2b_init_sse2, - blake2b_init_ssse3, - blake2b_init_sse41, - blake2b_init_avx, - blake2b_init_xop -#endif -}; - -static const blake2b_init_key_fn blake2b_init_key_table[] = -{ - blake2b_init_key_ref, -#if defined(HAVE_X86) - blake2b_init_key_sse2, - blake2b_init_key_ssse3, - blake2b_init_key_sse41, - blake2b_init_key_avx, - blake2b_init_key_xop -#endif -}; - -static const blake2b_init_param_fn blake2b_init_param_table[] = -{ - blake2b_init_param_ref, -#if defined(HAVE_X86) - blake2b_init_param_sse2, - blake2b_init_param_ssse3, - blake2b_init_param_sse41, - blake2b_init_param_avx, - blake2b_init_param_xop -#endif -}; - -static const blake2b_update_fn blake2b_update_table[] = -{ - blake2b_update_ref, -#if defined(HAVE_X86) - blake2b_update_sse2, - blake2b_update_ssse3, - blake2b_update_sse41, - blake2b_update_avx, - blake2b_update_xop -#endif -}; - -static const blake2b_final_fn blake2b_final_table[] = -{ - blake2b_final_ref, -#if defined(HAVE_X86) - blake2b_final_sse2, - blake2b_final_ssse3, - blake2b_final_sse41, - blake2b_final_avx, - blake2b_final_xop -#endif -}; - -static const blake2b_fn blake2b_table[] = -{ - blake2b_ref, -#if defined(HAVE_X86) - blake2b_sse2, - blake2b_ssse3, - blake2b_sse41, - blake2b_avx, - blake2b_xop -#endif -}; - -static const blake2s_init_fn blake2s_init_table[] = -{ - blake2s_init_ref, -#if defined(HAVE_X86) - blake2s_init_sse2, - blake2s_init_ssse3, - blake2s_init_sse41, - blake2s_init_avx, - blake2s_init_xop -#endif -}; - -static const blake2s_init_key_fn blake2s_init_key_table[] = -{ - blake2s_init_key_ref, -#if defined(HAVE_X86) - blake2s_init_key_sse2, - blake2s_init_key_ssse3, - blake2s_init_key_sse41, - blake2s_init_key_avx, - blake2s_init_key_xop -#endif -}; - -static const blake2s_init_param_fn blake2s_init_param_table[] = -{ - blake2s_init_param_ref, -#if defined(HAVE_X86) - blake2s_init_param_sse2, - blake2s_init_param_ssse3, - blake2s_init_param_sse41, - blake2s_init_param_avx, - blake2s_init_param_xop -#endif -}; - -static const blake2s_update_fn blake2s_update_table[] = -{ - blake2s_update_ref, -#if defined(HAVE_X86) - blake2s_update_sse2, - blake2s_update_ssse3, - blake2s_update_sse41, - blake2s_update_avx, - blake2s_update_xop -#endif -}; - -static const blake2s_final_fn blake2s_final_table[] = -{ - blake2s_final_ref, -#if defined(HAVE_X86) - blake2s_final_sse2, - blake2s_final_ssse3, - blake2s_final_sse41, - blake2s_final_avx, - blake2s_final_xop -#endif -}; - -static const blake2s_fn blake2s_table[] = -{ - blake2s_ref, -#if defined(HAVE_X86) - blake2s_sse2, - blake2s_ssse3, - blake2s_sse41, - blake2s_avx, - blake2s_xop -#endif -}; - -#if defined(__cplusplus) -extern "C" { -#endif - int blake2b_init_dispatch( blake2b_state *S, size_t outlen ); - int blake2b_init_key_dispatch( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2b_init_param_dispatch( blake2b_state *S, const blake2b_param *P ); - int blake2b_update_dispatch( blake2b_state *S, const uint8_t *in, size_t inlen ); - int blake2b_final_dispatch( blake2b_state *S, uint8_t *out, size_t outlen ); - int blake2b_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); - - int blake2s_init_dispatch( blake2s_state *S, size_t outlen ); - int blake2s_init_key_dispatch( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2s_init_param_dispatch( blake2s_state *S, const blake2s_param *P ); - int blake2s_update_dispatch( blake2s_state *S, const uint8_t *in, size_t inlen ); - int blake2s_final_dispatch( blake2s_state *S, uint8_t *out, size_t outlen ); - int blake2s_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); -#if defined(__cplusplus) -} -#endif - -static blake2b_init_fn blake2b_init_ptr = blake2b_init_dispatch; -static blake2b_init_key_fn blake2b_init_key_ptr = blake2b_init_key_dispatch; -static blake2b_init_param_fn blake2b_init_param_ptr = blake2b_init_param_dispatch; -static blake2b_update_fn blake2b_update_ptr = blake2b_update_dispatch; -static blake2b_final_fn blake2b_final_ptr = blake2b_final_dispatch; -static blake2b_fn blake2b_ptr = blake2b_dispatch; - -static blake2s_init_fn blake2s_init_ptr = blake2s_init_dispatch; -static blake2s_init_key_fn blake2s_init_key_ptr = blake2s_init_key_dispatch; -static blake2s_init_param_fn blake2s_init_param_ptr = blake2s_init_param_dispatch; -static blake2s_update_fn blake2s_update_ptr = blake2s_update_dispatch; -static blake2s_final_fn blake2s_final_ptr = blake2s_final_dispatch; -static blake2s_fn blake2s_ptr = blake2s_dispatch; - -int blake2b_init_dispatch( blake2b_state *S, size_t outlen ) -{ - blake2b_init_ptr = blake2b_init_table[get_cpu_features()]; - return blake2b_init_ptr( S, outlen ); -} - -int blake2b_init_key_dispatch( blake2b_state *S, size_t outlen, const void *key, size_t keylen ) -{ - blake2b_init_key_ptr = blake2b_init_key_table[get_cpu_features()]; - return blake2b_init_key_ptr( S, outlen, key, keylen ); -} - -int blake2b_init_param_dispatch( blake2b_state *S, const blake2b_param *P ) -{ - blake2b_init_param_ptr = blake2b_init_param_table[get_cpu_features()]; - return blake2b_init_param_ptr( S, P ); -} - -int blake2b_update_dispatch( blake2b_state *S, const uint8_t *in, size_t inlen ) -{ - blake2b_update_ptr = blake2b_update_table[get_cpu_features()]; - return blake2b_update_ptr( S, in, inlen ); -} - -int blake2b_final_dispatch( blake2b_state *S, uint8_t *out, size_t outlen ) -{ - blake2b_final_ptr = blake2b_final_table[get_cpu_features()]; - return blake2b_final_ptr( S, out, outlen ); -} - -int blake2b_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) -{ - blake2b_ptr = blake2b_table[get_cpu_features()]; - return blake2b_ptr( out, in, key, outlen, inlen, keylen ); -} - -BLAKE2_API int blake2b_init( blake2b_state *S, size_t outlen ) -{ - return blake2b_init_ptr( S, outlen ); -} - -BLAKE2_API int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ) -{ - return blake2b_init_key_ptr( S, outlen, key, keylen ); -} - -BLAKE2_API int blake2b_init_param( blake2b_state *S, const blake2b_param *P ) -{ - return blake2b_init_param_ptr( S, P ); -} - -BLAKE2_API int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen ) -{ - return blake2b_update_ptr( S, in, inlen ); -} - -BLAKE2_API int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen ) -{ - return blake2b_final_ptr( S, out, outlen ); -} - -BLAKE2_API int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) -{ - return blake2b_ptr( out, in, key, outlen, inlen, keylen ); -} - -int blake2s_init_dispatch( blake2s_state *S, size_t outlen ) -{ - blake2s_init_ptr = blake2s_init_table[get_cpu_features()]; - return blake2s_init_ptr( S, outlen ); -} - -int blake2s_init_key_dispatch( blake2s_state *S, size_t outlen, const void *key, size_t keylen ) -{ - blake2s_init_key_ptr = blake2s_init_key_table[get_cpu_features()]; - return blake2s_init_key_ptr( S, outlen, key, keylen ); -} - -int blake2s_init_param_dispatch( blake2s_state *S, const blake2s_param *P ) -{ - blake2s_init_param_ptr = blake2s_init_param_table[get_cpu_features()]; - return blake2s_init_param_ptr( S, P ); -} - -int blake2s_update_dispatch( blake2s_state *S, const uint8_t *in, size_t inlen ) -{ - blake2s_update_ptr = blake2s_update_table[get_cpu_features()]; - return blake2s_update_ptr( S, in, inlen ); -} - -int blake2s_final_dispatch( blake2s_state *S, uint8_t *out, size_t outlen ) -{ - blake2s_final_ptr = blake2s_final_table[get_cpu_features()]; - return blake2s_final_ptr( S, out, outlen ); -} - -int blake2s_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) -{ - blake2s_ptr = blake2s_table[get_cpu_features()]; - return blake2s_ptr( out, in, key, outlen, inlen, keylen ); -} - -BLAKE2_API int blake2s_init( blake2s_state *S, size_t outlen ) -{ - return blake2s_init_ptr( S, outlen ); -} - -BLAKE2_API int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ) -{ - return blake2s_init_key_ptr( S, outlen, key, keylen ); -} - -BLAKE2_API int blake2s_init_param( blake2s_state *S, const blake2s_param *P ) -{ - return blake2s_init_param_ptr( S, P ); -} - -BLAKE2_API int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen ) -{ - return blake2s_update_ptr( S, in, inlen ); -} - -BLAKE2_API int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen ) -{ - return blake2s_final_ptr( S, out, outlen ); -} - -BLAKE2_API int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) -{ - return blake2s_ptr( out, in, key, outlen, inlen, keylen ); -} - diff --git a/Modules/_blake2/impl/blake2-kat.h b/Modules/_blake2/impl/blake2-kat.h deleted file mode 100644 index 3d2072763aa935..00000000000000 --- a/Modules/_blake2/impl/blake2-kat.h +++ /dev/null @@ -1,16467 +0,0 @@ -/* - BLAKE2 reference source code package - optimized C implementations - - Written in 2012 by Samuel Neves - - To the extent possible under law, the author(s) have dedicated all copyright - and related and neighboring rights to this software to the public domain - worldwide. This software is distributed without any warranty. - - You should have received a copy of the CC0 Public Domain Dedication along with - this software. If not, see . -*/ -#pragma once -#ifndef __BLAKE2_KAT_H__ -#define __BLAKE2_KAT_H__ - - -#include - -#define KAT_LENGTH 256 - - - -static const uint8_t blake2s_kat[KAT_LENGTH][BLAKE2S_OUTBYTES] = -{ - { - 0x69, 0x21, 0x7A, 0x30, 0x79, 0x90, 0x80, 0x94, - 0xE1, 0x11, 0x21, 0xD0, 0x42, 0x35, 0x4A, 0x7C, - 0x1F, 0x55, 0xB6, 0x48, 0x2C, 0xA1, 0xA5, 0x1E, - 0x1B, 0x25, 0x0D, 0xFD, 0x1E, 0xD0, 0xEE, 0xF9 - }, - { - 0xE3, 0x4D, 0x74, 0xDB, 0xAF, 0x4F, 0xF4, 0xC6, - 0xAB, 0xD8, 0x71, 0xCC, 0x22, 0x04, 0x51, 0xD2, - 0xEA, 0x26, 0x48, 0x84, 0x6C, 0x77, 0x57, 0xFB, - 0xAA, 0xC8, 0x2F, 0xE5, 0x1A, 0xD6, 0x4B, 0xEA - }, - { - 0xDD, 0xAD, 0x9A, 0xB1, 0x5D, 0xAC, 0x45, 0x49, - 0xBA, 0x42, 0xF4, 0x9D, 0x26, 0x24, 0x96, 0xBE, - 0xF6, 0xC0, 0xBA, 0xE1, 0xDD, 0x34, 0x2A, 0x88, - 0x08, 0xF8, 0xEA, 0x26, 0x7C, 0x6E, 0x21, 0x0C - }, - { - 0xE8, 0xF9, 0x1C, 0x6E, 0xF2, 0x32, 0xA0, 0x41, - 0x45, 0x2A, 0xB0, 0xE1, 0x49, 0x07, 0x0C, 0xDD, - 0x7D, 0xD1, 0x76, 0x9E, 0x75, 0xB3, 0xA5, 0x92, - 0x1B, 0xE3, 0x78, 0x76, 0xC4, 0x5C, 0x99, 0x00 - }, - { - 0x0C, 0xC7, 0x0E, 0x00, 0x34, 0x8B, 0x86, 0xBA, - 0x29, 0x44, 0xD0, 0xC3, 0x20, 0x38, 0xB2, 0x5C, - 0x55, 0x58, 0x4F, 0x90, 0xDF, 0x23, 0x04, 0xF5, - 0x5F, 0xA3, 0x32, 0xAF, 0x5F, 0xB0, 0x1E, 0x20 - }, - { - 0xEC, 0x19, 0x64, 0x19, 0x10, 0x87, 0xA4, 0xFE, - 0x9D, 0xF1, 0xC7, 0x95, 0x34, 0x2A, 0x02, 0xFF, - 0xC1, 0x91, 0xA5, 0xB2, 0x51, 0x76, 0x48, 0x56, - 0xAE, 0x5B, 0x8B, 0x57, 0x69, 0xF0, 0xC6, 0xCD - }, - { - 0xE1, 0xFA, 0x51, 0x61, 0x8D, 0x7D, 0xF4, 0xEB, - 0x70, 0xCF, 0x0D, 0x5A, 0x9E, 0x90, 0x6F, 0x80, - 0x6E, 0x9D, 0x19, 0xF7, 0xF4, 0xF0, 0x1E, 0x3B, - 0x62, 0x12, 0x88, 0xE4, 0x12, 0x04, 0x05, 0xD6 - }, - { - 0x59, 0x80, 0x01, 0xFA, 0xFB, 0xE8, 0xF9, 0x4E, - 0xC6, 0x6D, 0xC8, 0x27, 0xD0, 0x12, 0xCF, 0xCB, - 0xBA, 0x22, 0x28, 0x56, 0x9F, 0x44, 0x8E, 0x89, - 0xEA, 0x22, 0x08, 0xC8, 0xBF, 0x76, 0x92, 0x93 - }, - { - 0xC7, 0xE8, 0x87, 0xB5, 0x46, 0x62, 0x36, 0x35, - 0xE9, 0x3E, 0x04, 0x95, 0x59, 0x8F, 0x17, 0x26, - 0x82, 0x19, 0x96, 0xC2, 0x37, 0x77, 0x05, 0xB9, - 0x3A, 0x1F, 0x63, 0x6F, 0x87, 0x2B, 0xFA, 0x2D - }, - { - 0xC3, 0x15, 0xA4, 0x37, 0xDD, 0x28, 0x06, 0x2A, - 0x77, 0x0D, 0x48, 0x19, 0x67, 0x13, 0x6B, 0x1B, - 0x5E, 0xB8, 0x8B, 0x21, 0xEE, 0x53, 0xD0, 0x32, - 0x9C, 0x58, 0x97, 0x12, 0x6E, 0x9D, 0xB0, 0x2C - }, - { - 0xBB, 0x47, 0x3D, 0xED, 0xDC, 0x05, 0x5F, 0xEA, - 0x62, 0x28, 0xF2, 0x07, 0xDA, 0x57, 0x53, 0x47, - 0xBB, 0x00, 0x40, 0x4C, 0xD3, 0x49, 0xD3, 0x8C, - 0x18, 0x02, 0x63, 0x07, 0xA2, 0x24, 0xCB, 0xFF - }, - { - 0x68, 0x7E, 0x18, 0x73, 0xA8, 0x27, 0x75, 0x91, - 0xBB, 0x33, 0xD9, 0xAD, 0xF9, 0xA1, 0x39, 0x12, - 0xEF, 0xEF, 0xE5, 0x57, 0xCA, 0xFC, 0x39, 0xA7, - 0x95, 0x26, 0x23, 0xE4, 0x72, 0x55, 0xF1, 0x6D - }, - { - 0x1A, 0xC7, 0xBA, 0x75, 0x4D, 0x6E, 0x2F, 0x94, - 0xE0, 0xE8, 0x6C, 0x46, 0xBF, 0xB2, 0x62, 0xAB, - 0xBB, 0x74, 0xF4, 0x50, 0xEF, 0x45, 0x6D, 0x6B, - 0x4D, 0x97, 0xAA, 0x80, 0xCE, 0x6D, 0xA7, 0x67 - }, - { - 0x01, 0x2C, 0x97, 0x80, 0x96, 0x14, 0x81, 0x6B, - 0x5D, 0x94, 0x94, 0x47, 0x7D, 0x4B, 0x68, 0x7D, - 0x15, 0xB9, 0x6E, 0xB6, 0x9C, 0x0E, 0x80, 0x74, - 0xA8, 0x51, 0x6F, 0x31, 0x22, 0x4B, 0x5C, 0x98 - }, - { - 0x91, 0xFF, 0xD2, 0x6C, 0xFA, 0x4D, 0xA5, 0x13, - 0x4C, 0x7E, 0xA2, 0x62, 0xF7, 0x88, 0x9C, 0x32, - 0x9F, 0x61, 0xF6, 0xA6, 0x57, 0x22, 0x5C, 0xC2, - 0x12, 0xF4, 0x00, 0x56, 0xD9, 0x86, 0xB3, 0xF4 - }, - { - 0xD9, 0x7C, 0x82, 0x8D, 0x81, 0x82, 0xA7, 0x21, - 0x80, 0xA0, 0x6A, 0x78, 0x26, 0x83, 0x30, 0x67, - 0x3F, 0x7C, 0x4E, 0x06, 0x35, 0x94, 0x7C, 0x04, - 0xC0, 0x23, 0x23, 0xFD, 0x45, 0xC0, 0xA5, 0x2D - }, - { - 0xEF, 0xC0, 0x4C, 0xDC, 0x39, 0x1C, 0x7E, 0x91, - 0x19, 0xBD, 0x38, 0x66, 0x8A, 0x53, 0x4E, 0x65, - 0xFE, 0x31, 0x03, 0x6D, 0x6A, 0x62, 0x11, 0x2E, - 0x44, 0xEB, 0xEB, 0x11, 0xF9, 0xC5, 0x70, 0x80 - }, - { - 0x99, 0x2C, 0xF5, 0xC0, 0x53, 0x44, 0x2A, 0x5F, - 0xBC, 0x4F, 0xAF, 0x58, 0x3E, 0x04, 0xE5, 0x0B, - 0xB7, 0x0D, 0x2F, 0x39, 0xFB, 0xB6, 0xA5, 0x03, - 0xF8, 0x9E, 0x56, 0xA6, 0x3E, 0x18, 0x57, 0x8A - }, - { - 0x38, 0x64, 0x0E, 0x9F, 0x21, 0x98, 0x3E, 0x67, - 0xB5, 0x39, 0xCA, 0xCC, 0xAE, 0x5E, 0xCF, 0x61, - 0x5A, 0xE2, 0x76, 0x4F, 0x75, 0xA0, 0x9C, 0x9C, - 0x59, 0xB7, 0x64, 0x83, 0xC1, 0xFB, 0xC7, 0x35 - }, - { - 0x21, 0x3D, 0xD3, 0x4C, 0x7E, 0xFE, 0x4F, 0xB2, - 0x7A, 0x6B, 0x35, 0xF6, 0xB4, 0x00, 0x0D, 0x1F, - 0xE0, 0x32, 0x81, 0xAF, 0x3C, 0x72, 0x3E, 0x5C, - 0x9F, 0x94, 0x74, 0x7A, 0x5F, 0x31, 0xCD, 0x3B - }, - { - 0xEC, 0x24, 0x6E, 0xEE, 0xB9, 0xCE, 0xD3, 0xF7, - 0xAD, 0x33, 0xED, 0x28, 0x66, 0x0D, 0xD9, 0xBB, - 0x07, 0x32, 0x51, 0x3D, 0xB4, 0xE2, 0xFA, 0x27, - 0x8B, 0x60, 0xCD, 0xE3, 0x68, 0x2A, 0x4C, 0xCD - }, - { - 0xAC, 0x9B, 0x61, 0xD4, 0x46, 0x64, 0x8C, 0x30, - 0x05, 0xD7, 0x89, 0x2B, 0xF3, 0xA8, 0x71, 0x9F, - 0x4C, 0x81, 0x81, 0xCF, 0xDC, 0xBC, 0x2B, 0x79, - 0xFE, 0xF1, 0x0A, 0x27, 0x9B, 0x91, 0x10, 0x95 - }, - { - 0x7B, 0xF8, 0xB2, 0x29, 0x59, 0xE3, 0x4E, 0x3A, - 0x43, 0xF7, 0x07, 0x92, 0x23, 0xE8, 0x3A, 0x97, - 0x54, 0x61, 0x7D, 0x39, 0x1E, 0x21, 0x3D, 0xFD, - 0x80, 0x8E, 0x41, 0xB9, 0xBE, 0xAD, 0x4C, 0xE7 - }, - { - 0x68, 0xD4, 0xB5, 0xD4, 0xFA, 0x0E, 0x30, 0x2B, - 0x64, 0xCC, 0xC5, 0xAF, 0x79, 0x29, 0x13, 0xAC, - 0x4C, 0x88, 0xEC, 0x95, 0xC0, 0x7D, 0xDF, 0x40, - 0x69, 0x42, 0x56, 0xEB, 0x88, 0xCE, 0x9F, 0x3D - }, - { - 0xB2, 0xC2, 0x42, 0x0F, 0x05, 0xF9, 0xAB, 0xE3, - 0x63, 0x15, 0x91, 0x93, 0x36, 0xB3, 0x7E, 0x4E, - 0x0F, 0xA3, 0x3F, 0xF7, 0xE7, 0x6A, 0x49, 0x27, - 0x67, 0x00, 0x6F, 0xDB, 0x5D, 0x93, 0x54, 0x62 - }, - { - 0x13, 0x4F, 0x61, 0xBB, 0xD0, 0xBB, 0xB6, 0x9A, - 0xED, 0x53, 0x43, 0x90, 0x45, 0x51, 0xA3, 0xE6, - 0xC1, 0xAA, 0x7D, 0xCD, 0xD7, 0x7E, 0x90, 0x3E, - 0x70, 0x23, 0xEB, 0x7C, 0x60, 0x32, 0x0A, 0xA7 - }, - { - 0x46, 0x93, 0xF9, 0xBF, 0xF7, 0xD4, 0xF3, 0x98, - 0x6A, 0x7D, 0x17, 0x6E, 0x6E, 0x06, 0xF7, 0x2A, - 0xD1, 0x49, 0x0D, 0x80, 0x5C, 0x99, 0xE2, 0x53, - 0x47, 0xB8, 0xDE, 0x77, 0xB4, 0xDB, 0x6D, 0x9B - }, - { - 0x85, 0x3E, 0x26, 0xF7, 0x41, 0x95, 0x3B, 0x0F, - 0xD5, 0xBD, 0xB4, 0x24, 0xE8, 0xAB, 0x9E, 0x8B, - 0x37, 0x50, 0xEA, 0xA8, 0xEF, 0x61, 0xE4, 0x79, - 0x02, 0xC9, 0x1E, 0x55, 0x4E, 0x9C, 0x73, 0xB9 - }, - { - 0xF7, 0xDE, 0x53, 0x63, 0x61, 0xAB, 0xAA, 0x0E, - 0x15, 0x81, 0x56, 0xCF, 0x0E, 0xA4, 0xF6, 0x3A, - 0x99, 0xB5, 0xE4, 0x05, 0x4F, 0x8F, 0xA4, 0xC9, - 0xD4, 0x5F, 0x62, 0x85, 0xCA, 0xD5, 0x56, 0x94 - }, - { - 0x4C, 0x23, 0x06, 0x08, 0x86, 0x0A, 0x99, 0xAE, - 0x8D, 0x7B, 0xD5, 0xC2, 0xCC, 0x17, 0xFA, 0x52, - 0x09, 0x6B, 0x9A, 0x61, 0xBE, 0xDB, 0x17, 0xCB, - 0x76, 0x17, 0x86, 0x4A, 0xD2, 0x9C, 0xA7, 0xA6 - }, - { - 0xAE, 0xB9, 0x20, 0xEA, 0x87, 0x95, 0x2D, 0xAD, - 0xB1, 0xFB, 0x75, 0x92, 0x91, 0xE3, 0x38, 0x81, - 0x39, 0xA8, 0x72, 0x86, 0x50, 0x01, 0x88, 0x6E, - 0xD8, 0x47, 0x52, 0xE9, 0x3C, 0x25, 0x0C, 0x2A - }, - { - 0xAB, 0xA4, 0xAD, 0x9B, 0x48, 0x0B, 0x9D, 0xF3, - 0xD0, 0x8C, 0xA5, 0xE8, 0x7B, 0x0C, 0x24, 0x40, - 0xD4, 0xE4, 0xEA, 0x21, 0x22, 0x4C, 0x2E, 0xB4, - 0x2C, 0xBA, 0xE4, 0x69, 0xD0, 0x89, 0xB9, 0x31 - }, - { - 0x05, 0x82, 0x56, 0x07, 0xD7, 0xFD, 0xF2, 0xD8, - 0x2E, 0xF4, 0xC3, 0xC8, 0xC2, 0xAE, 0xA9, 0x61, - 0xAD, 0x98, 0xD6, 0x0E, 0xDF, 0xF7, 0xD0, 0x18, - 0x98, 0x3E, 0x21, 0x20, 0x4C, 0x0D, 0x93, 0xD1 - }, - { - 0xA7, 0x42, 0xF8, 0xB6, 0xAF, 0x82, 0xD8, 0xA6, - 0xCA, 0x23, 0x57, 0xC5, 0xF1, 0xCF, 0x91, 0xDE, - 0xFB, 0xD0, 0x66, 0x26, 0x7D, 0x75, 0xC0, 0x48, - 0xB3, 0x52, 0x36, 0x65, 0x85, 0x02, 0x59, 0x62 - }, - { - 0x2B, 0xCA, 0xC8, 0x95, 0x99, 0x00, 0x0B, 0x42, - 0xC9, 0x5A, 0xE2, 0x38, 0x35, 0xA7, 0x13, 0x70, - 0x4E, 0xD7, 0x97, 0x89, 0xC8, 0x4F, 0xEF, 0x14, - 0x9A, 0x87, 0x4F, 0xF7, 0x33, 0xF0, 0x17, 0xA2 - }, - { - 0xAC, 0x1E, 0xD0, 0x7D, 0x04, 0x8F, 0x10, 0x5A, - 0x9E, 0x5B, 0x7A, 0xB8, 0x5B, 0x09, 0xA4, 0x92, - 0xD5, 0xBA, 0xFF, 0x14, 0xB8, 0xBF, 0xB0, 0xE9, - 0xFD, 0x78, 0x94, 0x86, 0xEE, 0xA2, 0xB9, 0x74 - }, - { - 0xE4, 0x8D, 0x0E, 0xCF, 0xAF, 0x49, 0x7D, 0x5B, - 0x27, 0xC2, 0x5D, 0x99, 0xE1, 0x56, 0xCB, 0x05, - 0x79, 0xD4, 0x40, 0xD6, 0xE3, 0x1F, 0xB6, 0x24, - 0x73, 0x69, 0x6D, 0xBF, 0x95, 0xE0, 0x10, 0xE4 - }, - { - 0x12, 0xA9, 0x1F, 0xAD, 0xF8, 0xB2, 0x16, 0x44, - 0xFD, 0x0F, 0x93, 0x4F, 0x3C, 0x4A, 0x8F, 0x62, - 0xBA, 0x86, 0x2F, 0xFD, 0x20, 0xE8, 0xE9, 0x61, - 0x15, 0x4C, 0x15, 0xC1, 0x38, 0x84, 0xED, 0x3D - }, - { - 0x7C, 0xBE, 0xE9, 0x6E, 0x13, 0x98, 0x97, 0xDC, - 0x98, 0xFB, 0xEF, 0x3B, 0xE8, 0x1A, 0xD4, 0xD9, - 0x64, 0xD2, 0x35, 0xCB, 0x12, 0x14, 0x1F, 0xB6, - 0x67, 0x27, 0xE6, 0xE5, 0xDF, 0x73, 0xA8, 0x78 - }, - { - 0xEB, 0xF6, 0x6A, 0xBB, 0x59, 0x7A, 0xE5, 0x72, - 0xA7, 0x29, 0x7C, 0xB0, 0x87, 0x1E, 0x35, 0x5A, - 0xCC, 0xAF, 0xAD, 0x83, 0x77, 0xB8, 0xE7, 0x8B, - 0xF1, 0x64, 0xCE, 0x2A, 0x18, 0xDE, 0x4B, 0xAF - }, - { - 0x71, 0xB9, 0x33, 0xB0, 0x7E, 0x4F, 0xF7, 0x81, - 0x8C, 0xE0, 0x59, 0xD0, 0x08, 0x82, 0x9E, 0x45, - 0x3C, 0x6F, 0xF0, 0x2E, 0xC0, 0xA7, 0xDB, 0x39, - 0x3F, 0xC2, 0xD8, 0x70, 0xF3, 0x7A, 0x72, 0x86 - }, - { - 0x7C, 0xF7, 0xC5, 0x13, 0x31, 0x22, 0x0B, 0x8D, - 0x3E, 0xBA, 0xED, 0x9C, 0x29, 0x39, 0x8A, 0x16, - 0xD9, 0x81, 0x56, 0xE2, 0x61, 0x3C, 0xB0, 0x88, - 0xF2, 0xB0, 0xE0, 0x8A, 0x1B, 0xE4, 0xCF, 0x4F - }, - { - 0x3E, 0x41, 0xA1, 0x08, 0xE0, 0xF6, 0x4A, 0xD2, - 0x76, 0xB9, 0x79, 0xE1, 0xCE, 0x06, 0x82, 0x79, - 0xE1, 0x6F, 0x7B, 0xC7, 0xE4, 0xAA, 0x1D, 0x21, - 0x1E, 0x17, 0xB8, 0x11, 0x61, 0xDF, 0x16, 0x02 - }, - { - 0x88, 0x65, 0x02, 0xA8, 0x2A, 0xB4, 0x7B, 0xA8, - 0xD8, 0x67, 0x10, 0xAA, 0x9D, 0xE3, 0xD4, 0x6E, - 0xA6, 0x5C, 0x47, 0xAF, 0x6E, 0xE8, 0xDE, 0x45, - 0x0C, 0xCE, 0xB8, 0xB1, 0x1B, 0x04, 0x5F, 0x50 - }, - { - 0xC0, 0x21, 0xBC, 0x5F, 0x09, 0x54, 0xFE, 0xE9, - 0x4F, 0x46, 0xEA, 0x09, 0x48, 0x7E, 0x10, 0xA8, - 0x48, 0x40, 0xD0, 0x2F, 0x64, 0x81, 0x0B, 0xC0, - 0x8D, 0x9E, 0x55, 0x1F, 0x7D, 0x41, 0x68, 0x14 - }, - { - 0x20, 0x30, 0x51, 0x6E, 0x8A, 0x5F, 0xE1, 0x9A, - 0xE7, 0x9C, 0x33, 0x6F, 0xCE, 0x26, 0x38, 0x2A, - 0x74, 0x9D, 0x3F, 0xD0, 0xEC, 0x91, 0xE5, 0x37, - 0xD4, 0xBD, 0x23, 0x58, 0xC1, 0x2D, 0xFB, 0x22 - }, - { - 0x55, 0x66, 0x98, 0xDA, 0xC8, 0x31, 0x7F, 0xD3, - 0x6D, 0xFB, 0xDF, 0x25, 0xA7, 0x9C, 0xB1, 0x12, - 0xD5, 0x42, 0x58, 0x60, 0x60, 0x5C, 0xBA, 0xF5, - 0x07, 0xF2, 0x3B, 0xF7, 0xE9, 0xF4, 0x2A, 0xFE - }, - { - 0x2F, 0x86, 0x7B, 0xA6, 0x77, 0x73, 0xFD, 0xC3, - 0xE9, 0x2F, 0xCE, 0xD9, 0x9A, 0x64, 0x09, 0xAD, - 0x39, 0xD0, 0xB8, 0x80, 0xFD, 0xE8, 0xF1, 0x09, - 0xA8, 0x17, 0x30, 0xC4, 0x45, 0x1D, 0x01, 0x78 - }, - { - 0x17, 0x2E, 0xC2, 0x18, 0xF1, 0x19, 0xDF, 0xAE, - 0x98, 0x89, 0x6D, 0xFF, 0x29, 0xDD, 0x98, 0x76, - 0xC9, 0x4A, 0xF8, 0x74, 0x17, 0xF9, 0xAE, 0x4C, - 0x70, 0x14, 0xBB, 0x4E, 0x4B, 0x96, 0xAF, 0xC7 - }, - { - 0x3F, 0x85, 0x81, 0x4A, 0x18, 0x19, 0x5F, 0x87, - 0x9A, 0xA9, 0x62, 0xF9, 0x5D, 0x26, 0xBD, 0x82, - 0xA2, 0x78, 0xF2, 0xB8, 0x23, 0x20, 0x21, 0x8F, - 0x6B, 0x3B, 0xD6, 0xF7, 0xF6, 0x67, 0xA6, 0xD9 - }, - { - 0x1B, 0x61, 0x8F, 0xBA, 0xA5, 0x66, 0xB3, 0xD4, - 0x98, 0xC1, 0x2E, 0x98, 0x2C, 0x9E, 0xC5, 0x2E, - 0x4D, 0xA8, 0x5A, 0x8C, 0x54, 0xF3, 0x8F, 0x34, - 0xC0, 0x90, 0x39, 0x4F, 0x23, 0xC1, 0x84, 0xC1 - }, - { - 0x0C, 0x75, 0x8F, 0xB5, 0x69, 0x2F, 0xFD, 0x41, - 0xA3, 0x57, 0x5D, 0x0A, 0xF0, 0x0C, 0xC7, 0xFB, - 0xF2, 0xCB, 0xE5, 0x90, 0x5A, 0x58, 0x32, 0x3A, - 0x88, 0xAE, 0x42, 0x44, 0xF6, 0xE4, 0xC9, 0x93 - }, - { - 0xA9, 0x31, 0x36, 0x0C, 0xAD, 0x62, 0x8C, 0x7F, - 0x12, 0xA6, 0xC1, 0xC4, 0xB7, 0x53, 0xB0, 0xF4, - 0x06, 0x2A, 0xEF, 0x3C, 0xE6, 0x5A, 0x1A, 0xE3, - 0xF1, 0x93, 0x69, 0xDA, 0xDF, 0x3A, 0xE2, 0x3D - }, - { - 0xCB, 0xAC, 0x7D, 0x77, 0x3B, 0x1E, 0x3B, 0x3C, - 0x66, 0x91, 0xD7, 0xAB, 0xB7, 0xE9, 0xDF, 0x04, - 0x5C, 0x8B, 0xA1, 0x92, 0x68, 0xDE, 0xD1, 0x53, - 0x20, 0x7F, 0x5E, 0x80, 0x43, 0x52, 0xEC, 0x5D - }, - { - 0x23, 0xA1, 0x96, 0xD3, 0x80, 0x2E, 0xD3, 0xC1, - 0xB3, 0x84, 0x01, 0x9A, 0x82, 0x32, 0x58, 0x40, - 0xD3, 0x2F, 0x71, 0x95, 0x0C, 0x45, 0x80, 0xB0, - 0x34, 0x45, 0xE0, 0x89, 0x8E, 0x14, 0x05, 0x3C - }, - { - 0xF4, 0x49, 0x54, 0x70, 0xF2, 0x26, 0xC8, 0xC2, - 0x14, 0xBE, 0x08, 0xFD, 0xFA, 0xD4, 0xBC, 0x4A, - 0x2A, 0x9D, 0xBE, 0xA9, 0x13, 0x6A, 0x21, 0x0D, - 0xF0, 0xD4, 0xB6, 0x49, 0x29, 0xE6, 0xFC, 0x14 - }, - { - 0xE2, 0x90, 0xDD, 0x27, 0x0B, 0x46, 0x7F, 0x34, - 0xAB, 0x1C, 0x00, 0x2D, 0x34, 0x0F, 0xA0, 0x16, - 0x25, 0x7F, 0xF1, 0x9E, 0x58, 0x33, 0xFD, 0xBB, - 0xF2, 0xCB, 0x40, 0x1C, 0x3B, 0x28, 0x17, 0xDE - }, - { - 0x9F, 0xC7, 0xB5, 0xDE, 0xD3, 0xC1, 0x50, 0x42, - 0xB2, 0xA6, 0x58, 0x2D, 0xC3, 0x9B, 0xE0, 0x16, - 0xD2, 0x4A, 0x68, 0x2D, 0x5E, 0x61, 0xAD, 0x1E, - 0xFF, 0x9C, 0x63, 0x30, 0x98, 0x48, 0xF7, 0x06 - }, - { - 0x8C, 0xCA, 0x67, 0xA3, 0x6D, 0x17, 0xD5, 0xE6, - 0x34, 0x1C, 0xB5, 0x92, 0xFD, 0x7B, 0xEF, 0x99, - 0x26, 0xC9, 0xE3, 0xAA, 0x10, 0x27, 0xEA, 0x11, - 0xA7, 0xD8, 0xBD, 0x26, 0x0B, 0x57, 0x6E, 0x04 - }, - { - 0x40, 0x93, 0x92, 0xF5, 0x60, 0xF8, 0x68, 0x31, - 0xDA, 0x43, 0x73, 0xEE, 0x5E, 0x00, 0x74, 0x26, - 0x05, 0x95, 0xD7, 0xBC, 0x24, 0x18, 0x3B, 0x60, - 0xED, 0x70, 0x0D, 0x45, 0x83, 0xD3, 0xF6, 0xF0 - }, - { - 0x28, 0x02, 0x16, 0x5D, 0xE0, 0x90, 0x91, 0x55, - 0x46, 0xF3, 0x39, 0x8C, 0xD8, 0x49, 0x16, 0x4A, - 0x19, 0xF9, 0x2A, 0xDB, 0xC3, 0x61, 0xAD, 0xC9, - 0x9B, 0x0F, 0x20, 0xC8, 0xEA, 0x07, 0x10, 0x54 - }, - { - 0xAD, 0x83, 0x91, 0x68, 0xD9, 0xF8, 0xA4, 0xBE, - 0x95, 0xBA, 0x9E, 0xF9, 0xA6, 0x92, 0xF0, 0x72, - 0x56, 0xAE, 0x43, 0xFE, 0x6F, 0x98, 0x64, 0xE2, - 0x90, 0x69, 0x1B, 0x02, 0x56, 0xCE, 0x50, 0xA9 - }, - { - 0x75, 0xFD, 0xAA, 0x50, 0x38, 0xC2, 0x84, 0xB8, - 0x6D, 0x6E, 0x8A, 0xFF, 0xE8, 0xB2, 0x80, 0x7E, - 0x46, 0x7B, 0x86, 0x60, 0x0E, 0x79, 0xAF, 0x36, - 0x89, 0xFB, 0xC0, 0x63, 0x28, 0xCB, 0xF8, 0x94 - }, - { - 0xE5, 0x7C, 0xB7, 0x94, 0x87, 0xDD, 0x57, 0x90, - 0x24, 0x32, 0xB2, 0x50, 0x73, 0x38, 0x13, 0xBD, - 0x96, 0xA8, 0x4E, 0xFC, 0xE5, 0x9F, 0x65, 0x0F, - 0xAC, 0x26, 0xE6, 0x69, 0x6A, 0xEF, 0xAF, 0xC3 - }, - { - 0x56, 0xF3, 0x4E, 0x8B, 0x96, 0x55, 0x7E, 0x90, - 0xC1, 0xF2, 0x4B, 0x52, 0xD0, 0xC8, 0x9D, 0x51, - 0x08, 0x6A, 0xCF, 0x1B, 0x00, 0xF6, 0x34, 0xCF, - 0x1D, 0xDE, 0x92, 0x33, 0xB8, 0xEA, 0xAA, 0x3E - }, - { - 0x1B, 0x53, 0xEE, 0x94, 0xAA, 0xF3, 0x4E, 0x4B, - 0x15, 0x9D, 0x48, 0xDE, 0x35, 0x2C, 0x7F, 0x06, - 0x61, 0xD0, 0xA4, 0x0E, 0xDF, 0xF9, 0x5A, 0x0B, - 0x16, 0x39, 0xB4, 0x09, 0x0E, 0x97, 0x44, 0x72 - }, - { - 0x05, 0x70, 0x5E, 0x2A, 0x81, 0x75, 0x7C, 0x14, - 0xBD, 0x38, 0x3E, 0xA9, 0x8D, 0xDA, 0x54, 0x4E, - 0xB1, 0x0E, 0x6B, 0xC0, 0x7B, 0xAE, 0x43, 0x5E, - 0x25, 0x18, 0xDB, 0xE1, 0x33, 0x52, 0x53, 0x75 - }, - { - 0xD8, 0xB2, 0x86, 0x6E, 0x8A, 0x30, 0x9D, 0xB5, - 0x3E, 0x52, 0x9E, 0xC3, 0x29, 0x11, 0xD8, 0x2F, - 0x5C, 0xA1, 0x6C, 0xFF, 0x76, 0x21, 0x68, 0x91, - 0xA9, 0x67, 0x6A, 0xA3, 0x1A, 0xAA, 0x6C, 0x42 - }, - { - 0xF5, 0x04, 0x1C, 0x24, 0x12, 0x70, 0xEB, 0x04, - 0xC7, 0x1E, 0xC2, 0xC9, 0x5D, 0x4C, 0x38, 0xD8, - 0x03, 0xB1, 0x23, 0x7B, 0x0F, 0x29, 0xFD, 0x4D, - 0xB3, 0xEB, 0x39, 0x76, 0x69, 0xE8, 0x86, 0x99 - }, - { - 0x9A, 0x4C, 0xE0, 0x77, 0xC3, 0x49, 0x32, 0x2F, - 0x59, 0x5E, 0x0E, 0xE7, 0x9E, 0xD0, 0xDA, 0x5F, - 0xAB, 0x66, 0x75, 0x2C, 0xBF, 0xEF, 0x8F, 0x87, - 0xD0, 0xE9, 0xD0, 0x72, 0x3C, 0x75, 0x30, 0xDD - }, - { - 0x65, 0x7B, 0x09, 0xF3, 0xD0, 0xF5, 0x2B, 0x5B, - 0x8F, 0x2F, 0x97, 0x16, 0x3A, 0x0E, 0xDF, 0x0C, - 0x04, 0xF0, 0x75, 0x40, 0x8A, 0x07, 0xBB, 0xEB, - 0x3A, 0x41, 0x01, 0xA8, 0x91, 0x99, 0x0D, 0x62 - }, - { - 0x1E, 0x3F, 0x7B, 0xD5, 0xA5, 0x8F, 0xA5, 0x33, - 0x34, 0x4A, 0xA8, 0xED, 0x3A, 0xC1, 0x22, 0xBB, - 0x9E, 0x70, 0xD4, 0xEF, 0x50, 0xD0, 0x04, 0x53, - 0x08, 0x21, 0x94, 0x8F, 0x5F, 0xE6, 0x31, 0x5A - }, - { - 0x80, 0xDC, 0xCF, 0x3F, 0xD8, 0x3D, 0xFD, 0x0D, - 0x35, 0xAA, 0x28, 0x58, 0x59, 0x22, 0xAB, 0x89, - 0xD5, 0x31, 0x39, 0x97, 0x67, 0x3E, 0xAF, 0x90, - 0x5C, 0xEA, 0x9C, 0x0B, 0x22, 0x5C, 0x7B, 0x5F - }, - { - 0x8A, 0x0D, 0x0F, 0xBF, 0x63, 0x77, 0xD8, 0x3B, - 0xB0, 0x8B, 0x51, 0x4B, 0x4B, 0x1C, 0x43, 0xAC, - 0xC9, 0x5D, 0x75, 0x17, 0x14, 0xF8, 0x92, 0x56, - 0x45, 0xCB, 0x6B, 0xC8, 0x56, 0xCA, 0x15, 0x0A - }, - { - 0x9F, 0xA5, 0xB4, 0x87, 0x73, 0x8A, 0xD2, 0x84, - 0x4C, 0xC6, 0x34, 0x8A, 0x90, 0x19, 0x18, 0xF6, - 0x59, 0xA3, 0xB8, 0x9E, 0x9C, 0x0D, 0xFE, 0xEA, - 0xD3, 0x0D, 0xD9, 0x4B, 0xCF, 0x42, 0xEF, 0x8E - }, - { - 0x80, 0x83, 0x2C, 0x4A, 0x16, 0x77, 0xF5, 0xEA, - 0x25, 0x60, 0xF6, 0x68, 0xE9, 0x35, 0x4D, 0xD3, - 0x69, 0x97, 0xF0, 0x37, 0x28, 0xCF, 0xA5, 0x5E, - 0x1B, 0x38, 0x33, 0x7C, 0x0C, 0x9E, 0xF8, 0x18 - }, - { - 0xAB, 0x37, 0xDD, 0xB6, 0x83, 0x13, 0x7E, 0x74, - 0x08, 0x0D, 0x02, 0x6B, 0x59, 0x0B, 0x96, 0xAE, - 0x9B, 0xB4, 0x47, 0x72, 0x2F, 0x30, 0x5A, 0x5A, - 0xC5, 0x70, 0xEC, 0x1D, 0xF9, 0xB1, 0x74, 0x3C - }, - { - 0x3E, 0xE7, 0x35, 0xA6, 0x94, 0xC2, 0x55, 0x9B, - 0x69, 0x3A, 0xA6, 0x86, 0x29, 0x36, 0x1E, 0x15, - 0xD1, 0x22, 0x65, 0xAD, 0x6A, 0x3D, 0xED, 0xF4, - 0x88, 0xB0, 0xB0, 0x0F, 0xAC, 0x97, 0x54, 0xBA - }, - { - 0xD6, 0xFC, 0xD2, 0x32, 0x19, 0xB6, 0x47, 0xE4, - 0xCB, 0xD5, 0xEB, 0x2D, 0x0A, 0xD0, 0x1E, 0xC8, - 0x83, 0x8A, 0x4B, 0x29, 0x01, 0xFC, 0x32, 0x5C, - 0xC3, 0x70, 0x19, 0x81, 0xCA, 0x6C, 0x88, 0x8B - }, - { - 0x05, 0x20, 0xEC, 0x2F, 0x5B, 0xF7, 0xA7, 0x55, - 0xDA, 0xCB, 0x50, 0xC6, 0xBF, 0x23, 0x3E, 0x35, - 0x15, 0x43, 0x47, 0x63, 0xDB, 0x01, 0x39, 0xCC, - 0xD9, 0xFA, 0xEF, 0xBB, 0x82, 0x07, 0x61, 0x2D - }, - { - 0xAF, 0xF3, 0xB7, 0x5F, 0x3F, 0x58, 0x12, 0x64, - 0xD7, 0x66, 0x16, 0x62, 0xB9, 0x2F, 0x5A, 0xD3, - 0x7C, 0x1D, 0x32, 0xBD, 0x45, 0xFF, 0x81, 0xA4, - 0xED, 0x8A, 0xDC, 0x9E, 0xF3, 0x0D, 0xD9, 0x89 - }, - { - 0xD0, 0xDD, 0x65, 0x0B, 0xEF, 0xD3, 0xBA, 0x63, - 0xDC, 0x25, 0x10, 0x2C, 0x62, 0x7C, 0x92, 0x1B, - 0x9C, 0xBE, 0xB0, 0xB1, 0x30, 0x68, 0x69, 0x35, - 0xB5, 0xC9, 0x27, 0xCB, 0x7C, 0xCD, 0x5E, 0x3B - }, - { - 0xE1, 0x14, 0x98, 0x16, 0xB1, 0x0A, 0x85, 0x14, - 0xFB, 0x3E, 0x2C, 0xAB, 0x2C, 0x08, 0xBE, 0xE9, - 0xF7, 0x3C, 0xE7, 0x62, 0x21, 0x70, 0x12, 0x46, - 0xA5, 0x89, 0xBB, 0xB6, 0x73, 0x02, 0xD8, 0xA9 - }, - { - 0x7D, 0xA3, 0xF4, 0x41, 0xDE, 0x90, 0x54, 0x31, - 0x7E, 0x72, 0xB5, 0xDB, 0xF9, 0x79, 0xDA, 0x01, - 0xE6, 0xBC, 0xEE, 0xBB, 0x84, 0x78, 0xEA, 0xE6, - 0xA2, 0x28, 0x49, 0xD9, 0x02, 0x92, 0x63, 0x5C - }, - { - 0x12, 0x30, 0xB1, 0xFC, 0x8A, 0x7D, 0x92, 0x15, - 0xED, 0xC2, 0xD4, 0xA2, 0xDE, 0xCB, 0xDD, 0x0A, - 0x6E, 0x21, 0x6C, 0x92, 0x42, 0x78, 0xC9, 0x1F, - 0xC5, 0xD1, 0x0E, 0x7D, 0x60, 0x19, 0x2D, 0x94 - }, - { - 0x57, 0x50, 0xD7, 0x16, 0xB4, 0x80, 0x8F, 0x75, - 0x1F, 0xEB, 0xC3, 0x88, 0x06, 0xBA, 0x17, 0x0B, - 0xF6, 0xD5, 0x19, 0x9A, 0x78, 0x16, 0xBE, 0x51, - 0x4E, 0x3F, 0x93, 0x2F, 0xBE, 0x0C, 0xB8, 0x71 - }, - { - 0x6F, 0xC5, 0x9B, 0x2F, 0x10, 0xFE, 0xBA, 0x95, - 0x4A, 0xA6, 0x82, 0x0B, 0x3C, 0xA9, 0x87, 0xEE, - 0x81, 0xD5, 0xCC, 0x1D, 0xA3, 0xC6, 0x3C, 0xE8, - 0x27, 0x30, 0x1C, 0x56, 0x9D, 0xFB, 0x39, 0xCE - }, - { - 0xC7, 0xC3, 0xFE, 0x1E, 0xEB, 0xDC, 0x7B, 0x5A, - 0x93, 0x93, 0x26, 0xE8, 0xDD, 0xB8, 0x3E, 0x8B, - 0xF2, 0xB7, 0x80, 0xB6, 0x56, 0x78, 0xCB, 0x62, - 0xF2, 0x08, 0xB0, 0x40, 0xAB, 0xDD, 0x35, 0xE2 - }, - { - 0x0C, 0x75, 0xC1, 0xA1, 0x5C, 0xF3, 0x4A, 0x31, - 0x4E, 0xE4, 0x78, 0xF4, 0xA5, 0xCE, 0x0B, 0x8A, - 0x6B, 0x36, 0x52, 0x8E, 0xF7, 0xA8, 0x20, 0x69, - 0x6C, 0x3E, 0x42, 0x46, 0xC5, 0xA1, 0x58, 0x64 - }, - { - 0x21, 0x6D, 0xC1, 0x2A, 0x10, 0x85, 0x69, 0xA3, - 0xC7, 0xCD, 0xDE, 0x4A, 0xED, 0x43, 0xA6, 0xC3, - 0x30, 0x13, 0x9D, 0xDA, 0x3C, 0xCC, 0x4A, 0x10, - 0x89, 0x05, 0xDB, 0x38, 0x61, 0x89, 0x90, 0x50 - }, - { - 0xA5, 0x7B, 0xE6, 0xAE, 0x67, 0x56, 0xF2, 0x8B, - 0x02, 0xF5, 0x9D, 0xAD, 0xF7, 0xE0, 0xD7, 0xD8, - 0x80, 0x7F, 0x10, 0xFA, 0x15, 0xCE, 0xD1, 0xAD, - 0x35, 0x85, 0x52, 0x1A, 0x1D, 0x99, 0x5A, 0x89 - }, - { - 0x81, 0x6A, 0xEF, 0x87, 0x59, 0x53, 0x71, 0x6C, - 0xD7, 0xA5, 0x81, 0xF7, 0x32, 0xF5, 0x3D, 0xD4, - 0x35, 0xDA, 0xB6, 0x6D, 0x09, 0xC3, 0x61, 0xD2, - 0xD6, 0x59, 0x2D, 0xE1, 0x77, 0x55, 0xD8, 0xA8 - }, - { - 0x9A, 0x76, 0x89, 0x32, 0x26, 0x69, 0x3B, 0x6E, - 0xA9, 0x7E, 0x6A, 0x73, 0x8F, 0x9D, 0x10, 0xFB, - 0x3D, 0x0B, 0x43, 0xAE, 0x0E, 0x8B, 0x7D, 0x81, - 0x23, 0xEA, 0x76, 0xCE, 0x97, 0x98, 0x9C, 0x7E - }, - { - 0x8D, 0xAE, 0xDB, 0x9A, 0x27, 0x15, 0x29, 0xDB, - 0xB7, 0xDC, 0x3B, 0x60, 0x7F, 0xE5, 0xEB, 0x2D, - 0x32, 0x11, 0x77, 0x07, 0x58, 0xDD, 0x3B, 0x0A, - 0x35, 0x93, 0xD2, 0xD7, 0x95, 0x4E, 0x2D, 0x5B - }, - { - 0x16, 0xDB, 0xC0, 0xAA, 0x5D, 0xD2, 0xC7, 0x74, - 0xF5, 0x05, 0x10, 0x0F, 0x73, 0x37, 0x86, 0xD8, - 0xA1, 0x75, 0xFC, 0xBB, 0xB5, 0x9C, 0x43, 0xE1, - 0xFB, 0xFF, 0x3E, 0x1E, 0xAF, 0x31, 0xCB, 0x4A - }, - { - 0x86, 0x06, 0xCB, 0x89, 0x9C, 0x6A, 0xEA, 0xF5, - 0x1B, 0x9D, 0xB0, 0xFE, 0x49, 0x24, 0xA9, 0xFD, - 0x5D, 0xAB, 0xC1, 0x9F, 0x88, 0x26, 0xF2, 0xBC, - 0x1C, 0x1D, 0x7D, 0xA1, 0x4D, 0x2C, 0x2C, 0x99 - }, - { - 0x84, 0x79, 0x73, 0x1A, 0xED, 0xA5, 0x7B, 0xD3, - 0x7E, 0xAD, 0xB5, 0x1A, 0x50, 0x7E, 0x30, 0x7F, - 0x3B, 0xD9, 0x5E, 0x69, 0xDB, 0xCA, 0x94, 0xF3, - 0xBC, 0x21, 0x72, 0x60, 0x66, 0xAD, 0x6D, 0xFD - }, - { - 0x58, 0x47, 0x3A, 0x9E, 0xA8, 0x2E, 0xFA, 0x3F, - 0x3B, 0x3D, 0x8F, 0xC8, 0x3E, 0xD8, 0x86, 0x31, - 0x27, 0xB3, 0x3A, 0xE8, 0xDE, 0xAE, 0x63, 0x07, - 0x20, 0x1E, 0xDB, 0x6D, 0xDE, 0x61, 0xDE, 0x29 - }, - { - 0x9A, 0x92, 0x55, 0xD5, 0x3A, 0xF1, 0x16, 0xDE, - 0x8B, 0xA2, 0x7C, 0xE3, 0x5B, 0x4C, 0x7E, 0x15, - 0x64, 0x06, 0x57, 0xA0, 0xFC, 0xB8, 0x88, 0xC7, - 0x0D, 0x95, 0x43, 0x1D, 0xAC, 0xD8, 0xF8, 0x30 - }, - { - 0x9E, 0xB0, 0x5F, 0xFB, 0xA3, 0x9F, 0xD8, 0x59, - 0x6A, 0x45, 0x49, 0x3E, 0x18, 0xD2, 0x51, 0x0B, - 0xF3, 0xEF, 0x06, 0x5C, 0x51, 0xD6, 0xE1, 0x3A, - 0xBE, 0x66, 0xAA, 0x57, 0xE0, 0x5C, 0xFD, 0xB7 - }, - { - 0x81, 0xDC, 0xC3, 0xA5, 0x05, 0xEA, 0xCE, 0x3F, - 0x87, 0x9D, 0x8F, 0x70, 0x27, 0x76, 0x77, 0x0F, - 0x9D, 0xF5, 0x0E, 0x52, 0x1D, 0x14, 0x28, 0xA8, - 0x5D, 0xAF, 0x04, 0xF9, 0xAD, 0x21, 0x50, 0xE0 - }, - { - 0xE3, 0xE3, 0xC4, 0xAA, 0x3A, 0xCB, 0xBC, 0x85, - 0x33, 0x2A, 0xF9, 0xD5, 0x64, 0xBC, 0x24, 0x16, - 0x5E, 0x16, 0x87, 0xF6, 0xB1, 0xAD, 0xCB, 0xFA, - 0xE7, 0x7A, 0x8F, 0x03, 0xC7, 0x2A, 0xC2, 0x8C - }, - { - 0x67, 0x46, 0xC8, 0x0B, 0x4E, 0xB5, 0x6A, 0xEA, - 0x45, 0xE6, 0x4E, 0x72, 0x89, 0xBB, 0xA3, 0xED, - 0xBF, 0x45, 0xEC, 0xF8, 0x20, 0x64, 0x81, 0xFF, - 0x63, 0x02, 0x12, 0x29, 0x84, 0xCD, 0x52, 0x6A - }, - { - 0x2B, 0x62, 0x8E, 0x52, 0x76, 0x4D, 0x7D, 0x62, - 0xC0, 0x86, 0x8B, 0x21, 0x23, 0x57, 0xCD, 0xD1, - 0x2D, 0x91, 0x49, 0x82, 0x2F, 0x4E, 0x98, 0x45, - 0xD9, 0x18, 0xA0, 0x8D, 0x1A, 0xE9, 0x90, 0xC0 - }, - { - 0xE4, 0xBF, 0xE8, 0x0D, 0x58, 0xC9, 0x19, 0x94, - 0x61, 0x39, 0x09, 0xDC, 0x4B, 0x1A, 0x12, 0x49, - 0x68, 0x96, 0xC0, 0x04, 0xAF, 0x7B, 0x57, 0x01, - 0x48, 0x3D, 0xE4, 0x5D, 0x28, 0x23, 0xD7, 0x8E - }, - { - 0xEB, 0xB4, 0xBA, 0x15, 0x0C, 0xEF, 0x27, 0x34, - 0x34, 0x5B, 0x5D, 0x64, 0x1B, 0xBE, 0xD0, 0x3A, - 0x21, 0xEA, 0xFA, 0xE9, 0x33, 0xC9, 0x9E, 0x00, - 0x92, 0x12, 0xEF, 0x04, 0x57, 0x4A, 0x85, 0x30 - }, - { - 0x39, 0x66, 0xEC, 0x73, 0xB1, 0x54, 0xAC, 0xC6, - 0x97, 0xAC, 0x5C, 0xF5, 0xB2, 0x4B, 0x40, 0xBD, - 0xB0, 0xDB, 0x9E, 0x39, 0x88, 0x36, 0xD7, 0x6D, - 0x4B, 0x88, 0x0E, 0x3B, 0x2A, 0xF1, 0xAA, 0x27 - }, - { - 0xEF, 0x7E, 0x48, 0x31, 0xB3, 0xA8, 0x46, 0x36, - 0x51, 0x8D, 0x6E, 0x4B, 0xFC, 0xE6, 0x4A, 0x43, - 0xDB, 0x2A, 0x5D, 0xDA, 0x9C, 0xCA, 0x2B, 0x44, - 0xF3, 0x90, 0x33, 0xBD, 0xC4, 0x0D, 0x62, 0x43 - }, - { - 0x7A, 0xBF, 0x6A, 0xCF, 0x5C, 0x8E, 0x54, 0x9D, - 0xDB, 0xB1, 0x5A, 0xE8, 0xD8, 0xB3, 0x88, 0xC1, - 0xC1, 0x97, 0xE6, 0x98, 0x73, 0x7C, 0x97, 0x85, - 0x50, 0x1E, 0xD1, 0xF9, 0x49, 0x30, 0xB7, 0xD9 - }, - { - 0x88, 0x01, 0x8D, 0xED, 0x66, 0x81, 0x3F, 0x0C, - 0xA9, 0x5D, 0xEF, 0x47, 0x4C, 0x63, 0x06, 0x92, - 0x01, 0x99, 0x67, 0xB9, 0xE3, 0x68, 0x88, 0xDA, - 0xDD, 0x94, 0x12, 0x47, 0x19, 0xB6, 0x82, 0xF6 - }, - { - 0x39, 0x30, 0x87, 0x6B, 0x9F, 0xC7, 0x52, 0x90, - 0x36, 0xB0, 0x08, 0xB1, 0xB8, 0xBB, 0x99, 0x75, - 0x22, 0xA4, 0x41, 0x63, 0x5A, 0x0C, 0x25, 0xEC, - 0x02, 0xFB, 0x6D, 0x90, 0x26, 0xE5, 0x5A, 0x97 - }, - { - 0x0A, 0x40, 0x49, 0xD5, 0x7E, 0x83, 0x3B, 0x56, - 0x95, 0xFA, 0xC9, 0x3D, 0xD1, 0xFB, 0xEF, 0x31, - 0x66, 0xB4, 0x4B, 0x12, 0xAD, 0x11, 0x24, 0x86, - 0x62, 0x38, 0x3A, 0xE0, 0x51, 0xE1, 0x58, 0x27 - }, - { - 0x81, 0xDC, 0xC0, 0x67, 0x8B, 0xB6, 0xA7, 0x65, - 0xE4, 0x8C, 0x32, 0x09, 0x65, 0x4F, 0xE9, 0x00, - 0x89, 0xCE, 0x44, 0xFF, 0x56, 0x18, 0x47, 0x7E, - 0x39, 0xAB, 0x28, 0x64, 0x76, 0xDF, 0x05, 0x2B - }, - { - 0xE6, 0x9B, 0x3A, 0x36, 0xA4, 0x46, 0x19, 0x12, - 0xDC, 0x08, 0x34, 0x6B, 0x11, 0xDD, 0xCB, 0x9D, - 0xB7, 0x96, 0xF8, 0x85, 0xFD, 0x01, 0x93, 0x6E, - 0x66, 0x2F, 0xE2, 0x92, 0x97, 0xB0, 0x99, 0xA4 - }, - { - 0x5A, 0xC6, 0x50, 0x3B, 0x0D, 0x8D, 0xA6, 0x91, - 0x76, 0x46, 0xE6, 0xDC, 0xC8, 0x7E, 0xDC, 0x58, - 0xE9, 0x42, 0x45, 0x32, 0x4C, 0xC2, 0x04, 0xF4, - 0xDD, 0x4A, 0xF0, 0x15, 0x63, 0xAC, 0xD4, 0x27 - }, - { - 0xDF, 0x6D, 0xDA, 0x21, 0x35, 0x9A, 0x30, 0xBC, - 0x27, 0x17, 0x80, 0x97, 0x1C, 0x1A, 0xBD, 0x56, - 0xA6, 0xEF, 0x16, 0x7E, 0x48, 0x08, 0x87, 0x88, - 0x8E, 0x73, 0xA8, 0x6D, 0x3B, 0xF6, 0x05, 0xE9 - }, - { - 0xE8, 0xE6, 0xE4, 0x70, 0x71, 0xE7, 0xB7, 0xDF, - 0x25, 0x80, 0xF2, 0x25, 0xCF, 0xBB, 0xED, 0xF8, - 0x4C, 0xE6, 0x77, 0x46, 0x62, 0x66, 0x28, 0xD3, - 0x30, 0x97, 0xE4, 0xB7, 0xDC, 0x57, 0x11, 0x07 - }, - { - 0x53, 0xE4, 0x0E, 0xAD, 0x62, 0x05, 0x1E, 0x19, - 0xCB, 0x9B, 0xA8, 0x13, 0x3E, 0x3E, 0x5C, 0x1C, - 0xE0, 0x0D, 0xDC, 0xAD, 0x8A, 0xCF, 0x34, 0x2A, - 0x22, 0x43, 0x60, 0xB0, 0xAC, 0xC1, 0x47, 0x77 - }, - { - 0x9C, 0xCD, 0x53, 0xFE, 0x80, 0xBE, 0x78, 0x6A, - 0xA9, 0x84, 0x63, 0x84, 0x62, 0xFB, 0x28, 0xAF, - 0xDF, 0x12, 0x2B, 0x34, 0xD7, 0x8F, 0x46, 0x87, - 0xEC, 0x63, 0x2B, 0xB1, 0x9D, 0xE2, 0x37, 0x1A - }, - { - 0xCB, 0xD4, 0x80, 0x52, 0xC4, 0x8D, 0x78, 0x84, - 0x66, 0xA3, 0xE8, 0x11, 0x8C, 0x56, 0xC9, 0x7F, - 0xE1, 0x46, 0xE5, 0x54, 0x6F, 0xAA, 0xF9, 0x3E, - 0x2B, 0xC3, 0xC4, 0x7E, 0x45, 0x93, 0x97, 0x53 - }, - { - 0x25, 0x68, 0x83, 0xB1, 0x4E, 0x2A, 0xF4, 0x4D, - 0xAD, 0xB2, 0x8E, 0x1B, 0x34, 0xB2, 0xAC, 0x0F, - 0x0F, 0x4C, 0x91, 0xC3, 0x4E, 0xC9, 0x16, 0x9E, - 0x29, 0x03, 0x61, 0x58, 0xAC, 0xAA, 0x95, 0xB9 - }, - { - 0x44, 0x71, 0xB9, 0x1A, 0xB4, 0x2D, 0xB7, 0xC4, - 0xDD, 0x84, 0x90, 0xAB, 0x95, 0xA2, 0xEE, 0x8D, - 0x04, 0xE3, 0xEF, 0x5C, 0x3D, 0x6F, 0xC7, 0x1A, - 0xC7, 0x4B, 0x2B, 0x26, 0x91, 0x4D, 0x16, 0x41 - }, - { - 0xA5, 0xEB, 0x08, 0x03, 0x8F, 0x8F, 0x11, 0x55, - 0xED, 0x86, 0xE6, 0x31, 0x90, 0x6F, 0xC1, 0x30, - 0x95, 0xF6, 0xBB, 0xA4, 0x1D, 0xE5, 0xD4, 0xE7, - 0x95, 0x75, 0x8E, 0xC8, 0xC8, 0xDF, 0x8A, 0xF1 - }, - { - 0xDC, 0x1D, 0xB6, 0x4E, 0xD8, 0xB4, 0x8A, 0x91, - 0x0E, 0x06, 0x0A, 0x6B, 0x86, 0x63, 0x74, 0xC5, - 0x78, 0x78, 0x4E, 0x9A, 0xC4, 0x9A, 0xB2, 0x77, - 0x40, 0x92, 0xAC, 0x71, 0x50, 0x19, 0x34, 0xAC - }, - { - 0x28, 0x54, 0x13, 0xB2, 0xF2, 0xEE, 0x87, 0x3D, - 0x34, 0x31, 0x9E, 0xE0, 0xBB, 0xFB, 0xB9, 0x0F, - 0x32, 0xDA, 0x43, 0x4C, 0xC8, 0x7E, 0x3D, 0xB5, - 0xED, 0x12, 0x1B, 0xB3, 0x98, 0xED, 0x96, 0x4B - }, - { - 0x02, 0x16, 0xE0, 0xF8, 0x1F, 0x75, 0x0F, 0x26, - 0xF1, 0x99, 0x8B, 0xC3, 0x93, 0x4E, 0x3E, 0x12, - 0x4C, 0x99, 0x45, 0xE6, 0x85, 0xA6, 0x0B, 0x25, - 0xE8, 0xFB, 0xD9, 0x62, 0x5A, 0xB6, 0xB5, 0x99 - }, - { - 0x38, 0xC4, 0x10, 0xF5, 0xB9, 0xD4, 0x07, 0x20, - 0x50, 0x75, 0x5B, 0x31, 0xDC, 0xA8, 0x9F, 0xD5, - 0x39, 0x5C, 0x67, 0x85, 0xEE, 0xB3, 0xD7, 0x90, - 0xF3, 0x20, 0xFF, 0x94, 0x1C, 0x5A, 0x93, 0xBF - }, - { - 0xF1, 0x84, 0x17, 0xB3, 0x9D, 0x61, 0x7A, 0xB1, - 0xC1, 0x8F, 0xDF, 0x91, 0xEB, 0xD0, 0xFC, 0x6D, - 0x55, 0x16, 0xBB, 0x34, 0xCF, 0x39, 0x36, 0x40, - 0x37, 0xBC, 0xE8, 0x1F, 0xA0, 0x4C, 0xEC, 0xB1 - }, - { - 0x1F, 0xA8, 0x77, 0xDE, 0x67, 0x25, 0x9D, 0x19, - 0x86, 0x3A, 0x2A, 0x34, 0xBC, 0xC6, 0x96, 0x2A, - 0x2B, 0x25, 0xFC, 0xBF, 0x5C, 0xBE, 0xCD, 0x7E, - 0xDE, 0x8F, 0x1F, 0xA3, 0x66, 0x88, 0xA7, 0x96 - }, - { - 0x5B, 0xD1, 0x69, 0xE6, 0x7C, 0x82, 0xC2, 0xC2, - 0xE9, 0x8E, 0xF7, 0x00, 0x8B, 0xDF, 0x26, 0x1F, - 0x2D, 0xDF, 0x30, 0xB1, 0xC0, 0x0F, 0x9E, 0x7F, - 0x27, 0x5B, 0xB3, 0xE8, 0xA2, 0x8D, 0xC9, 0xA2 - }, - { - 0xC8, 0x0A, 0xBE, 0xEB, 0xB6, 0x69, 0xAD, 0x5D, - 0xEE, 0xB5, 0xF5, 0xEC, 0x8E, 0xA6, 0xB7, 0xA0, - 0x5D, 0xDF, 0x7D, 0x31, 0xEC, 0x4C, 0x0A, 0x2E, - 0xE2, 0x0B, 0x0B, 0x98, 0xCA, 0xEC, 0x67, 0x46 - }, - { - 0xE7, 0x6D, 0x3F, 0xBD, 0xA5, 0xBA, 0x37, 0x4E, - 0x6B, 0xF8, 0xE5, 0x0F, 0xAD, 0xC3, 0xBB, 0xB9, - 0xBA, 0x5C, 0x20, 0x6E, 0xBD, 0xEC, 0x89, 0xA3, - 0xA5, 0x4C, 0xF3, 0xDD, 0x84, 0xA0, 0x70, 0x16 - }, - { - 0x7B, 0xBA, 0x9D, 0xC5, 0xB5, 0xDB, 0x20, 0x71, - 0xD1, 0x77, 0x52, 0xB1, 0x04, 0x4C, 0x1E, 0xCE, - 0xD9, 0x6A, 0xAF, 0x2D, 0xD4, 0x6E, 0x9B, 0x43, - 0x37, 0x50, 0xE8, 0xEA, 0x0D, 0xCC, 0x18, 0x70 - }, - { - 0xF2, 0x9B, 0x1B, 0x1A, 0xB9, 0xBA, 0xB1, 0x63, - 0x01, 0x8E, 0xE3, 0xDA, 0x15, 0x23, 0x2C, 0xCA, - 0x78, 0xEC, 0x52, 0xDB, 0xC3, 0x4E, 0xDA, 0x5B, - 0x82, 0x2E, 0xC1, 0xD8, 0x0F, 0xC2, 0x1B, 0xD0 - }, - { - 0x9E, 0xE3, 0xE3, 0xE7, 0xE9, 0x00, 0xF1, 0xE1, - 0x1D, 0x30, 0x8C, 0x4B, 0x2B, 0x30, 0x76, 0xD2, - 0x72, 0xCF, 0x70, 0x12, 0x4F, 0x9F, 0x51, 0xE1, - 0xDA, 0x60, 0xF3, 0x78, 0x46, 0xCD, 0xD2, 0xF4 - }, - { - 0x70, 0xEA, 0x3B, 0x01, 0x76, 0x92, 0x7D, 0x90, - 0x96, 0xA1, 0x85, 0x08, 0xCD, 0x12, 0x3A, 0x29, - 0x03, 0x25, 0x92, 0x0A, 0x9D, 0x00, 0xA8, 0x9B, - 0x5D, 0xE0, 0x42, 0x73, 0xFB, 0xC7, 0x6B, 0x85 - }, - { - 0x67, 0xDE, 0x25, 0xC0, 0x2A, 0x4A, 0xAB, 0xA2, - 0x3B, 0xDC, 0x97, 0x3C, 0x8B, 0xB0, 0xB5, 0x79, - 0x6D, 0x47, 0xCC, 0x06, 0x59, 0xD4, 0x3D, 0xFF, - 0x1F, 0x97, 0xDE, 0x17, 0x49, 0x63, 0xB6, 0x8E - }, - { - 0xB2, 0x16, 0x8E, 0x4E, 0x0F, 0x18, 0xB0, 0xE6, - 0x41, 0x00, 0xB5, 0x17, 0xED, 0x95, 0x25, 0x7D, - 0x73, 0xF0, 0x62, 0x0D, 0xF8, 0x85, 0xC1, 0x3D, - 0x2E, 0xCF, 0x79, 0x36, 0x7B, 0x38, 0x4C, 0xEE - }, - { - 0x2E, 0x7D, 0xEC, 0x24, 0x28, 0x85, 0x3B, 0x2C, - 0x71, 0x76, 0x07, 0x45, 0x54, 0x1F, 0x7A, 0xFE, - 0x98, 0x25, 0xB5, 0xDD, 0x77, 0xDF, 0x06, 0x51, - 0x1D, 0x84, 0x41, 0xA9, 0x4B, 0xAC, 0xC9, 0x27 - }, - { - 0xCA, 0x9F, 0xFA, 0xC4, 0xC4, 0x3F, 0x0B, 0x48, - 0x46, 0x1D, 0xC5, 0xC2, 0x63, 0xBE, 0xA3, 0xF6, - 0xF0, 0x06, 0x11, 0xCE, 0xAC, 0xAB, 0xF6, 0xF8, - 0x95, 0xBA, 0x2B, 0x01, 0x01, 0xDB, 0xB6, 0x8D - }, - { - 0x74, 0x10, 0xD4, 0x2D, 0x8F, 0xD1, 0xD5, 0xE9, - 0xD2, 0xF5, 0x81, 0x5C, 0xB9, 0x34, 0x17, 0x99, - 0x88, 0x28, 0xEF, 0x3C, 0x42, 0x30, 0xBF, 0xBD, - 0x41, 0x2D, 0xF0, 0xA4, 0xA7, 0xA2, 0x50, 0x7A - }, - { - 0x50, 0x10, 0xF6, 0x84, 0x51, 0x6D, 0xCC, 0xD0, - 0xB6, 0xEE, 0x08, 0x52, 0xC2, 0x51, 0x2B, 0x4D, - 0xC0, 0x06, 0x6C, 0xF0, 0xD5, 0x6F, 0x35, 0x30, - 0x29, 0x78, 0xDB, 0x8A, 0xE3, 0x2C, 0x6A, 0x81 - }, - { - 0xAC, 0xAA, 0xB5, 0x85, 0xF7, 0xB7, 0x9B, 0x71, - 0x99, 0x35, 0xCE, 0xB8, 0x95, 0x23, 0xDD, 0xC5, - 0x48, 0x27, 0xF7, 0x5C, 0x56, 0x88, 0x38, 0x56, - 0x15, 0x4A, 0x56, 0xCD, 0xCD, 0x5E, 0xE9, 0x88 - }, - { - 0x66, 0x6D, 0xE5, 0xD1, 0x44, 0x0F, 0xEE, 0x73, - 0x31, 0xAA, 0xF0, 0x12, 0x3A, 0x62, 0xEF, 0x2D, - 0x8B, 0xA5, 0x74, 0x53, 0xA0, 0x76, 0x96, 0x35, - 0xAC, 0x6C, 0xD0, 0x1E, 0x63, 0x3F, 0x77, 0x12 - }, - { - 0xA6, 0xF9, 0x86, 0x58, 0xF6, 0xEA, 0xBA, 0xF9, - 0x02, 0xD8, 0xB3, 0x87, 0x1A, 0x4B, 0x10, 0x1D, - 0x16, 0x19, 0x6E, 0x8A, 0x4B, 0x24, 0x1E, 0x15, - 0x58, 0xFE, 0x29, 0x96, 0x6E, 0x10, 0x3E, 0x8D - }, - { - 0x89, 0x15, 0x46, 0xA8, 0xB2, 0x9F, 0x30, 0x47, - 0xDD, 0xCF, 0xE5, 0xB0, 0x0E, 0x45, 0xFD, 0x55, - 0x75, 0x63, 0x73, 0x10, 0x5E, 0xA8, 0x63, 0x7D, - 0xFC, 0xFF, 0x54, 0x7B, 0x6E, 0xA9, 0x53, 0x5F - }, - { - 0x18, 0xDF, 0xBC, 0x1A, 0xC5, 0xD2, 0x5B, 0x07, - 0x61, 0x13, 0x7D, 0xBD, 0x22, 0xC1, 0x7C, 0x82, - 0x9D, 0x0F, 0x0E, 0xF1, 0xD8, 0x23, 0x44, 0xE9, - 0xC8, 0x9C, 0x28, 0x66, 0x94, 0xDA, 0x24, 0xE8 - }, - { - 0xB5, 0x4B, 0x9B, 0x67, 0xF8, 0xFE, 0xD5, 0x4B, - 0xBF, 0x5A, 0x26, 0x66, 0xDB, 0xDF, 0x4B, 0x23, - 0xCF, 0xF1, 0xD1, 0xB6, 0xF4, 0xAF, 0xC9, 0x85, - 0xB2, 0xE6, 0xD3, 0x30, 0x5A, 0x9F, 0xF8, 0x0F - }, - { - 0x7D, 0xB4, 0x42, 0xE1, 0x32, 0xBA, 0x59, 0xBC, - 0x12, 0x89, 0xAA, 0x98, 0xB0, 0xD3, 0xE8, 0x06, - 0x00, 0x4F, 0x8E, 0xC1, 0x28, 0x11, 0xAF, 0x1E, - 0x2E, 0x33, 0xC6, 0x9B, 0xFD, 0xE7, 0x29, 0xE1 - }, - { - 0x25, 0x0F, 0x37, 0xCD, 0xC1, 0x5E, 0x81, 0x7D, - 0x2F, 0x16, 0x0D, 0x99, 0x56, 0xC7, 0x1F, 0xE3, - 0xEB, 0x5D, 0xB7, 0x45, 0x56, 0xE4, 0xAD, 0xF9, - 0xA4, 0xFF, 0xAF, 0xBA, 0x74, 0x01, 0x03, 0x96 - }, - { - 0x4A, 0xB8, 0xA3, 0xDD, 0x1D, 0xDF, 0x8A, 0xD4, - 0x3D, 0xAB, 0x13, 0xA2, 0x7F, 0x66, 0xA6, 0x54, - 0x4F, 0x29, 0x05, 0x97, 0xFA, 0x96, 0x04, 0x0E, - 0x0E, 0x1D, 0xB9, 0x26, 0x3A, 0xA4, 0x79, 0xF8 - }, - { - 0xEE, 0x61, 0x72, 0x7A, 0x07, 0x66, 0xDF, 0x93, - 0x9C, 0xCD, 0xC8, 0x60, 0x33, 0x40, 0x44, 0xC7, - 0x9A, 0x3C, 0x9B, 0x15, 0x62, 0x00, 0xBC, 0x3A, - 0xA3, 0x29, 0x73, 0x48, 0x3D, 0x83, 0x41, 0xAE - }, - { - 0x3F, 0x68, 0xC7, 0xEC, 0x63, 0xAC, 0x11, 0xEB, - 0xB9, 0x8F, 0x94, 0xB3, 0x39, 0xB0, 0x5C, 0x10, - 0x49, 0x84, 0xFD, 0xA5, 0x01, 0x03, 0x06, 0x01, - 0x44, 0xE5, 0xA2, 0xBF, 0xCC, 0xC9, 0xDA, 0x95 - }, - { - 0x05, 0x6F, 0x29, 0x81, 0x6B, 0x8A, 0xF8, 0xF5, - 0x66, 0x82, 0xBC, 0x4D, 0x7C, 0xF0, 0x94, 0x11, - 0x1D, 0xA7, 0x73, 0x3E, 0x72, 0x6C, 0xD1, 0x3D, - 0x6B, 0x3E, 0x8E, 0xA0, 0x3E, 0x92, 0xA0, 0xD5 - }, - { - 0xF5, 0xEC, 0x43, 0xA2, 0x8A, 0xCB, 0xEF, 0xF1, - 0xF3, 0x31, 0x8A, 0x5B, 0xCA, 0xC7, 0xC6, 0x6D, - 0xDB, 0x52, 0x30, 0xB7, 0x9D, 0xB2, 0xD1, 0x05, - 0xBC, 0xBE, 0x15, 0xF3, 0xC1, 0x14, 0x8D, 0x69 - }, - { - 0x2A, 0x69, 0x60, 0xAD, 0x1D, 0x8D, 0xD5, 0x47, - 0x55, 0x5C, 0xFB, 0xD5, 0xE4, 0x60, 0x0F, 0x1E, - 0xAA, 0x1C, 0x8E, 0xDA, 0x34, 0xDE, 0x03, 0x74, - 0xEC, 0x4A, 0x26, 0xEA, 0xAA, 0xA3, 0x3B, 0x4E - }, - { - 0xDC, 0xC1, 0xEA, 0x7B, 0xAA, 0xB9, 0x33, 0x84, - 0xF7, 0x6B, 0x79, 0x68, 0x66, 0x19, 0x97, 0x54, - 0x74, 0x2F, 0x7B, 0x96, 0xD6, 0xB4, 0xC1, 0x20, - 0x16, 0x5C, 0x04, 0xA6, 0xC4, 0xF5, 0xCE, 0x10 - }, - { - 0x13, 0xD5, 0xDF, 0x17, 0x92, 0x21, 0x37, 0x9C, - 0x6A, 0x78, 0xC0, 0x7C, 0x79, 0x3F, 0xF5, 0x34, - 0x87, 0xCA, 0xE6, 0xBF, 0x9F, 0xE8, 0x82, 0x54, - 0x1A, 0xB0, 0xE7, 0x35, 0xE3, 0xEA, 0xDA, 0x3B - }, - { - 0x8C, 0x59, 0xE4, 0x40, 0x76, 0x41, 0xA0, 0x1E, - 0x8F, 0xF9, 0x1F, 0x99, 0x80, 0xDC, 0x23, 0x6F, - 0x4E, 0xCD, 0x6F, 0xCF, 0x52, 0x58, 0x9A, 0x09, - 0x9A, 0x96, 0x16, 0x33, 0x96, 0x77, 0x14, 0xE1 - }, - { - 0x83, 0x3B, 0x1A, 0xC6, 0xA2, 0x51, 0xFD, 0x08, - 0xFD, 0x6D, 0x90, 0x8F, 0xEA, 0x2A, 0x4E, 0xE1, - 0xE0, 0x40, 0xBC, 0xA9, 0x3F, 0xC1, 0xA3, 0x8E, - 0xC3, 0x82, 0x0E, 0x0C, 0x10, 0xBD, 0x82, 0xEA - }, - { - 0xA2, 0x44, 0xF9, 0x27, 0xF3, 0xB4, 0x0B, 0x8F, - 0x6C, 0x39, 0x15, 0x70, 0xC7, 0x65, 0x41, 0x8F, - 0x2F, 0x6E, 0x70, 0x8E, 0xAC, 0x90, 0x06, 0xC5, - 0x1A, 0x7F, 0xEF, 0xF4, 0xAF, 0x3B, 0x2B, 0x9E - }, - { - 0x3D, 0x99, 0xED, 0x95, 0x50, 0xCF, 0x11, 0x96, - 0xE6, 0xC4, 0xD2, 0x0C, 0x25, 0x96, 0x20, 0xF8, - 0x58, 0xC3, 0xD7, 0x03, 0x37, 0x4C, 0x12, 0x8C, - 0xE7, 0xB5, 0x90, 0x31, 0x0C, 0x83, 0x04, 0x6D - }, - { - 0x2B, 0x35, 0xC4, 0x7D, 0x7B, 0x87, 0x76, 0x1F, - 0x0A, 0xE4, 0x3A, 0xC5, 0x6A, 0xC2, 0x7B, 0x9F, - 0x25, 0x83, 0x03, 0x67, 0xB5, 0x95, 0xBE, 0x8C, - 0x24, 0x0E, 0x94, 0x60, 0x0C, 0x6E, 0x33, 0x12 - }, - { - 0x5D, 0x11, 0xED, 0x37, 0xD2, 0x4D, 0xC7, 0x67, - 0x30, 0x5C, 0xB7, 0xE1, 0x46, 0x7D, 0x87, 0xC0, - 0x65, 0xAC, 0x4B, 0xC8, 0xA4, 0x26, 0xDE, 0x38, - 0x99, 0x1F, 0xF5, 0x9A, 0xA8, 0x73, 0x5D, 0x02 - }, - { - 0xB8, 0x36, 0x47, 0x8E, 0x1C, 0xA0, 0x64, 0x0D, - 0xCE, 0x6F, 0xD9, 0x10, 0xA5, 0x09, 0x62, 0x72, - 0xC8, 0x33, 0x09, 0x90, 0xCD, 0x97, 0x86, 0x4A, - 0xC2, 0xBF, 0x14, 0xEF, 0x6B, 0x23, 0x91, 0x4A - }, - { - 0x91, 0x00, 0xF9, 0x46, 0xD6, 0xCC, 0xDE, 0x3A, - 0x59, 0x7F, 0x90, 0xD3, 0x9F, 0xC1, 0x21, 0x5B, - 0xAD, 0xDC, 0x74, 0x13, 0x64, 0x3D, 0x85, 0xC2, - 0x1C, 0x3E, 0xEE, 0x5D, 0x2D, 0xD3, 0x28, 0x94 - }, - { - 0xDA, 0x70, 0xEE, 0xDD, 0x23, 0xE6, 0x63, 0xAA, - 0x1A, 0x74, 0xB9, 0x76, 0x69, 0x35, 0xB4, 0x79, - 0x22, 0x2A, 0x72, 0xAF, 0xBA, 0x5C, 0x79, 0x51, - 0x58, 0xDA, 0xD4, 0x1A, 0x3B, 0xD7, 0x7E, 0x40 - }, - { - 0xF0, 0x67, 0xED, 0x6A, 0x0D, 0xBD, 0x43, 0xAA, - 0x0A, 0x92, 0x54, 0xE6, 0x9F, 0xD6, 0x6B, 0xDD, - 0x8A, 0xCB, 0x87, 0xDE, 0x93, 0x6C, 0x25, 0x8C, - 0xFB, 0x02, 0x28, 0x5F, 0x2C, 0x11, 0xFA, 0x79 - }, - { - 0x71, 0x5C, 0x99, 0xC7, 0xD5, 0x75, 0x80, 0xCF, - 0x97, 0x53, 0xB4, 0xC1, 0xD7, 0x95, 0xE4, 0x5A, - 0x83, 0xFB, 0xB2, 0x28, 0xC0, 0xD3, 0x6F, 0xBE, - 0x20, 0xFA, 0xF3, 0x9B, 0xDD, 0x6D, 0x4E, 0x85 - }, - { - 0xE4, 0x57, 0xD6, 0xAD, 0x1E, 0x67, 0xCB, 0x9B, - 0xBD, 0x17, 0xCB, 0xD6, 0x98, 0xFA, 0x6D, 0x7D, - 0xAE, 0x0C, 0x9B, 0x7A, 0xD6, 0xCB, 0xD6, 0x53, - 0x96, 0x34, 0xE3, 0x2A, 0x71, 0x9C, 0x84, 0x92 - }, - { - 0xEC, 0xE3, 0xEA, 0x81, 0x03, 0xE0, 0x24, 0x83, - 0xC6, 0x4A, 0x70, 0xA4, 0xBD, 0xCE, 0xE8, 0xCE, - 0xB6, 0x27, 0x8F, 0x25, 0x33, 0xF3, 0xF4, 0x8D, - 0xBE, 0xED, 0xFB, 0xA9, 0x45, 0x31, 0xD4, 0xAE - }, - { - 0x38, 0x8A, 0xA5, 0xD3, 0x66, 0x7A, 0x97, 0xC6, - 0x8D, 0x3D, 0x56, 0xF8, 0xF3, 0xEE, 0x8D, 0x3D, - 0x36, 0x09, 0x1F, 0x17, 0xFE, 0x5D, 0x1B, 0x0D, - 0x5D, 0x84, 0xC9, 0x3B, 0x2F, 0xFE, 0x40, 0xBD - }, - { - 0x8B, 0x6B, 0x31, 0xB9, 0xAD, 0x7C, 0x3D, 0x5C, - 0xD8, 0x4B, 0xF9, 0x89, 0x47, 0xB9, 0xCD, 0xB5, - 0x9D, 0xF8, 0xA2, 0x5F, 0xF7, 0x38, 0x10, 0x10, - 0x13, 0xBE, 0x4F, 0xD6, 0x5E, 0x1D, 0xD1, 0xA3 - }, - { - 0x06, 0x62, 0x91, 0xF6, 0xBB, 0xD2, 0x5F, 0x3C, - 0x85, 0x3D, 0xB7, 0xD8, 0xB9, 0x5C, 0x9A, 0x1C, - 0xFB, 0x9B, 0xF1, 0xC1, 0xC9, 0x9F, 0xB9, 0x5A, - 0x9B, 0x78, 0x69, 0xD9, 0x0F, 0x1C, 0x29, 0x03 - }, - { - 0xA7, 0x07, 0xEF, 0xBC, 0xCD, 0xCE, 0xED, 0x42, - 0x96, 0x7A, 0x66, 0xF5, 0x53, 0x9B, 0x93, 0xED, - 0x75, 0x60, 0xD4, 0x67, 0x30, 0x40, 0x16, 0xC4, - 0x78, 0x0D, 0x77, 0x55, 0xA5, 0x65, 0xD4, 0xC4 - }, - { - 0x38, 0xC5, 0x3D, 0xFB, 0x70, 0xBE, 0x7E, 0x79, - 0x2B, 0x07, 0xA6, 0xA3, 0x5B, 0x8A, 0x6A, 0x0A, - 0xBA, 0x02, 0xC5, 0xC5, 0xF3, 0x8B, 0xAF, 0x5C, - 0x82, 0x3F, 0xDF, 0xD9, 0xE4, 0x2D, 0x65, 0x7E - }, - { - 0xF2, 0x91, 0x13, 0x86, 0x50, 0x1D, 0x9A, 0xB9, - 0xD7, 0x20, 0xCF, 0x8A, 0xD1, 0x05, 0x03, 0xD5, - 0x63, 0x4B, 0xF4, 0xB7, 0xD1, 0x2B, 0x56, 0xDF, - 0xB7, 0x4F, 0xEC, 0xC6, 0xE4, 0x09, 0x3F, 0x68 - }, - { - 0xC6, 0xF2, 0xBD, 0xD5, 0x2B, 0x81, 0xE6, 0xE4, - 0xF6, 0x59, 0x5A, 0xBD, 0x4D, 0x7F, 0xB3, 0x1F, - 0x65, 0x11, 0x69, 0xD0, 0x0F, 0xF3, 0x26, 0x92, - 0x6B, 0x34, 0x94, 0x7B, 0x28, 0xA8, 0x39, 0x59 - }, - { - 0x29, 0x3D, 0x94, 0xB1, 0x8C, 0x98, 0xBB, 0x32, - 0x23, 0x36, 0x6B, 0x8C, 0xE7, 0x4C, 0x28, 0xFB, - 0xDF, 0x28, 0xE1, 0xF8, 0x4A, 0x33, 0x50, 0xB0, - 0xEB, 0x2D, 0x18, 0x04, 0xA5, 0x77, 0x57, 0x9B - }, - { - 0x2C, 0x2F, 0xA5, 0xC0, 0xB5, 0x15, 0x33, 0x16, - 0x5B, 0xC3, 0x75, 0xC2, 0x2E, 0x27, 0x81, 0x76, - 0x82, 0x70, 0xA3, 0x83, 0x98, 0x5D, 0x13, 0xBD, - 0x6B, 0x67, 0xB6, 0xFD, 0x67, 0xF8, 0x89, 0xEB - }, - { - 0xCA, 0xA0, 0x9B, 0x82, 0xB7, 0x25, 0x62, 0xE4, - 0x3F, 0x4B, 0x22, 0x75, 0xC0, 0x91, 0x91, 0x8E, - 0x62, 0x4D, 0x91, 0x16, 0x61, 0xCC, 0x81, 0x1B, - 0xB5, 0xFA, 0xEC, 0x51, 0xF6, 0x08, 0x8E, 0xF7 - }, - { - 0x24, 0x76, 0x1E, 0x45, 0xE6, 0x74, 0x39, 0x53, - 0x79, 0xFB, 0x17, 0x72, 0x9C, 0x78, 0xCB, 0x93, - 0x9E, 0x6F, 0x74, 0xC5, 0xDF, 0xFB, 0x9C, 0x96, - 0x1F, 0x49, 0x59, 0x82, 0xC3, 0xED, 0x1F, 0xE3 - }, - { - 0x55, 0xB7, 0x0A, 0x82, 0x13, 0x1E, 0xC9, 0x48, - 0x88, 0xD7, 0xAB, 0x54, 0xA7, 0xC5, 0x15, 0x25, - 0x5C, 0x39, 0x38, 0xBB, 0x10, 0xBC, 0x78, 0x4D, - 0xC9, 0xB6, 0x7F, 0x07, 0x6E, 0x34, 0x1A, 0x73 - }, - { - 0x6A, 0xB9, 0x05, 0x7B, 0x97, 0x7E, 0xBC, 0x3C, - 0xA4, 0xD4, 0xCE, 0x74, 0x50, 0x6C, 0x25, 0xCC, - 0xCD, 0xC5, 0x66, 0x49, 0x7C, 0x45, 0x0B, 0x54, - 0x15, 0xA3, 0x94, 0x86, 0xF8, 0x65, 0x7A, 0x03 - }, - { - 0x24, 0x06, 0x6D, 0xEE, 0xE0, 0xEC, 0xEE, 0x15, - 0xA4, 0x5F, 0x0A, 0x32, 0x6D, 0x0F, 0x8D, 0xBC, - 0x79, 0x76, 0x1E, 0xBB, 0x93, 0xCF, 0x8C, 0x03, - 0x77, 0xAF, 0x44, 0x09, 0x78, 0xFC, 0xF9, 0x94 - }, - { - 0x20, 0x00, 0x0D, 0x3F, 0x66, 0xBA, 0x76, 0x86, - 0x0D, 0x5A, 0x95, 0x06, 0x88, 0xB9, 0xAA, 0x0D, - 0x76, 0xCF, 0xEA, 0x59, 0xB0, 0x05, 0xD8, 0x59, - 0x91, 0x4B, 0x1A, 0x46, 0x65, 0x3A, 0x93, 0x9B - }, - { - 0xB9, 0x2D, 0xAA, 0x79, 0x60, 0x3E, 0x3B, 0xDB, - 0xC3, 0xBF, 0xE0, 0xF4, 0x19, 0xE4, 0x09, 0xB2, - 0xEA, 0x10, 0xDC, 0x43, 0x5B, 0xEE, 0xFE, 0x29, - 0x59, 0xDA, 0x16, 0x89, 0x5D, 0x5D, 0xCA, 0x1C - }, - { - 0xE9, 0x47, 0x94, 0x87, 0x05, 0xB2, 0x06, 0xD5, - 0x72, 0xB0, 0xE8, 0xF6, 0x2F, 0x66, 0xA6, 0x55, - 0x1C, 0xBD, 0x6B, 0xC3, 0x05, 0xD2, 0x6C, 0xE7, - 0x53, 0x9A, 0x12, 0xF9, 0xAA, 0xDF, 0x75, 0x71 - }, - { - 0x3D, 0x67, 0xC1, 0xB3, 0xF9, 0xB2, 0x39, 0x10, - 0xE3, 0xD3, 0x5E, 0x6B, 0x0F, 0x2C, 0xCF, 0x44, - 0xA0, 0xB5, 0x40, 0xA4, 0x5C, 0x18, 0xBA, 0x3C, - 0x36, 0x26, 0x4D, 0xD4, 0x8E, 0x96, 0xAF, 0x6A - }, - { - 0xC7, 0x55, 0x8B, 0xAB, 0xDA, 0x04, 0xBC, 0xCB, - 0x76, 0x4D, 0x0B, 0xBF, 0x33, 0x58, 0x42, 0x51, - 0x41, 0x90, 0x2D, 0x22, 0x39, 0x1D, 0x9F, 0x8C, - 0x59, 0x15, 0x9F, 0xEC, 0x9E, 0x49, 0xB1, 0x51 - }, - { - 0x0B, 0x73, 0x2B, 0xB0, 0x35, 0x67, 0x5A, 0x50, - 0xFF, 0x58, 0xF2, 0xC2, 0x42, 0xE4, 0x71, 0x0A, - 0xEC, 0xE6, 0x46, 0x70, 0x07, 0x9C, 0x13, 0x04, - 0x4C, 0x79, 0xC9, 0xB7, 0x49, 0x1F, 0x70, 0x00 - }, - { - 0xD1, 0x20, 0xB5, 0xEF, 0x6D, 0x57, 0xEB, 0xF0, - 0x6E, 0xAF, 0x96, 0xBC, 0x93, 0x3C, 0x96, 0x7B, - 0x16, 0xCB, 0xE6, 0xE2, 0xBF, 0x00, 0x74, 0x1C, - 0x30, 0xAA, 0x1C, 0x54, 0xBA, 0x64, 0x80, 0x1F - }, - { - 0x58, 0xD2, 0x12, 0xAD, 0x6F, 0x58, 0xAE, 0xF0, - 0xF8, 0x01, 0x16, 0xB4, 0x41, 0xE5, 0x7F, 0x61, - 0x95, 0xBF, 0xEF, 0x26, 0xB6, 0x14, 0x63, 0xED, - 0xEC, 0x11, 0x83, 0xCD, 0xB0, 0x4F, 0xE7, 0x6D - }, - { - 0xB8, 0x83, 0x6F, 0x51, 0xD1, 0xE2, 0x9B, 0xDF, - 0xDB, 0xA3, 0x25, 0x56, 0x53, 0x60, 0x26, 0x8B, - 0x8F, 0xAD, 0x62, 0x74, 0x73, 0xED, 0xEC, 0xEF, - 0x7E, 0xAE, 0xFE, 0xE8, 0x37, 0xC7, 0x40, 0x03 - }, - { - 0xC5, 0x47, 0xA3, 0xC1, 0x24, 0xAE, 0x56, 0x85, - 0xFF, 0xA7, 0xB8, 0xED, 0xAF, 0x96, 0xEC, 0x86, - 0xF8, 0xB2, 0xD0, 0xD5, 0x0C, 0xEE, 0x8B, 0xE3, - 0xB1, 0xF0, 0xC7, 0x67, 0x63, 0x06, 0x9D, 0x9C - }, - { - 0x5D, 0x16, 0x8B, 0x76, 0x9A, 0x2F, 0x67, 0x85, - 0x3D, 0x62, 0x95, 0xF7, 0x56, 0x8B, 0xE4, 0x0B, - 0xB7, 0xA1, 0x6B, 0x8D, 0x65, 0xBA, 0x87, 0x63, - 0x5D, 0x19, 0x78, 0xD2, 0xAB, 0x11, 0xBA, 0x2A - }, - { - 0xA2, 0xF6, 0x75, 0xDC, 0x73, 0x02, 0x63, 0x8C, - 0xB6, 0x02, 0x01, 0x06, 0x4C, 0xA5, 0x50, 0x77, - 0x71, 0x4D, 0x71, 0xFE, 0x09, 0x6A, 0x31, 0x5F, - 0x2F, 0xE7, 0x40, 0x12, 0x77, 0xCA, 0xA5, 0xAF - }, - { - 0xC8, 0xAA, 0xB5, 0xCD, 0x01, 0x60, 0xAE, 0x78, - 0xCD, 0x2E, 0x8A, 0xC5, 0xFB, 0x0E, 0x09, 0x3C, - 0xDB, 0x5C, 0x4B, 0x60, 0x52, 0xA0, 0xA9, 0x7B, - 0xB0, 0x42, 0x16, 0x82, 0x6F, 0xA7, 0xA4, 0x37 - }, - { - 0xFF, 0x68, 0xCA, 0x40, 0x35, 0xBF, 0xEB, 0x43, - 0xFB, 0xF1, 0x45, 0xFD, 0xDD, 0x5E, 0x43, 0xF1, - 0xCE, 0xA5, 0x4F, 0x11, 0xF7, 0xBE, 0xE1, 0x30, - 0x58, 0xF0, 0x27, 0x32, 0x9A, 0x4A, 0x5F, 0xA4 - }, - { - 0x1D, 0x4E, 0x54, 0x87, 0xAE, 0x3C, 0x74, 0x0F, - 0x2B, 0xA6, 0xE5, 0x41, 0xAC, 0x91, 0xBC, 0x2B, - 0xFC, 0xD2, 0x99, 0x9C, 0x51, 0x8D, 0x80, 0x7B, - 0x42, 0x67, 0x48, 0x80, 0x3A, 0x35, 0x0F, 0xD4 - }, - { - 0x6D, 0x24, 0x4E, 0x1A, 0x06, 0xCE, 0x4E, 0xF5, - 0x78, 0xDD, 0x0F, 0x63, 0xAF, 0xF0, 0x93, 0x67, - 0x06, 0x73, 0x51, 0x19, 0xCA, 0x9C, 0x8D, 0x22, - 0xD8, 0x6C, 0x80, 0x14, 0x14, 0xAB, 0x97, 0x41 - }, - { - 0xDE, 0xCF, 0x73, 0x29, 0xDB, 0xCC, 0x82, 0x7B, - 0x8F, 0xC5, 0x24, 0xC9, 0x43, 0x1E, 0x89, 0x98, - 0x02, 0x9E, 0xCE, 0x12, 0xCE, 0x93, 0xB7, 0xB2, - 0xF3, 0xE7, 0x69, 0xA9, 0x41, 0xFB, 0x8C, 0xEA - }, - { - 0x2F, 0xAF, 0xCC, 0x0F, 0x2E, 0x63, 0xCB, 0xD0, - 0x77, 0x55, 0xBE, 0x7B, 0x75, 0xEC, 0xEA, 0x0A, - 0xDF, 0xF9, 0xAA, 0x5E, 0xDE, 0x2A, 0x52, 0xFD, - 0xAB, 0x4D, 0xFD, 0x03, 0x74, 0xCD, 0x48, 0x3F - }, - { - 0xAA, 0x85, 0x01, 0x0D, 0xD4, 0x6A, 0x54, 0x6B, - 0x53, 0x5E, 0xF4, 0xCF, 0x5F, 0x07, 0xD6, 0x51, - 0x61, 0xE8, 0x98, 0x28, 0xF3, 0xA7, 0x7D, 0xB7, - 0xB9, 0xB5, 0x6F, 0x0D, 0xF5, 0x9A, 0xAE, 0x45 - }, - { - 0x07, 0xE8, 0xE1, 0xEE, 0x73, 0x2C, 0xB0, 0xD3, - 0x56, 0xC9, 0xC0, 0xD1, 0x06, 0x9C, 0x89, 0xD1, - 0x7A, 0xDF, 0x6A, 0x9A, 0x33, 0x4F, 0x74, 0x5E, - 0xC7, 0x86, 0x73, 0x32, 0x54, 0x8C, 0xA8, 0xE9 - }, - { - 0x0E, 0x01, 0xE8, 0x1C, 0xAD, 0xA8, 0x16, 0x2B, - 0xFD, 0x5F, 0x8A, 0x8C, 0x81, 0x8A, 0x6C, 0x69, - 0xFE, 0xDF, 0x02, 0xCE, 0xB5, 0x20, 0x85, 0x23, - 0xCB, 0xE5, 0x31, 0x3B, 0x89, 0xCA, 0x10, 0x53 - }, - { - 0x6B, 0xB6, 0xC6, 0x47, 0x26, 0x55, 0x08, 0x43, - 0x99, 0x85, 0x2E, 0x00, 0x24, 0x9F, 0x8C, 0xB2, - 0x47, 0x89, 0x6D, 0x39, 0x2B, 0x02, 0xD7, 0x3B, - 0x7F, 0x0D, 0xD8, 0x18, 0xE1, 0xE2, 0x9B, 0x07 - }, - { - 0x42, 0xD4, 0x63, 0x6E, 0x20, 0x60, 0xF0, 0x8F, - 0x41, 0xC8, 0x82, 0xE7, 0x6B, 0x39, 0x6B, 0x11, - 0x2E, 0xF6, 0x27, 0xCC, 0x24, 0xC4, 0x3D, 0xD5, - 0xF8, 0x3A, 0x1D, 0x1A, 0x7E, 0xAD, 0x71, 0x1A - }, - { - 0x48, 0x58, 0xC9, 0xA1, 0x88, 0xB0, 0x23, 0x4F, - 0xB9, 0xA8, 0xD4, 0x7D, 0x0B, 0x41, 0x33, 0x65, - 0x0A, 0x03, 0x0B, 0xD0, 0x61, 0x1B, 0x87, 0xC3, - 0x89, 0x2E, 0x94, 0x95, 0x1F, 0x8D, 0xF8, 0x52 - }, - { - 0x3F, 0xAB, 0x3E, 0x36, 0x98, 0x8D, 0x44, 0x5A, - 0x51, 0xC8, 0x78, 0x3E, 0x53, 0x1B, 0xE3, 0xA0, - 0x2B, 0xE4, 0x0C, 0xD0, 0x47, 0x96, 0xCF, 0xB6, - 0x1D, 0x40, 0x34, 0x74, 0x42, 0xD3, 0xF7, 0x94 - }, - { - 0xEB, 0xAB, 0xC4, 0x96, 0x36, 0xBD, 0x43, 0x3D, - 0x2E, 0xC8, 0xF0, 0xE5, 0x18, 0x73, 0x2E, 0xF8, - 0xFA, 0x21, 0xD4, 0xD0, 0x71, 0xCC, 0x3B, 0xC4, - 0x6C, 0xD7, 0x9F, 0xA3, 0x8A, 0x28, 0xB8, 0x10 - }, - { - 0xA1, 0xD0, 0x34, 0x35, 0x23, 0xB8, 0x93, 0xFC, - 0xA8, 0x4F, 0x47, 0xFE, 0xB4, 0xA6, 0x4D, 0x35, - 0x0A, 0x17, 0xD8, 0xEE, 0xF5, 0x49, 0x7E, 0xCE, - 0x69, 0x7D, 0x02, 0xD7, 0x91, 0x78, 0xB5, 0x91 - }, - { - 0x26, 0x2E, 0xBF, 0xD9, 0x13, 0x0B, 0x7D, 0x28, - 0x76, 0x0D, 0x08, 0xEF, 0x8B, 0xFD, 0x3B, 0x86, - 0xCD, 0xD3, 0xB2, 0x11, 0x3D, 0x2C, 0xAE, 0xF7, - 0xEA, 0x95, 0x1A, 0x30, 0x3D, 0xFA, 0x38, 0x46 - }, - { - 0xF7, 0x61, 0x58, 0xED, 0xD5, 0x0A, 0x15, 0x4F, - 0xA7, 0x82, 0x03, 0xED, 0x23, 0x62, 0x93, 0x2F, - 0xCB, 0x82, 0x53, 0xAA, 0xE3, 0x78, 0x90, 0x3E, - 0xDE, 0xD1, 0xE0, 0x3F, 0x70, 0x21, 0xA2, 0x57 - }, - { - 0x26, 0x17, 0x8E, 0x95, 0x0A, 0xC7, 0x22, 0xF6, - 0x7A, 0xE5, 0x6E, 0x57, 0x1B, 0x28, 0x4C, 0x02, - 0x07, 0x68, 0x4A, 0x63, 0x34, 0xA1, 0x77, 0x48, - 0xA9, 0x4D, 0x26, 0x0B, 0xC5, 0xF5, 0x52, 0x74 - }, - { - 0xC3, 0x78, 0xD1, 0xE4, 0x93, 0xB4, 0x0E, 0xF1, - 0x1F, 0xE6, 0xA1, 0x5D, 0x9C, 0x27, 0x37, 0xA3, - 0x78, 0x09, 0x63, 0x4C, 0x5A, 0xBA, 0xD5, 0xB3, - 0x3D, 0x7E, 0x39, 0x3B, 0x4A, 0xE0, 0x5D, 0x03 - }, - { - 0x98, 0x4B, 0xD8, 0x37, 0x91, 0x01, 0xBE, 0x8F, - 0xD8, 0x06, 0x12, 0xD8, 0xEA, 0x29, 0x59, 0xA7, - 0x86, 0x5E, 0xC9, 0x71, 0x85, 0x23, 0x55, 0x01, - 0x07, 0xAE, 0x39, 0x38, 0xDF, 0x32, 0x01, 0x1B - }, - { - 0xC6, 0xF2, 0x5A, 0x81, 0x2A, 0x14, 0x48, 0x58, - 0xAC, 0x5C, 0xED, 0x37, 0xA9, 0x3A, 0x9F, 0x47, - 0x59, 0xBA, 0x0B, 0x1C, 0x0F, 0xDC, 0x43, 0x1D, - 0xCE, 0x35, 0xF9, 0xEC, 0x1F, 0x1F, 0x4A, 0x99 - }, - { - 0x92, 0x4C, 0x75, 0xC9, 0x44, 0x24, 0xFF, 0x75, - 0xE7, 0x4B, 0x8B, 0x4E, 0x94, 0x35, 0x89, 0x58, - 0xB0, 0x27, 0xB1, 0x71, 0xDF, 0x5E, 0x57, 0x89, - 0x9A, 0xD0, 0xD4, 0xDA, 0xC3, 0x73, 0x53, 0xB6 - }, - { - 0x0A, 0xF3, 0x58, 0x92, 0xA6, 0x3F, 0x45, 0x93, - 0x1F, 0x68, 0x46, 0xED, 0x19, 0x03, 0x61, 0xCD, - 0x07, 0x30, 0x89, 0xE0, 0x77, 0x16, 0x57, 0x14, - 0xB5, 0x0B, 0x81, 0xA2, 0xE3, 0xDD, 0x9B, 0xA1 - }, - { - 0xCC, 0x80, 0xCE, 0xFB, 0x26, 0xC3, 0xB2, 0xB0, - 0xDA, 0xEF, 0x23, 0x3E, 0x60, 0x6D, 0x5F, 0xFC, - 0x80, 0xFA, 0x17, 0x42, 0x7D, 0x18, 0xE3, 0x04, - 0x89, 0x67, 0x3E, 0x06, 0xEF, 0x4B, 0x87, 0xF7 - }, - { - 0xC2, 0xF8, 0xC8, 0x11, 0x74, 0x47, 0xF3, 0x97, - 0x8B, 0x08, 0x18, 0xDC, 0xF6, 0xF7, 0x01, 0x16, - 0xAC, 0x56, 0xFD, 0x18, 0x4D, 0xD1, 0x27, 0x84, - 0x94, 0xE1, 0x03, 0xFC, 0x6D, 0x74, 0xA8, 0x87 - }, - { - 0xBD, 0xEC, 0xF6, 0xBF, 0xC1, 0xBA, 0x0D, 0xF6, - 0xE8, 0x62, 0xC8, 0x31, 0x99, 0x22, 0x07, 0x79, - 0x6A, 0xCC, 0x79, 0x79, 0x68, 0x35, 0x88, 0x28, - 0xC0, 0x6E, 0x7A, 0x51, 0xE0, 0x90, 0x09, 0x8F - }, - { - 0x24, 0xD1, 0xA2, 0x6E, 0x3D, 0xAB, 0x02, 0xFE, - 0x45, 0x72, 0xD2, 0xAA, 0x7D, 0xBD, 0x3E, 0xC3, - 0x0F, 0x06, 0x93, 0xDB, 0x26, 0xF2, 0x73, 0xD0, - 0xAB, 0x2C, 0xB0, 0xC1, 0x3B, 0x5E, 0x64, 0x51 - }, - { - 0xEC, 0x56, 0xF5, 0x8B, 0x09, 0x29, 0x9A, 0x30, - 0x0B, 0x14, 0x05, 0x65, 0xD7, 0xD3, 0xE6, 0x87, - 0x82, 0xB6, 0xE2, 0xFB, 0xEB, 0x4B, 0x7E, 0xA9, - 0x7A, 0xC0, 0x57, 0x98, 0x90, 0x61, 0xDD, 0x3F - }, - { - 0x11, 0xA4, 0x37, 0xC1, 0xAB, 0xA3, 0xC1, 0x19, - 0xDD, 0xFA, 0xB3, 0x1B, 0x3E, 0x8C, 0x84, 0x1D, - 0xEE, 0xEB, 0x91, 0x3E, 0xF5, 0x7F, 0x7E, 0x48, - 0xF2, 0xC9, 0xCF, 0x5A, 0x28, 0xFA, 0x42, 0xBC - }, - { - 0x53, 0xC7, 0xE6, 0x11, 0x4B, 0x85, 0x0A, 0x2C, - 0xB4, 0x96, 0xC9, 0xB3, 0xC6, 0x9A, 0x62, 0x3E, - 0xAE, 0xA2, 0xCB, 0x1D, 0x33, 0xDD, 0x81, 0x7E, - 0x47, 0x65, 0xED, 0xAA, 0x68, 0x23, 0xC2, 0x28 - }, - { - 0x15, 0x4C, 0x3E, 0x96, 0xFE, 0xE5, 0xDB, 0x14, - 0xF8, 0x77, 0x3E, 0x18, 0xAF, 0x14, 0x85, 0x79, - 0x13, 0x50, 0x9D, 0xA9, 0x99, 0xB4, 0x6C, 0xDD, - 0x3D, 0x4C, 0x16, 0x97, 0x60, 0xC8, 0x3A, 0xD2 - }, - { - 0x40, 0xB9, 0x91, 0x6F, 0x09, 0x3E, 0x02, 0x7A, - 0x87, 0x86, 0x64, 0x18, 0x18, 0x92, 0x06, 0x20, - 0x47, 0x2F, 0xBC, 0xF6, 0x8F, 0x70, 0x1D, 0x1B, - 0x68, 0x06, 0x32, 0xE6, 0x99, 0x6B, 0xDE, 0xD3 - }, - { - 0x24, 0xC4, 0xCB, 0xBA, 0x07, 0x11, 0x98, 0x31, - 0xA7, 0x26, 0xB0, 0x53, 0x05, 0xD9, 0x6D, 0xA0, - 0x2F, 0xF8, 0xB1, 0x48, 0xF0, 0xDA, 0x44, 0x0F, - 0xE2, 0x33, 0xBC, 0xAA, 0x32, 0xC7, 0x2F, 0x6F - }, - { - 0x5D, 0x20, 0x15, 0x10, 0x25, 0x00, 0x20, 0xB7, - 0x83, 0x68, 0x96, 0x88, 0xAB, 0xBF, 0x8E, 0xCF, - 0x25, 0x94, 0xA9, 0x6A, 0x08, 0xF2, 0xBF, 0xEC, - 0x6C, 0xE0, 0x57, 0x44, 0x65, 0xDD, 0xED, 0x71 - }, - { - 0x04, 0x3B, 0x97, 0xE3, 0x36, 0xEE, 0x6F, 0xDB, - 0xBE, 0x2B, 0x50, 0xF2, 0x2A, 0xF8, 0x32, 0x75, - 0xA4, 0x08, 0x48, 0x05, 0xD2, 0xD5, 0x64, 0x59, - 0x62, 0x45, 0x4B, 0x6C, 0x9B, 0x80, 0x53, 0xA0 - }, - { - 0x56, 0x48, 0x35, 0xCB, 0xAE, 0xA7, 0x74, 0x94, - 0x85, 0x68, 0xBE, 0x36, 0xCF, 0x52, 0xFC, 0xDD, - 0x83, 0x93, 0x4E, 0xB0, 0xA2, 0x75, 0x12, 0xDB, - 0xE3, 0xE2, 0xDB, 0x47, 0xB9, 0xE6, 0x63, 0x5A - }, - { - 0xF2, 0x1C, 0x33, 0xF4, 0x7B, 0xDE, 0x40, 0xA2, - 0xA1, 0x01, 0xC9, 0xCD, 0xE8, 0x02, 0x7A, 0xAF, - 0x61, 0xA3, 0x13, 0x7D, 0xE2, 0x42, 0x2B, 0x30, - 0x03, 0x5A, 0x04, 0xC2, 0x70, 0x89, 0x41, 0x83 - }, - { - 0x9D, 0xB0, 0xEF, 0x74, 0xE6, 0x6C, 0xBB, 0x84, - 0x2E, 0xB0, 0xE0, 0x73, 0x43, 0xA0, 0x3C, 0x5C, - 0x56, 0x7E, 0x37, 0x2B, 0x3F, 0x23, 0xB9, 0x43, - 0xC7, 0x88, 0xA4, 0xF2, 0x50, 0xF6, 0x78, 0x91 - }, - { - 0xAB, 0x8D, 0x08, 0x65, 0x5F, 0xF1, 0xD3, 0xFE, - 0x87, 0x58, 0xD5, 0x62, 0x23, 0x5F, 0xD2, 0x3E, - 0x7C, 0xF9, 0xDC, 0xAA, 0xD6, 0x58, 0x87, 0x2A, - 0x49, 0xE5, 0xD3, 0x18, 0x3B, 0x6C, 0xCE, 0xBD - }, - { - 0x6F, 0x27, 0xF7, 0x7E, 0x7B, 0xCF, 0x46, 0xA1, - 0xE9, 0x63, 0xAD, 0xE0, 0x30, 0x97, 0x33, 0x54, - 0x30, 0x31, 0xDC, 0xCD, 0xD4, 0x7C, 0xAA, 0xC1, - 0x74, 0xD7, 0xD2, 0x7C, 0xE8, 0x07, 0x7E, 0x8B - }, - { - 0xE3, 0xCD, 0x54, 0xDA, 0x7E, 0x44, 0x4C, 0xAA, - 0x62, 0x07, 0x56, 0x95, 0x25, 0xA6, 0x70, 0xEB, - 0xAE, 0x12, 0x78, 0xDE, 0x4E, 0x3F, 0xE2, 0x68, - 0x4B, 0x3E, 0x33, 0xF5, 0xEF, 0x90, 0xCC, 0x1B - }, - { - 0xB2, 0xC3, 0xE3, 0x3A, 0x51, 0xD2, 0x2C, 0x4C, - 0x08, 0xFC, 0x09, 0x89, 0xC8, 0x73, 0xC9, 0xCC, - 0x41, 0x50, 0x57, 0x9B, 0x1E, 0x61, 0x63, 0xFA, - 0x69, 0x4A, 0xD5, 0x1D, 0x53, 0xD7, 0x12, 0xDC - }, - { - 0xBE, 0x7F, 0xDA, 0x98, 0x3E, 0x13, 0x18, 0x9B, - 0x4C, 0x77, 0xE0, 0xA8, 0x09, 0x20, 0xB6, 0xE0, - 0xE0, 0xEA, 0x80, 0xC3, 0xB8, 0x4D, 0xBE, 0x7E, - 0x71, 0x17, 0xD2, 0x53, 0xF4, 0x81, 0x12, 0xF4 - }, - { - 0xB6, 0x00, 0x8C, 0x28, 0xFA, 0xE0, 0x8A, 0xA4, - 0x27, 0xE5, 0xBD, 0x3A, 0xAD, 0x36, 0xF1, 0x00, - 0x21, 0xF1, 0x6C, 0x77, 0xCF, 0xEA, 0xBE, 0xD0, - 0x7F, 0x97, 0xCC, 0x7D, 0xC1, 0xF1, 0x28, 0x4A - }, - { - 0x6E, 0x4E, 0x67, 0x60, 0xC5, 0x38, 0xF2, 0xE9, - 0x7B, 0x3A, 0xDB, 0xFB, 0xBC, 0xDE, 0x57, 0xF8, - 0x96, 0x6B, 0x7E, 0xA8, 0xFC, 0xB5, 0xBF, 0x7E, - 0xFE, 0xC9, 0x13, 0xFD, 0x2A, 0x2B, 0x0C, 0x55 - }, - { - 0x4A, 0xE5, 0x1F, 0xD1, 0x83, 0x4A, 0xA5, 0xBD, - 0x9A, 0x6F, 0x7E, 0xC3, 0x9F, 0xC6, 0x63, 0x33, - 0x8D, 0xC5, 0xD2, 0xE2, 0x07, 0x61, 0x56, 0x6D, - 0x90, 0xCC, 0x68, 0xB1, 0xCB, 0x87, 0x5E, 0xD8 - }, - { - 0xB6, 0x73, 0xAA, 0xD7, 0x5A, 0xB1, 0xFD, 0xB5, - 0x40, 0x1A, 0xBF, 0xA1, 0xBF, 0x89, 0xF3, 0xAD, - 0xD2, 0xEB, 0xC4, 0x68, 0xDF, 0x36, 0x24, 0xA4, - 0x78, 0xF4, 0xFE, 0x85, 0x9D, 0x8D, 0x55, 0xE2 - }, - { - 0x13, 0xC9, 0x47, 0x1A, 0x98, 0x55, 0x91, 0x35, - 0x39, 0x83, 0x66, 0x60, 0x39, 0x8D, 0xA0, 0xF3, - 0xF9, 0x9A, 0xDA, 0x08, 0x47, 0x9C, 0x69, 0xD1, - 0xB7, 0xFC, 0xAA, 0x34, 0x61, 0xDD, 0x7E, 0x59 - }, - { - 0x2C, 0x11, 0xF4, 0xA7, 0xF9, 0x9A, 0x1D, 0x23, - 0xA5, 0x8B, 0xB6, 0x36, 0x35, 0x0F, 0xE8, 0x49, - 0xF2, 0x9C, 0xBA, 0xC1, 0xB2, 0xA1, 0x11, 0x2D, - 0x9F, 0x1E, 0xD5, 0xBC, 0x5B, 0x31, 0x3C, 0xCD - }, - { - 0xC7, 0xD3, 0xC0, 0x70, 0x6B, 0x11, 0xAE, 0x74, - 0x1C, 0x05, 0xA1, 0xEF, 0x15, 0x0D, 0xD6, 0x5B, - 0x54, 0x94, 0xD6, 0xD5, 0x4C, 0x9A, 0x86, 0xE2, - 0x61, 0x78, 0x54, 0xE6, 0xAE, 0xEE, 0xBB, 0xD9 - }, - { - 0x19, 0x4E, 0x10, 0xC9, 0x38, 0x93, 0xAF, 0xA0, - 0x64, 0xC3, 0xAC, 0x04, 0xC0, 0xDD, 0x80, 0x8D, - 0x79, 0x1C, 0x3D, 0x4B, 0x75, 0x56, 0xE8, 0x9D, - 0x8D, 0x9C, 0xB2, 0x25, 0xC4, 0xB3, 0x33, 0x39 - }, - { - 0x6F, 0xC4, 0x98, 0x8B, 0x8F, 0x78, 0x54, 0x6B, - 0x16, 0x88, 0x99, 0x18, 0x45, 0x90, 0x8F, 0x13, - 0x4B, 0x6A, 0x48, 0x2E, 0x69, 0x94, 0xB3, 0xD4, - 0x83, 0x17, 0xBF, 0x08, 0xDB, 0x29, 0x21, 0x85 - }, - { - 0x56, 0x65, 0xBE, 0xB8, 0xB0, 0x95, 0x55, 0x25, - 0x81, 0x3B, 0x59, 0x81, 0xCD, 0x14, 0x2E, 0xD4, - 0xD0, 0x3F, 0xBA, 0x38, 0xA6, 0xF3, 0xE5, 0xAD, - 0x26, 0x8E, 0x0C, 0xC2, 0x70, 0xD1, 0xCD, 0x11 - }, - { - 0xB8, 0x83, 0xD6, 0x8F, 0x5F, 0xE5, 0x19, 0x36, - 0x43, 0x1B, 0xA4, 0x25, 0x67, 0x38, 0x05, 0x3B, - 0x1D, 0x04, 0x26, 0xD4, 0xCB, 0x64, 0xB1, 0x6E, - 0x83, 0xBA, 0xDC, 0x5E, 0x9F, 0xBE, 0x3B, 0x81 - }, - { - 0x53, 0xE7, 0xB2, 0x7E, 0xA5, 0x9C, 0x2F, 0x6D, - 0xBB, 0x50, 0x76, 0x9E, 0x43, 0x55, 0x4D, 0xF3, - 0x5A, 0xF8, 0x9F, 0x48, 0x22, 0xD0, 0x46, 0x6B, - 0x00, 0x7D, 0xD6, 0xF6, 0xDE, 0xAF, 0xFF, 0x02 - }, - { - 0x1F, 0x1A, 0x02, 0x29, 0xD4, 0x64, 0x0F, 0x01, - 0x90, 0x15, 0x88, 0xD9, 0xDE, 0xC2, 0x2D, 0x13, - 0xFC, 0x3E, 0xB3, 0x4A, 0x61, 0xB3, 0x29, 0x38, - 0xEF, 0xBF, 0x53, 0x34, 0xB2, 0x80, 0x0A, 0xFA - }, - { - 0xC2, 0xB4, 0x05, 0xAF, 0xA0, 0xFA, 0x66, 0x68, - 0x85, 0x2A, 0xEE, 0x4D, 0x88, 0x04, 0x08, 0x53, - 0xFA, 0xB8, 0x00, 0xE7, 0x2B, 0x57, 0x58, 0x14, - 0x18, 0xE5, 0x50, 0x6F, 0x21, 0x4C, 0x7D, 0x1F - }, - { - 0xC0, 0x8A, 0xA1, 0xC2, 0x86, 0xD7, 0x09, 0xFD, - 0xC7, 0x47, 0x37, 0x44, 0x97, 0x71, 0x88, 0xC8, - 0x95, 0xBA, 0x01, 0x10, 0x14, 0x24, 0x7E, 0x4E, - 0xFA, 0x8D, 0x07, 0xE7, 0x8F, 0xEC, 0x69, 0x5C - }, - { - 0xF0, 0x3F, 0x57, 0x89, 0xD3, 0x33, 0x6B, 0x80, - 0xD0, 0x02, 0xD5, 0x9F, 0xDF, 0x91, 0x8B, 0xDB, - 0x77, 0x5B, 0x00, 0x95, 0x6E, 0xD5, 0x52, 0x8E, - 0x86, 0xAA, 0x99, 0x4A, 0xCB, 0x38, 0xFE, 0x2D - }, -}; - - - - -static const uint8_t blake2s_keyed_kat[KAT_LENGTH][BLAKE2S_OUTBYTES] = -{ - { - 0x48, 0xA8, 0x99, 0x7D, 0xA4, 0x07, 0x87, 0x6B, - 0x3D, 0x79, 0xC0, 0xD9, 0x23, 0x25, 0xAD, 0x3B, - 0x89, 0xCB, 0xB7, 0x54, 0xD8, 0x6A, 0xB7, 0x1A, - 0xEE, 0x04, 0x7A, 0xD3, 0x45, 0xFD, 0x2C, 0x49 - }, - { - 0x40, 0xD1, 0x5F, 0xEE, 0x7C, 0x32, 0x88, 0x30, - 0x16, 0x6A, 0xC3, 0xF9, 0x18, 0x65, 0x0F, 0x80, - 0x7E, 0x7E, 0x01, 0xE1, 0x77, 0x25, 0x8C, 0xDC, - 0x0A, 0x39, 0xB1, 0x1F, 0x59, 0x80, 0x66, 0xF1 - }, - { - 0x6B, 0xB7, 0x13, 0x00, 0x64, 0x4C, 0xD3, 0x99, - 0x1B, 0x26, 0xCC, 0xD4, 0xD2, 0x74, 0xAC, 0xD1, - 0xAD, 0xEA, 0xB8, 0xB1, 0xD7, 0x91, 0x45, 0x46, - 0xC1, 0x19, 0x8B, 0xBE, 0x9F, 0xC9, 0xD8, 0x03 - }, - { - 0x1D, 0x22, 0x0D, 0xBE, 0x2E, 0xE1, 0x34, 0x66, - 0x1F, 0xDF, 0x6D, 0x9E, 0x74, 0xB4, 0x17, 0x04, - 0x71, 0x05, 0x56, 0xF2, 0xF6, 0xE5, 0xA0, 0x91, - 0xB2, 0x27, 0x69, 0x74, 0x45, 0xDB, 0xEA, 0x6B - }, - { - 0xF6, 0xC3, 0xFB, 0xAD, 0xB4, 0xCC, 0x68, 0x7A, - 0x00, 0x64, 0xA5, 0xBE, 0x6E, 0x79, 0x1B, 0xEC, - 0x63, 0xB8, 0x68, 0xAD, 0x62, 0xFB, 0xA6, 0x1B, - 0x37, 0x57, 0xEF, 0x9C, 0xA5, 0x2E, 0x05, 0xB2 - }, - { - 0x49, 0xC1, 0xF2, 0x11, 0x88, 0xDF, 0xD7, 0x69, - 0xAE, 0xA0, 0xE9, 0x11, 0xDD, 0x6B, 0x41, 0xF1, - 0x4D, 0xAB, 0x10, 0x9D, 0x2B, 0x85, 0x97, 0x7A, - 0xA3, 0x08, 0x8B, 0x5C, 0x70, 0x7E, 0x85, 0x98 - }, - { - 0xFD, 0xD8, 0x99, 0x3D, 0xCD, 0x43, 0xF6, 0x96, - 0xD4, 0x4F, 0x3C, 0xEA, 0x0F, 0xF3, 0x53, 0x45, - 0x23, 0x4E, 0xC8, 0xEE, 0x08, 0x3E, 0xB3, 0xCA, - 0xDA, 0x01, 0x7C, 0x7F, 0x78, 0xC1, 0x71, 0x43 - }, - { - 0xE6, 0xC8, 0x12, 0x56, 0x37, 0x43, 0x8D, 0x09, - 0x05, 0xB7, 0x49, 0xF4, 0x65, 0x60, 0xAC, 0x89, - 0xFD, 0x47, 0x1C, 0xF8, 0x69, 0x2E, 0x28, 0xFA, - 0xB9, 0x82, 0xF7, 0x3F, 0x01, 0x9B, 0x83, 0xA9 - }, - { - 0x19, 0xFC, 0x8C, 0xA6, 0x97, 0x9D, 0x60, 0xE6, - 0xED, 0xD3, 0xB4, 0x54, 0x1E, 0x2F, 0x96, 0x7C, - 0xED, 0x74, 0x0D, 0xF6, 0xEC, 0x1E, 0xAE, 0xBB, - 0xFE, 0x81, 0x38, 0x32, 0xE9, 0x6B, 0x29, 0x74 - }, - { - 0xA6, 0xAD, 0x77, 0x7C, 0xE8, 0x81, 0xB5, 0x2B, - 0xB5, 0xA4, 0x42, 0x1A, 0xB6, 0xCD, 0xD2, 0xDF, - 0xBA, 0x13, 0xE9, 0x63, 0x65, 0x2D, 0x4D, 0x6D, - 0x12, 0x2A, 0xEE, 0x46, 0x54, 0x8C, 0x14, 0xA7 - }, - { - 0xF5, 0xC4, 0xB2, 0xBA, 0x1A, 0x00, 0x78, 0x1B, - 0x13, 0xAB, 0xA0, 0x42, 0x52, 0x42, 0xC6, 0x9C, - 0xB1, 0x55, 0x2F, 0x3F, 0x71, 0xA9, 0xA3, 0xBB, - 0x22, 0xB4, 0xA6, 0xB4, 0x27, 0x7B, 0x46, 0xDD - }, - { - 0xE3, 0x3C, 0x4C, 0x9B, 0xD0, 0xCC, 0x7E, 0x45, - 0xC8, 0x0E, 0x65, 0xC7, 0x7F, 0xA5, 0x99, 0x7F, - 0xEC, 0x70, 0x02, 0x73, 0x85, 0x41, 0x50, 0x9E, - 0x68, 0xA9, 0x42, 0x38, 0x91, 0xE8, 0x22, 0xA3 - }, - { - 0xFB, 0xA1, 0x61, 0x69, 0xB2, 0xC3, 0xEE, 0x10, - 0x5B, 0xE6, 0xE1, 0xE6, 0x50, 0xE5, 0xCB, 0xF4, - 0x07, 0x46, 0xB6, 0x75, 0x3D, 0x03, 0x6A, 0xB5, - 0x51, 0x79, 0x01, 0x4A, 0xD7, 0xEF, 0x66, 0x51 - }, - { - 0xF5, 0xC4, 0xBE, 0xC6, 0xD6, 0x2F, 0xC6, 0x08, - 0xBF, 0x41, 0xCC, 0x11, 0x5F, 0x16, 0xD6, 0x1C, - 0x7E, 0xFD, 0x3F, 0xF6, 0xC6, 0x56, 0x92, 0xBB, - 0xE0, 0xAF, 0xFF, 0xB1, 0xFE, 0xDE, 0x74, 0x75 - }, - { - 0xA4, 0x86, 0x2E, 0x76, 0xDB, 0x84, 0x7F, 0x05, - 0xBA, 0x17, 0xED, 0xE5, 0xDA, 0x4E, 0x7F, 0x91, - 0xB5, 0x92, 0x5C, 0xF1, 0xAD, 0x4B, 0xA1, 0x27, - 0x32, 0xC3, 0x99, 0x57, 0x42, 0xA5, 0xCD, 0x6E - }, - { - 0x65, 0xF4, 0xB8, 0x60, 0xCD, 0x15, 0xB3, 0x8E, - 0xF8, 0x14, 0xA1, 0xA8, 0x04, 0x31, 0x4A, 0x55, - 0xBE, 0x95, 0x3C, 0xAA, 0x65, 0xFD, 0x75, 0x8A, - 0xD9, 0x89, 0xFF, 0x34, 0xA4, 0x1C, 0x1E, 0xEA - }, - { - 0x19, 0xBA, 0x23, 0x4F, 0x0A, 0x4F, 0x38, 0x63, - 0x7D, 0x18, 0x39, 0xF9, 0xD9, 0xF7, 0x6A, 0xD9, - 0x1C, 0x85, 0x22, 0x30, 0x71, 0x43, 0xC9, 0x7D, - 0x5F, 0x93, 0xF6, 0x92, 0x74, 0xCE, 0xC9, 0xA7 - }, - { - 0x1A, 0x67, 0x18, 0x6C, 0xA4, 0xA5, 0xCB, 0x8E, - 0x65, 0xFC, 0xA0, 0xE2, 0xEC, 0xBC, 0x5D, 0xDC, - 0x14, 0xAE, 0x38, 0x1B, 0xB8, 0xBF, 0xFE, 0xB9, - 0xE0, 0xA1, 0x03, 0x44, 0x9E, 0x3E, 0xF0, 0x3C - }, - { - 0xAF, 0xBE, 0xA3, 0x17, 0xB5, 0xA2, 0xE8, 0x9C, - 0x0B, 0xD9, 0x0C, 0xCF, 0x5D, 0x7F, 0xD0, 0xED, - 0x57, 0xFE, 0x58, 0x5E, 0x4B, 0xE3, 0x27, 0x1B, - 0x0A, 0x6B, 0xF0, 0xF5, 0x78, 0x6B, 0x0F, 0x26 - }, - { - 0xF1, 0xB0, 0x15, 0x58, 0xCE, 0x54, 0x12, 0x62, - 0xF5, 0xEC, 0x34, 0x29, 0x9D, 0x6F, 0xB4, 0x09, - 0x00, 0x09, 0xE3, 0x43, 0x4B, 0xE2, 0xF4, 0x91, - 0x05, 0xCF, 0x46, 0xAF, 0x4D, 0x2D, 0x41, 0x24 - }, - { - 0x13, 0xA0, 0xA0, 0xC8, 0x63, 0x35, 0x63, 0x5E, - 0xAA, 0x74, 0xCA, 0x2D, 0x5D, 0x48, 0x8C, 0x79, - 0x7B, 0xBB, 0x4F, 0x47, 0xDC, 0x07, 0x10, 0x50, - 0x15, 0xED, 0x6A, 0x1F, 0x33, 0x09, 0xEF, 0xCE - }, - { - 0x15, 0x80, 0xAF, 0xEE, 0xBE, 0xBB, 0x34, 0x6F, - 0x94, 0xD5, 0x9F, 0xE6, 0x2D, 0xA0, 0xB7, 0x92, - 0x37, 0xEA, 0xD7, 0xB1, 0x49, 0x1F, 0x56, 0x67, - 0xA9, 0x0E, 0x45, 0xED, 0xF6, 0xCA, 0x8B, 0x03 - }, - { - 0x20, 0xBE, 0x1A, 0x87, 0x5B, 0x38, 0xC5, 0x73, - 0xDD, 0x7F, 0xAA, 0xA0, 0xDE, 0x48, 0x9D, 0x65, - 0x5C, 0x11, 0xEF, 0xB6, 0xA5, 0x52, 0x69, 0x8E, - 0x07, 0xA2, 0xD3, 0x31, 0xB5, 0xF6, 0x55, 0xC3 - }, - { - 0xBE, 0x1F, 0xE3, 0xC4, 0xC0, 0x40, 0x18, 0xC5, - 0x4C, 0x4A, 0x0F, 0x6B, 0x9A, 0x2E, 0xD3, 0xC5, - 0x3A, 0xBE, 0x3A, 0x9F, 0x76, 0xB4, 0xD2, 0x6D, - 0xE5, 0x6F, 0xC9, 0xAE, 0x95, 0x05, 0x9A, 0x99 - }, - { - 0xE3, 0xE3, 0xAC, 0xE5, 0x37, 0xEB, 0x3E, 0xDD, - 0x84, 0x63, 0xD9, 0xAD, 0x35, 0x82, 0xE1, 0x3C, - 0xF8, 0x65, 0x33, 0xFF, 0xDE, 0x43, 0xD6, 0x68, - 0xDD, 0x2E, 0x93, 0xBB, 0xDB, 0xD7, 0x19, 0x5A - }, - { - 0x11, 0x0C, 0x50, 0xC0, 0xBF, 0x2C, 0x6E, 0x7A, - 0xEB, 0x7E, 0x43, 0x5D, 0x92, 0xD1, 0x32, 0xAB, - 0x66, 0x55, 0x16, 0x8E, 0x78, 0xA2, 0xDE, 0xCD, - 0xEC, 0x33, 0x30, 0x77, 0x76, 0x84, 0xD9, 0xC1 - }, - { - 0xE9, 0xBA, 0x8F, 0x50, 0x5C, 0x9C, 0x80, 0xC0, - 0x86, 0x66, 0xA7, 0x01, 0xF3, 0x36, 0x7E, 0x6C, - 0xC6, 0x65, 0xF3, 0x4B, 0x22, 0xE7, 0x3C, 0x3C, - 0x04, 0x17, 0xEB, 0x1C, 0x22, 0x06, 0x08, 0x2F - }, - { - 0x26, 0xCD, 0x66, 0xFC, 0xA0, 0x23, 0x79, 0xC7, - 0x6D, 0xF1, 0x23, 0x17, 0x05, 0x2B, 0xCA, 0xFD, - 0x6C, 0xD8, 0xC3, 0xA7, 0xB8, 0x90, 0xD8, 0x05, - 0xF3, 0x6C, 0x49, 0x98, 0x97, 0x82, 0x43, 0x3A - }, - { - 0x21, 0x3F, 0x35, 0x96, 0xD6, 0xE3, 0xA5, 0xD0, - 0xE9, 0x93, 0x2C, 0xD2, 0x15, 0x91, 0x46, 0x01, - 0x5E, 0x2A, 0xBC, 0x94, 0x9F, 0x47, 0x29, 0xEE, - 0x26, 0x32, 0xFE, 0x1E, 0xDB, 0x78, 0xD3, 0x37 - }, - { - 0x10, 0x15, 0xD7, 0x01, 0x08, 0xE0, 0x3B, 0xE1, - 0xC7, 0x02, 0xFE, 0x97, 0x25, 0x36, 0x07, 0xD1, - 0x4A, 0xEE, 0x59, 0x1F, 0x24, 0x13, 0xEA, 0x67, - 0x87, 0x42, 0x7B, 0x64, 0x59, 0xFF, 0x21, 0x9A - }, - { - 0x3C, 0xA9, 0x89, 0xDE, 0x10, 0xCF, 0xE6, 0x09, - 0x90, 0x94, 0x72, 0xC8, 0xD3, 0x56, 0x10, 0x80, - 0x5B, 0x2F, 0x97, 0x77, 0x34, 0xCF, 0x65, 0x2C, - 0xC6, 0x4B, 0x3B, 0xFC, 0x88, 0x2D, 0x5D, 0x89 - }, - { - 0xB6, 0x15, 0x6F, 0x72, 0xD3, 0x80, 0xEE, 0x9E, - 0xA6, 0xAC, 0xD1, 0x90, 0x46, 0x4F, 0x23, 0x07, - 0xA5, 0xC1, 0x79, 0xEF, 0x01, 0xFD, 0x71, 0xF9, - 0x9F, 0x2D, 0x0F, 0x7A, 0x57, 0x36, 0x0A, 0xEA - }, - { - 0xC0, 0x3B, 0xC6, 0x42, 0xB2, 0x09, 0x59, 0xCB, - 0xE1, 0x33, 0xA0, 0x30, 0x3E, 0x0C, 0x1A, 0xBF, - 0xF3, 0xE3, 0x1E, 0xC8, 0xE1, 0xA3, 0x28, 0xEC, - 0x85, 0x65, 0xC3, 0x6D, 0xEC, 0xFF, 0x52, 0x65 - }, - { - 0x2C, 0x3E, 0x08, 0x17, 0x6F, 0x76, 0x0C, 0x62, - 0x64, 0xC3, 0xA2, 0xCD, 0x66, 0xFE, 0xC6, 0xC3, - 0xD7, 0x8D, 0xE4, 0x3F, 0xC1, 0x92, 0x45, 0x7B, - 0x2A, 0x4A, 0x66, 0x0A, 0x1E, 0x0E, 0xB2, 0x2B - }, - { - 0xF7, 0x38, 0xC0, 0x2F, 0x3C, 0x1B, 0x19, 0x0C, - 0x51, 0x2B, 0x1A, 0x32, 0xDE, 0xAB, 0xF3, 0x53, - 0x72, 0x8E, 0x0E, 0x9A, 0xB0, 0x34, 0x49, 0x0E, - 0x3C, 0x34, 0x09, 0x94, 0x6A, 0x97, 0xAE, 0xEC - }, - { - 0x8B, 0x18, 0x80, 0xDF, 0x30, 0x1C, 0xC9, 0x63, - 0x41, 0x88, 0x11, 0x08, 0x89, 0x64, 0x83, 0x92, - 0x87, 0xFF, 0x7F, 0xE3, 0x1C, 0x49, 0xEA, 0x6E, - 0xBD, 0x9E, 0x48, 0xBD, 0xEE, 0xE4, 0x97, 0xC5 - }, - { - 0x1E, 0x75, 0xCB, 0x21, 0xC6, 0x09, 0x89, 0x02, - 0x03, 0x75, 0xF1, 0xA7, 0xA2, 0x42, 0x83, 0x9F, - 0x0B, 0x0B, 0x68, 0x97, 0x3A, 0x4C, 0x2A, 0x05, - 0xCF, 0x75, 0x55, 0xED, 0x5A, 0xAE, 0xC4, 0xC1 - }, - { - 0x62, 0xBF, 0x8A, 0x9C, 0x32, 0xA5, 0xBC, 0xCF, - 0x29, 0x0B, 0x6C, 0x47, 0x4D, 0x75, 0xB2, 0xA2, - 0xA4, 0x09, 0x3F, 0x1A, 0x9E, 0x27, 0x13, 0x94, - 0x33, 0xA8, 0xF2, 0xB3, 0xBC, 0xE7, 0xB8, 0xD7 - }, - { - 0x16, 0x6C, 0x83, 0x50, 0xD3, 0x17, 0x3B, 0x5E, - 0x70, 0x2B, 0x78, 0x3D, 0xFD, 0x33, 0xC6, 0x6E, - 0xE0, 0x43, 0x27, 0x42, 0xE9, 0xB9, 0x2B, 0x99, - 0x7F, 0xD2, 0x3C, 0x60, 0xDC, 0x67, 0x56, 0xCA - }, - { - 0x04, 0x4A, 0x14, 0xD8, 0x22, 0xA9, 0x0C, 0xAC, - 0xF2, 0xF5, 0xA1, 0x01, 0x42, 0x8A, 0xDC, 0x8F, - 0x41, 0x09, 0x38, 0x6C, 0xCB, 0x15, 0x8B, 0xF9, - 0x05, 0xC8, 0x61, 0x8B, 0x8E, 0xE2, 0x4E, 0xC3 - }, - { - 0x38, 0x7D, 0x39, 0x7E, 0xA4, 0x3A, 0x99, 0x4B, - 0xE8, 0x4D, 0x2D, 0x54, 0x4A, 0xFB, 0xE4, 0x81, - 0xA2, 0x00, 0x0F, 0x55, 0x25, 0x26, 0x96, 0xBB, - 0xA2, 0xC5, 0x0C, 0x8E, 0xBD, 0x10, 0x13, 0x47 - }, - { - 0x56, 0xF8, 0xCC, 0xF1, 0xF8, 0x64, 0x09, 0xB4, - 0x6C, 0xE3, 0x61, 0x66, 0xAE, 0x91, 0x65, 0x13, - 0x84, 0x41, 0x57, 0x75, 0x89, 0xDB, 0x08, 0xCB, - 0xC5, 0xF6, 0x6C, 0xA2, 0x97, 0x43, 0xB9, 0xFD - }, - { - 0x97, 0x06, 0xC0, 0x92, 0xB0, 0x4D, 0x91, 0xF5, - 0x3D, 0xFF, 0x91, 0xFA, 0x37, 0xB7, 0x49, 0x3D, - 0x28, 0xB5, 0x76, 0xB5, 0xD7, 0x10, 0x46, 0x9D, - 0xF7, 0x94, 0x01, 0x66, 0x22, 0x36, 0xFC, 0x03 - }, - { - 0x87, 0x79, 0x68, 0x68, 0x6C, 0x06, 0x8C, 0xE2, - 0xF7, 0xE2, 0xAD, 0xCF, 0xF6, 0x8B, 0xF8, 0x74, - 0x8E, 0xDF, 0x3C, 0xF8, 0x62, 0xCF, 0xB4, 0xD3, - 0x94, 0x7A, 0x31, 0x06, 0x95, 0x80, 0x54, 0xE3 - }, - { - 0x88, 0x17, 0xE5, 0x71, 0x98, 0x79, 0xAC, 0xF7, - 0x02, 0x47, 0x87, 0xEC, 0xCD, 0xB2, 0x71, 0x03, - 0x55, 0x66, 0xCF, 0xA3, 0x33, 0xE0, 0x49, 0x40, - 0x7C, 0x01, 0x78, 0xCC, 0xC5, 0x7A, 0x5B, 0x9F - }, - { - 0x89, 0x38, 0x24, 0x9E, 0x4B, 0x50, 0xCA, 0xDA, - 0xCC, 0xDF, 0x5B, 0x18, 0x62, 0x13, 0x26, 0xCB, - 0xB1, 0x52, 0x53, 0xE3, 0x3A, 0x20, 0xF5, 0x63, - 0x6E, 0x99, 0x5D, 0x72, 0x47, 0x8D, 0xE4, 0x72 - }, - { - 0xF1, 0x64, 0xAB, 0xBA, 0x49, 0x63, 0xA4, 0x4D, - 0x10, 0x72, 0x57, 0xE3, 0x23, 0x2D, 0x90, 0xAC, - 0xA5, 0xE6, 0x6A, 0x14, 0x08, 0x24, 0x8C, 0x51, - 0x74, 0x1E, 0x99, 0x1D, 0xB5, 0x22, 0x77, 0x56 - }, - { - 0xD0, 0x55, 0x63, 0xE2, 0xB1, 0xCB, 0xA0, 0xC4, - 0xA2, 0xA1, 0xE8, 0xBD, 0xE3, 0xA1, 0xA0, 0xD9, - 0xF5, 0xB4, 0x0C, 0x85, 0xA0, 0x70, 0xD6, 0xF5, - 0xFB, 0x21, 0x06, 0x6E, 0xAD, 0x5D, 0x06, 0x01 - }, - { - 0x03, 0xFB, 0xB1, 0x63, 0x84, 0xF0, 0xA3, 0x86, - 0x6F, 0x4C, 0x31, 0x17, 0x87, 0x76, 0x66, 0xEF, - 0xBF, 0x12, 0x45, 0x97, 0x56, 0x4B, 0x29, 0x3D, - 0x4A, 0xAB, 0x0D, 0x26, 0x9F, 0xAB, 0xDD, 0xFA - }, - { - 0x5F, 0xA8, 0x48, 0x6A, 0xC0, 0xE5, 0x29, 0x64, - 0xD1, 0x88, 0x1B, 0xBE, 0x33, 0x8E, 0xB5, 0x4B, - 0xE2, 0xF7, 0x19, 0x54, 0x92, 0x24, 0x89, 0x20, - 0x57, 0xB4, 0xDA, 0x04, 0xBA, 0x8B, 0x34, 0x75 - }, - { - 0xCD, 0xFA, 0xBC, 0xEE, 0x46, 0x91, 0x11, 0x11, - 0x23, 0x6A, 0x31, 0x70, 0x8B, 0x25, 0x39, 0xD7, - 0x1F, 0xC2, 0x11, 0xD9, 0xB0, 0x9C, 0x0D, 0x85, - 0x30, 0xA1, 0x1E, 0x1D, 0xBF, 0x6E, 0xED, 0x01 - }, - { - 0x4F, 0x82, 0xDE, 0x03, 0xB9, 0x50, 0x47, 0x93, - 0xB8, 0x2A, 0x07, 0xA0, 0xBD, 0xCD, 0xFF, 0x31, - 0x4D, 0x75, 0x9E, 0x7B, 0x62, 0xD2, 0x6B, 0x78, - 0x49, 0x46, 0xB0, 0xD3, 0x6F, 0x91, 0x6F, 0x52 - }, - { - 0x25, 0x9E, 0xC7, 0xF1, 0x73, 0xBC, 0xC7, 0x6A, - 0x09, 0x94, 0xC9, 0x67, 0xB4, 0xF5, 0xF0, 0x24, - 0xC5, 0x60, 0x57, 0xFB, 0x79, 0xC9, 0x65, 0xC4, - 0xFA, 0xE4, 0x18, 0x75, 0xF0, 0x6A, 0x0E, 0x4C - }, - { - 0x19, 0x3C, 0xC8, 0xE7, 0xC3, 0xE0, 0x8B, 0xB3, - 0x0F, 0x54, 0x37, 0xAA, 0x27, 0xAD, 0xE1, 0xF1, - 0x42, 0x36, 0x9B, 0x24, 0x6A, 0x67, 0x5B, 0x23, - 0x83, 0xE6, 0xDA, 0x9B, 0x49, 0xA9, 0x80, 0x9E - }, - { - 0x5C, 0x10, 0x89, 0x6F, 0x0E, 0x28, 0x56, 0xB2, - 0xA2, 0xEE, 0xE0, 0xFE, 0x4A, 0x2C, 0x16, 0x33, - 0x56, 0x5D, 0x18, 0xF0, 0xE9, 0x3E, 0x1F, 0xAB, - 0x26, 0xC3, 0x73, 0xE8, 0xF8, 0x29, 0x65, 0x4D - }, - { - 0xF1, 0x60, 0x12, 0xD9, 0x3F, 0x28, 0x85, 0x1A, - 0x1E, 0xB9, 0x89, 0xF5, 0xD0, 0xB4, 0x3F, 0x3F, - 0x39, 0xCA, 0x73, 0xC9, 0xA6, 0x2D, 0x51, 0x81, - 0xBF, 0xF2, 0x37, 0x53, 0x6B, 0xD3, 0x48, 0xC3 - }, - { - 0x29, 0x66, 0xB3, 0xCF, 0xAE, 0x1E, 0x44, 0xEA, - 0x99, 0x6D, 0xC5, 0xD6, 0x86, 0xCF, 0x25, 0xFA, - 0x05, 0x3F, 0xB6, 0xF6, 0x72, 0x01, 0xB9, 0xE4, - 0x6E, 0xAD, 0xE8, 0x5D, 0x0A, 0xD6, 0xB8, 0x06 - }, - { - 0xDD, 0xB8, 0x78, 0x24, 0x85, 0xE9, 0x00, 0xBC, - 0x60, 0xBC, 0xF4, 0xC3, 0x3A, 0x6F, 0xD5, 0x85, - 0x68, 0x0C, 0xC6, 0x83, 0xD5, 0x16, 0xEF, 0xA0, - 0x3E, 0xB9, 0x98, 0x5F, 0xAD, 0x87, 0x15, 0xFB - }, - { - 0x4C, 0x4D, 0x6E, 0x71, 0xAE, 0xA0, 0x57, 0x86, - 0x41, 0x31, 0x48, 0xFC, 0x7A, 0x78, 0x6B, 0x0E, - 0xCA, 0xF5, 0x82, 0xCF, 0xF1, 0x20, 0x9F, 0x5A, - 0x80, 0x9F, 0xBA, 0x85, 0x04, 0xCE, 0x66, 0x2C - }, - { - 0xFB, 0x4C, 0x5E, 0x86, 0xD7, 0xB2, 0x22, 0x9B, - 0x99, 0xB8, 0xBA, 0x6D, 0x94, 0xC2, 0x47, 0xEF, - 0x96, 0x4A, 0xA3, 0xA2, 0xBA, 0xE8, 0xED, 0xC7, - 0x75, 0x69, 0xF2, 0x8D, 0xBB, 0xFF, 0x2D, 0x4E - }, - { - 0xE9, 0x4F, 0x52, 0x6D, 0xE9, 0x01, 0x96, 0x33, - 0xEC, 0xD5, 0x4A, 0xC6, 0x12, 0x0F, 0x23, 0x95, - 0x8D, 0x77, 0x18, 0xF1, 0xE7, 0x71, 0x7B, 0xF3, - 0x29, 0x21, 0x1A, 0x4F, 0xAE, 0xED, 0x4E, 0x6D - }, - { - 0xCB, 0xD6, 0x66, 0x0A, 0x10, 0xDB, 0x3F, 0x23, - 0xF7, 0xA0, 0x3D, 0x4B, 0x9D, 0x40, 0x44, 0xC7, - 0x93, 0x2B, 0x28, 0x01, 0xAC, 0x89, 0xD6, 0x0B, - 0xC9, 0xEB, 0x92, 0xD6, 0x5A, 0x46, 0xC2, 0xA0 - }, - { - 0x88, 0x18, 0xBB, 0xD3, 0xDB, 0x4D, 0xC1, 0x23, - 0xB2, 0x5C, 0xBB, 0xA5, 0xF5, 0x4C, 0x2B, 0xC4, - 0xB3, 0xFC, 0xF9, 0xBF, 0x7D, 0x7A, 0x77, 0x09, - 0xF4, 0xAE, 0x58, 0x8B, 0x26, 0x7C, 0x4E, 0xCE - }, - { - 0xC6, 0x53, 0x82, 0x51, 0x3F, 0x07, 0x46, 0x0D, - 0xA3, 0x98, 0x33, 0xCB, 0x66, 0x6C, 0x5E, 0xD8, - 0x2E, 0x61, 0xB9, 0xE9, 0x98, 0xF4, 0xB0, 0xC4, - 0x28, 0x7C, 0xEE, 0x56, 0xC3, 0xCC, 0x9B, 0xCD - }, - { - 0x89, 0x75, 0xB0, 0x57, 0x7F, 0xD3, 0x55, 0x66, - 0xD7, 0x50, 0xB3, 0x62, 0xB0, 0x89, 0x7A, 0x26, - 0xC3, 0x99, 0x13, 0x6D, 0xF0, 0x7B, 0xAB, 0xAB, - 0xBD, 0xE6, 0x20, 0x3F, 0xF2, 0x95, 0x4E, 0xD4 - }, - { - 0x21, 0xFE, 0x0C, 0xEB, 0x00, 0x52, 0xBE, 0x7F, - 0xB0, 0xF0, 0x04, 0x18, 0x7C, 0xAC, 0xD7, 0xDE, - 0x67, 0xFA, 0x6E, 0xB0, 0x93, 0x8D, 0x92, 0x76, - 0x77, 0xF2, 0x39, 0x8C, 0x13, 0x23, 0x17, 0xA8 - }, - { - 0x2E, 0xF7, 0x3F, 0x3C, 0x26, 0xF1, 0x2D, 0x93, - 0x88, 0x9F, 0x3C, 0x78, 0xB6, 0xA6, 0x6C, 0x1D, - 0x52, 0xB6, 0x49, 0xDC, 0x9E, 0x85, 0x6E, 0x2C, - 0x17, 0x2E, 0xA7, 0xC5, 0x8A, 0xC2, 0xB5, 0xE3 - }, - { - 0x38, 0x8A, 0x3C, 0xD5, 0x6D, 0x73, 0x86, 0x7A, - 0xBB, 0x5F, 0x84, 0x01, 0x49, 0x2B, 0x6E, 0x26, - 0x81, 0xEB, 0x69, 0x85, 0x1E, 0x76, 0x7F, 0xD8, - 0x42, 0x10, 0xA5, 0x60, 0x76, 0xFB, 0x3D, 0xD3 - }, - { - 0xAF, 0x53, 0x3E, 0x02, 0x2F, 0xC9, 0x43, 0x9E, - 0x4E, 0x3C, 0xB8, 0x38, 0xEC, 0xD1, 0x86, 0x92, - 0x23, 0x2A, 0xDF, 0x6F, 0xE9, 0x83, 0x95, 0x26, - 0xD3, 0xC3, 0xDD, 0x1B, 0x71, 0x91, 0x0B, 0x1A - }, - { - 0x75, 0x1C, 0x09, 0xD4, 0x1A, 0x93, 0x43, 0x88, - 0x2A, 0x81, 0xCD, 0x13, 0xEE, 0x40, 0x81, 0x8D, - 0x12, 0xEB, 0x44, 0xC6, 0xC7, 0xF4, 0x0D, 0xF1, - 0x6E, 0x4A, 0xEA, 0x8F, 0xAB, 0x91, 0x97, 0x2A - }, - { - 0x5B, 0x73, 0xDD, 0xB6, 0x8D, 0x9D, 0x2B, 0x0A, - 0xA2, 0x65, 0xA0, 0x79, 0x88, 0xD6, 0xB8, 0x8A, - 0xE9, 0xAA, 0xC5, 0x82, 0xAF, 0x83, 0x03, 0x2F, - 0x8A, 0x9B, 0x21, 0xA2, 0xE1, 0xB7, 0xBF, 0x18 - }, - { - 0x3D, 0xA2, 0x91, 0x26, 0xC7, 0xC5, 0xD7, 0xF4, - 0x3E, 0x64, 0x24, 0x2A, 0x79, 0xFE, 0xAA, 0x4E, - 0xF3, 0x45, 0x9C, 0xDE, 0xCC, 0xC8, 0x98, 0xED, - 0x59, 0xA9, 0x7F, 0x6E, 0xC9, 0x3B, 0x9D, 0xAB - }, - { - 0x56, 0x6D, 0xC9, 0x20, 0x29, 0x3D, 0xA5, 0xCB, - 0x4F, 0xE0, 0xAA, 0x8A, 0xBD, 0xA8, 0xBB, 0xF5, - 0x6F, 0x55, 0x23, 0x13, 0xBF, 0xF1, 0x90, 0x46, - 0x64, 0x1E, 0x36, 0x15, 0xC1, 0xE3, 0xED, 0x3F - }, - { - 0x41, 0x15, 0xBE, 0xA0, 0x2F, 0x73, 0xF9, 0x7F, - 0x62, 0x9E, 0x5C, 0x55, 0x90, 0x72, 0x0C, 0x01, - 0xE7, 0xE4, 0x49, 0xAE, 0x2A, 0x66, 0x97, 0xD4, - 0xD2, 0x78, 0x33, 0x21, 0x30, 0x36, 0x92, 0xF9 - }, - { - 0x4C, 0xE0, 0x8F, 0x47, 0x62, 0x46, 0x8A, 0x76, - 0x70, 0x01, 0x21, 0x64, 0x87, 0x8D, 0x68, 0x34, - 0x0C, 0x52, 0xA3, 0x5E, 0x66, 0xC1, 0x88, 0x4D, - 0x5C, 0x86, 0x48, 0x89, 0xAB, 0xC9, 0x66, 0x77 - }, - { - 0x81, 0xEA, 0x0B, 0x78, 0x04, 0x12, 0x4E, 0x0C, - 0x22, 0xEA, 0x5F, 0xC7, 0x11, 0x04, 0xA2, 0xAF, - 0xCB, 0x52, 0xA1, 0xFA, 0x81, 0x6F, 0x3E, 0xCB, - 0x7D, 0xCB, 0x5D, 0x9D, 0xEA, 0x17, 0x86, 0xD0 - }, - { - 0xFE, 0x36, 0x27, 0x33, 0xB0, 0x5F, 0x6B, 0xED, - 0xAF, 0x93, 0x79, 0xD7, 0xF7, 0x93, 0x6E, 0xDE, - 0x20, 0x9B, 0x1F, 0x83, 0x23, 0xC3, 0x92, 0x25, - 0x49, 0xD9, 0xE7, 0x36, 0x81, 0xB5, 0xDB, 0x7B - }, - { - 0xEF, 0xF3, 0x7D, 0x30, 0xDF, 0xD2, 0x03, 0x59, - 0xBE, 0x4E, 0x73, 0xFD, 0xF4, 0x0D, 0x27, 0x73, - 0x4B, 0x3D, 0xF9, 0x0A, 0x97, 0xA5, 0x5E, 0xD7, - 0x45, 0x29, 0x72, 0x94, 0xCA, 0x85, 0xD0, 0x9F - }, - { - 0x17, 0x2F, 0xFC, 0x67, 0x15, 0x3D, 0x12, 0xE0, - 0xCA, 0x76, 0xA8, 0xB6, 0xCD, 0x5D, 0x47, 0x31, - 0x88, 0x5B, 0x39, 0xCE, 0x0C, 0xAC, 0x93, 0xA8, - 0x97, 0x2A, 0x18, 0x00, 0x6C, 0x8B, 0x8B, 0xAF - }, - { - 0xC4, 0x79, 0x57, 0xF1, 0xCC, 0x88, 0xE8, 0x3E, - 0xF9, 0x44, 0x58, 0x39, 0x70, 0x9A, 0x48, 0x0A, - 0x03, 0x6B, 0xED, 0x5F, 0x88, 0xAC, 0x0F, 0xCC, - 0x8E, 0x1E, 0x70, 0x3F, 0xFA, 0xAC, 0x13, 0x2C - }, - { - 0x30, 0xF3, 0x54, 0x83, 0x70, 0xCF, 0xDC, 0xED, - 0xA5, 0xC3, 0x7B, 0x56, 0x9B, 0x61, 0x75, 0xE7, - 0x99, 0xEE, 0xF1, 0xA6, 0x2A, 0xAA, 0x94, 0x32, - 0x45, 0xAE, 0x76, 0x69, 0xC2, 0x27, 0xA7, 0xB5 - }, - { - 0xC9, 0x5D, 0xCB, 0x3C, 0xF1, 0xF2, 0x7D, 0x0E, - 0xEF, 0x2F, 0x25, 0xD2, 0x41, 0x38, 0x70, 0x90, - 0x4A, 0x87, 0x7C, 0x4A, 0x56, 0xC2, 0xDE, 0x1E, - 0x83, 0xE2, 0xBC, 0x2A, 0xE2, 0xE4, 0x68, 0x21 - }, - { - 0xD5, 0xD0, 0xB5, 0xD7, 0x05, 0x43, 0x4C, 0xD4, - 0x6B, 0x18, 0x57, 0x49, 0xF6, 0x6B, 0xFB, 0x58, - 0x36, 0xDC, 0xDF, 0x6E, 0xE5, 0x49, 0xA2, 0xB7, - 0xA4, 0xAE, 0xE7, 0xF5, 0x80, 0x07, 0xCA, 0xAF - }, - { - 0xBB, 0xC1, 0x24, 0xA7, 0x12, 0xF1, 0x5D, 0x07, - 0xC3, 0x00, 0xE0, 0x5B, 0x66, 0x83, 0x89, 0xA4, - 0x39, 0xC9, 0x17, 0x77, 0xF7, 0x21, 0xF8, 0x32, - 0x0C, 0x1C, 0x90, 0x78, 0x06, 0x6D, 0x2C, 0x7E - }, - { - 0xA4, 0x51, 0xB4, 0x8C, 0x35, 0xA6, 0xC7, 0x85, - 0x4C, 0xFA, 0xAE, 0x60, 0x26, 0x2E, 0x76, 0x99, - 0x08, 0x16, 0x38, 0x2A, 0xC0, 0x66, 0x7E, 0x5A, - 0x5C, 0x9E, 0x1B, 0x46, 0xC4, 0x34, 0x2D, 0xDF - }, - { - 0xB0, 0xD1, 0x50, 0xFB, 0x55, 0xE7, 0x78, 0xD0, - 0x11, 0x47, 0xF0, 0xB5, 0xD8, 0x9D, 0x99, 0xEC, - 0xB2, 0x0F, 0xF0, 0x7E, 0x5E, 0x67, 0x60, 0xD6, - 0xB6, 0x45, 0xEB, 0x5B, 0x65, 0x4C, 0x62, 0x2B - }, - { - 0x34, 0xF7, 0x37, 0xC0, 0xAB, 0x21, 0x99, 0x51, - 0xEE, 0xE8, 0x9A, 0x9F, 0x8D, 0xAC, 0x29, 0x9C, - 0x9D, 0x4C, 0x38, 0xF3, 0x3F, 0xA4, 0x94, 0xC5, - 0xC6, 0xEE, 0xFC, 0x92, 0xB6, 0xDB, 0x08, 0xBC - }, - { - 0x1A, 0x62, 0xCC, 0x3A, 0x00, 0x80, 0x0D, 0xCB, - 0xD9, 0x98, 0x91, 0x08, 0x0C, 0x1E, 0x09, 0x84, - 0x58, 0x19, 0x3A, 0x8C, 0xC9, 0xF9, 0x70, 0xEA, - 0x99, 0xFB, 0xEF, 0xF0, 0x03, 0x18, 0xC2, 0x89 - }, - { - 0xCF, 0xCE, 0x55, 0xEB, 0xAF, 0xC8, 0x40, 0xD7, - 0xAE, 0x48, 0x28, 0x1C, 0x7F, 0xD5, 0x7E, 0xC8, - 0xB4, 0x82, 0xD4, 0xB7, 0x04, 0x43, 0x74, 0x95, - 0x49, 0x5A, 0xC4, 0x14, 0xCF, 0x4A, 0x37, 0x4B - }, - { - 0x67, 0x46, 0xFA, 0xCF, 0x71, 0x14, 0x6D, 0x99, - 0x9D, 0xAB, 0xD0, 0x5D, 0x09, 0x3A, 0xE5, 0x86, - 0x64, 0x8D, 0x1E, 0xE2, 0x8E, 0x72, 0x61, 0x7B, - 0x99, 0xD0, 0xF0, 0x08, 0x6E, 0x1E, 0x45, 0xBF - }, - { - 0x57, 0x1C, 0xED, 0x28, 0x3B, 0x3F, 0x23, 0xB4, - 0xE7, 0x50, 0xBF, 0x12, 0xA2, 0xCA, 0xF1, 0x78, - 0x18, 0x47, 0xBD, 0x89, 0x0E, 0x43, 0x60, 0x3C, - 0xDC, 0x59, 0x76, 0x10, 0x2B, 0x7B, 0xB1, 0x1B - }, - { - 0xCF, 0xCB, 0x76, 0x5B, 0x04, 0x8E, 0x35, 0x02, - 0x2C, 0x5D, 0x08, 0x9D, 0x26, 0xE8, 0x5A, 0x36, - 0xB0, 0x05, 0xA2, 0xB8, 0x04, 0x93, 0xD0, 0x3A, - 0x14, 0x4E, 0x09, 0xF4, 0x09, 0xB6, 0xAF, 0xD1 - }, - { - 0x40, 0x50, 0xC7, 0xA2, 0x77, 0x05, 0xBB, 0x27, - 0xF4, 0x20, 0x89, 0xB2, 0x99, 0xF3, 0xCB, 0xE5, - 0x05, 0x4E, 0xAD, 0x68, 0x72, 0x7E, 0x8E, 0xF9, - 0x31, 0x8C, 0xE6, 0xF2, 0x5C, 0xD6, 0xF3, 0x1D - }, - { - 0x18, 0x40, 0x70, 0xBD, 0x5D, 0x26, 0x5F, 0xBD, - 0xC1, 0x42, 0xCD, 0x1C, 0x5C, 0xD0, 0xD7, 0xE4, - 0x14, 0xE7, 0x03, 0x69, 0xA2, 0x66, 0xD6, 0x27, - 0xC8, 0xFB, 0xA8, 0x4F, 0xA5, 0xE8, 0x4C, 0x34 - }, - { - 0x9E, 0xDD, 0xA9, 0xA4, 0x44, 0x39, 0x02, 0xA9, - 0x58, 0x8C, 0x0D, 0x0C, 0xCC, 0x62, 0xB9, 0x30, - 0x21, 0x84, 0x79, 0xA6, 0x84, 0x1E, 0x6F, 0xE7, - 0xD4, 0x30, 0x03, 0xF0, 0x4B, 0x1F, 0xD6, 0x43 - }, - { - 0xE4, 0x12, 0xFE, 0xEF, 0x79, 0x08, 0x32, 0x4A, - 0x6D, 0xA1, 0x84, 0x16, 0x29, 0xF3, 0x5D, 0x3D, - 0x35, 0x86, 0x42, 0x01, 0x93, 0x10, 0xEC, 0x57, - 0xC6, 0x14, 0x83, 0x6B, 0x63, 0xD3, 0x07, 0x63 - }, - { - 0x1A, 0x2B, 0x8E, 0xDF, 0xF3, 0xF9, 0xAC, 0xC1, - 0x55, 0x4F, 0xCB, 0xAE, 0x3C, 0xF1, 0xD6, 0x29, - 0x8C, 0x64, 0x62, 0xE2, 0x2E, 0x5E, 0xB0, 0x25, - 0x96, 0x84, 0xF8, 0x35, 0x01, 0x2B, 0xD1, 0x3F - }, - { - 0x28, 0x8C, 0x4A, 0xD9, 0xB9, 0x40, 0x97, 0x62, - 0xEA, 0x07, 0xC2, 0x4A, 0x41, 0xF0, 0x4F, 0x69, - 0xA7, 0xD7, 0x4B, 0xEE, 0x2D, 0x95, 0x43, 0x53, - 0x74, 0xBD, 0xE9, 0x46, 0xD7, 0x24, 0x1C, 0x7B - }, - { - 0x80, 0x56, 0x91, 0xBB, 0x28, 0x67, 0x48, 0xCF, - 0xB5, 0x91, 0xD3, 0xAE, 0xBE, 0x7E, 0x6F, 0x4E, - 0x4D, 0xC6, 0xE2, 0x80, 0x8C, 0x65, 0x14, 0x3C, - 0xC0, 0x04, 0xE4, 0xEB, 0x6F, 0xD0, 0x9D, 0x43 - }, - { - 0xD4, 0xAC, 0x8D, 0x3A, 0x0A, 0xFC, 0x6C, 0xFA, - 0x7B, 0x46, 0x0A, 0xE3, 0x00, 0x1B, 0xAE, 0xB3, - 0x6D, 0xAD, 0xB3, 0x7D, 0xA0, 0x7D, 0x2E, 0x8A, - 0xC9, 0x18, 0x22, 0xDF, 0x34, 0x8A, 0xED, 0x3D - }, - { - 0xC3, 0x76, 0x61, 0x70, 0x14, 0xD2, 0x01, 0x58, - 0xBC, 0xED, 0x3D, 0x3B, 0xA5, 0x52, 0xB6, 0xEC, - 0xCF, 0x84, 0xE6, 0x2A, 0xA3, 0xEB, 0x65, 0x0E, - 0x90, 0x02, 0x9C, 0x84, 0xD1, 0x3E, 0xEA, 0x69 - }, - { - 0xC4, 0x1F, 0x09, 0xF4, 0x3C, 0xEC, 0xAE, 0x72, - 0x93, 0xD6, 0x00, 0x7C, 0xA0, 0xA3, 0x57, 0x08, - 0x7D, 0x5A, 0xE5, 0x9B, 0xE5, 0x00, 0xC1, 0xCD, - 0x5B, 0x28, 0x9E, 0xE8, 0x10, 0xC7, 0xB0, 0x82 - }, - { - 0x03, 0xD1, 0xCE, 0xD1, 0xFB, 0xA5, 0xC3, 0x91, - 0x55, 0xC4, 0x4B, 0x77, 0x65, 0xCB, 0x76, 0x0C, - 0x78, 0x70, 0x8D, 0xCF, 0xC8, 0x0B, 0x0B, 0xD8, - 0xAD, 0xE3, 0xA5, 0x6D, 0xA8, 0x83, 0x0B, 0x29 - }, - { - 0x09, 0xBD, 0xE6, 0xF1, 0x52, 0x21, 0x8D, 0xC9, - 0x2C, 0x41, 0xD7, 0xF4, 0x53, 0x87, 0xE6, 0x3E, - 0x58, 0x69, 0xD8, 0x07, 0xEC, 0x70, 0xB8, 0x21, - 0x40, 0x5D, 0xBD, 0x88, 0x4B, 0x7F, 0xCF, 0x4B - }, - { - 0x71, 0xC9, 0x03, 0x6E, 0x18, 0x17, 0x9B, 0x90, - 0xB3, 0x7D, 0x39, 0xE9, 0xF0, 0x5E, 0xB8, 0x9C, - 0xC5, 0xFC, 0x34, 0x1F, 0xD7, 0xC4, 0x77, 0xD0, - 0xD7, 0x49, 0x32, 0x85, 0xFA, 0xCA, 0x08, 0xA4 - }, - { - 0x59, 0x16, 0x83, 0x3E, 0xBB, 0x05, 0xCD, 0x91, - 0x9C, 0xA7, 0xFE, 0x83, 0xB6, 0x92, 0xD3, 0x20, - 0x5B, 0xEF, 0x72, 0x39, 0x2B, 0x2C, 0xF6, 0xBB, - 0x0A, 0x6D, 0x43, 0xF9, 0x94, 0xF9, 0x5F, 0x11 - }, - { - 0xF6, 0x3A, 0xAB, 0x3E, 0xC6, 0x41, 0xB3, 0xB0, - 0x24, 0x96, 0x4C, 0x2B, 0x43, 0x7C, 0x04, 0xF6, - 0x04, 0x3C, 0x4C, 0x7E, 0x02, 0x79, 0x23, 0x99, - 0x95, 0x40, 0x19, 0x58, 0xF8, 0x6B, 0xBE, 0x54 - }, - { - 0xF1, 0x72, 0xB1, 0x80, 0xBF, 0xB0, 0x97, 0x40, - 0x49, 0x31, 0x20, 0xB6, 0x32, 0x6C, 0xBD, 0xC5, - 0x61, 0xE4, 0x77, 0xDE, 0xF9, 0xBB, 0xCF, 0xD2, - 0x8C, 0xC8, 0xC1, 0xC5, 0xE3, 0x37, 0x9A, 0x31 - }, - { - 0xCB, 0x9B, 0x89, 0xCC, 0x18, 0x38, 0x1D, 0xD9, - 0x14, 0x1A, 0xDE, 0x58, 0x86, 0x54, 0xD4, 0xE6, - 0xA2, 0x31, 0xD5, 0xBF, 0x49, 0xD4, 0xD5, 0x9A, - 0xC2, 0x7D, 0x86, 0x9C, 0xBE, 0x10, 0x0C, 0xF3 - }, - { - 0x7B, 0xD8, 0x81, 0x50, 0x46, 0xFD, 0xD8, 0x10, - 0xA9, 0x23, 0xE1, 0x98, 0x4A, 0xAE, 0xBD, 0xCD, - 0xF8, 0x4D, 0x87, 0xC8, 0x99, 0x2D, 0x68, 0xB5, - 0xEE, 0xB4, 0x60, 0xF9, 0x3E, 0xB3, 0xC8, 0xD7 - }, - { - 0x60, 0x7B, 0xE6, 0x68, 0x62, 0xFD, 0x08, 0xEE, - 0x5B, 0x19, 0xFA, 0xCA, 0xC0, 0x9D, 0xFD, 0xBC, - 0xD4, 0x0C, 0x31, 0x21, 0x01, 0xD6, 0x6E, 0x6E, - 0xBD, 0x2B, 0x84, 0x1F, 0x1B, 0x9A, 0x93, 0x25 - }, - { - 0x9F, 0xE0, 0x3B, 0xBE, 0x69, 0xAB, 0x18, 0x34, - 0xF5, 0x21, 0x9B, 0x0D, 0xA8, 0x8A, 0x08, 0xB3, - 0x0A, 0x66, 0xC5, 0x91, 0x3F, 0x01, 0x51, 0x96, - 0x3C, 0x36, 0x05, 0x60, 0xDB, 0x03, 0x87, 0xB3 - }, - { - 0x90, 0xA8, 0x35, 0x85, 0x71, 0x7B, 0x75, 0xF0, - 0xE9, 0xB7, 0x25, 0xE0, 0x55, 0xEE, 0xEE, 0xB9, - 0xE7, 0xA0, 0x28, 0xEA, 0x7E, 0x6C, 0xBC, 0x07, - 0xB2, 0x09, 0x17, 0xEC, 0x03, 0x63, 0xE3, 0x8C - }, - { - 0x33, 0x6E, 0xA0, 0x53, 0x0F, 0x4A, 0x74, 0x69, - 0x12, 0x6E, 0x02, 0x18, 0x58, 0x7E, 0xBB, 0xDE, - 0x33, 0x58, 0xA0, 0xB3, 0x1C, 0x29, 0xD2, 0x00, - 0xF7, 0xDC, 0x7E, 0xB1, 0x5C, 0x6A, 0xAD, 0xD8 - }, - { - 0xA7, 0x9E, 0x76, 0xDC, 0x0A, 0xBC, 0xA4, 0x39, - 0x6F, 0x07, 0x47, 0xCD, 0x7B, 0x74, 0x8D, 0xF9, - 0x13, 0x00, 0x76, 0x26, 0xB1, 0xD6, 0x59, 0xDA, - 0x0C, 0x1F, 0x78, 0xB9, 0x30, 0x3D, 0x01, 0xA3 - }, - { - 0x44, 0xE7, 0x8A, 0x77, 0x37, 0x56, 0xE0, 0x95, - 0x15, 0x19, 0x50, 0x4D, 0x70, 0x38, 0xD2, 0x8D, - 0x02, 0x13, 0xA3, 0x7E, 0x0C, 0xE3, 0x75, 0x37, - 0x17, 0x57, 0xBC, 0x99, 0x63, 0x11, 0xE3, 0xB8 - }, - { - 0x77, 0xAC, 0x01, 0x2A, 0x3F, 0x75, 0x4D, 0xCF, - 0xEA, 0xB5, 0xEB, 0x99, 0x6B, 0xE9, 0xCD, 0x2D, - 0x1F, 0x96, 0x11, 0x1B, 0x6E, 0x49, 0xF3, 0x99, - 0x4D, 0xF1, 0x81, 0xF2, 0x85, 0x69, 0xD8, 0x25 - }, - { - 0xCE, 0x5A, 0x10, 0xDB, 0x6F, 0xCC, 0xDA, 0xF1, - 0x40, 0xAA, 0xA4, 0xDE, 0xD6, 0x25, 0x0A, 0x9C, - 0x06, 0xE9, 0x22, 0x2B, 0xC9, 0xF9, 0xF3, 0x65, - 0x8A, 0x4A, 0xFF, 0x93, 0x5F, 0x2B, 0x9F, 0x3A - }, - { - 0xEC, 0xC2, 0x03, 0xA7, 0xFE, 0x2B, 0xE4, 0xAB, - 0xD5, 0x5B, 0xB5, 0x3E, 0x6E, 0x67, 0x35, 0x72, - 0xE0, 0x07, 0x8D, 0xA8, 0xCD, 0x37, 0x5E, 0xF4, - 0x30, 0xCC, 0x97, 0xF9, 0xF8, 0x00, 0x83, 0xAF - }, - { - 0x14, 0xA5, 0x18, 0x6D, 0xE9, 0xD7, 0xA1, 0x8B, - 0x04, 0x12, 0xB8, 0x56, 0x3E, 0x51, 0xCC, 0x54, - 0x33, 0x84, 0x0B, 0x4A, 0x12, 0x9A, 0x8F, 0xF9, - 0x63, 0xB3, 0x3A, 0x3C, 0x4A, 0xFE, 0x8E, 0xBB - }, - { - 0x13, 0xF8, 0xEF, 0x95, 0xCB, 0x86, 0xE6, 0xA6, - 0x38, 0x93, 0x1C, 0x8E, 0x10, 0x76, 0x73, 0xEB, - 0x76, 0xBA, 0x10, 0xD7, 0xC2, 0xCD, 0x70, 0xB9, - 0xD9, 0x92, 0x0B, 0xBE, 0xED, 0x92, 0x94, 0x09 - }, - { - 0x0B, 0x33, 0x8F, 0x4E, 0xE1, 0x2F, 0x2D, 0xFC, - 0xB7, 0x87, 0x13, 0x37, 0x79, 0x41, 0xE0, 0xB0, - 0x63, 0x21, 0x52, 0x58, 0x1D, 0x13, 0x32, 0x51, - 0x6E, 0x4A, 0x2C, 0xAB, 0x19, 0x42, 0xCC, 0xA4 - }, - { - 0xEA, 0xAB, 0x0E, 0xC3, 0x7B, 0x3B, 0x8A, 0xB7, - 0x96, 0xE9, 0xF5, 0x72, 0x38, 0xDE, 0x14, 0xA2, - 0x64, 0xA0, 0x76, 0xF3, 0x88, 0x7D, 0x86, 0xE2, - 0x9B, 0xB5, 0x90, 0x6D, 0xB5, 0xA0, 0x0E, 0x02 - }, - { - 0x23, 0xCB, 0x68, 0xB8, 0xC0, 0xE6, 0xDC, 0x26, - 0xDC, 0x27, 0x76, 0x6D, 0xDC, 0x0A, 0x13, 0xA9, - 0x94, 0x38, 0xFD, 0x55, 0x61, 0x7A, 0xA4, 0x09, - 0x5D, 0x8F, 0x96, 0x97, 0x20, 0xC8, 0x72, 0xDF - }, - { - 0x09, 0x1D, 0x8E, 0xE3, 0x0D, 0x6F, 0x29, 0x68, - 0xD4, 0x6B, 0x68, 0x7D, 0xD6, 0x52, 0x92, 0x66, - 0x57, 0x42, 0xDE, 0x0B, 0xB8, 0x3D, 0xCC, 0x00, - 0x04, 0xC7, 0x2C, 0xE1, 0x00, 0x07, 0xA5, 0x49 - }, - { - 0x7F, 0x50, 0x7A, 0xBC, 0x6D, 0x19, 0xBA, 0x00, - 0xC0, 0x65, 0xA8, 0x76, 0xEC, 0x56, 0x57, 0x86, - 0x88, 0x82, 0xD1, 0x8A, 0x22, 0x1B, 0xC4, 0x6C, - 0x7A, 0x69, 0x12, 0x54, 0x1F, 0x5B, 0xC7, 0xBA - }, - { - 0xA0, 0x60, 0x7C, 0x24, 0xE1, 0x4E, 0x8C, 0x22, - 0x3D, 0xB0, 0xD7, 0x0B, 0x4D, 0x30, 0xEE, 0x88, - 0x01, 0x4D, 0x60, 0x3F, 0x43, 0x7E, 0x9E, 0x02, - 0xAA, 0x7D, 0xAF, 0xA3, 0xCD, 0xFB, 0xAD, 0x94 - }, - { - 0xDD, 0xBF, 0xEA, 0x75, 0xCC, 0x46, 0x78, 0x82, - 0xEB, 0x34, 0x83, 0xCE, 0x5E, 0x2E, 0x75, 0x6A, - 0x4F, 0x47, 0x01, 0xB7, 0x6B, 0x44, 0x55, 0x19, - 0xE8, 0x9F, 0x22, 0xD6, 0x0F, 0xA8, 0x6E, 0x06 - }, - { - 0x0C, 0x31, 0x1F, 0x38, 0xC3, 0x5A, 0x4F, 0xB9, - 0x0D, 0x65, 0x1C, 0x28, 0x9D, 0x48, 0x68, 0x56, - 0xCD, 0x14, 0x13, 0xDF, 0x9B, 0x06, 0x77, 0xF5, - 0x3E, 0xCE, 0x2C, 0xD9, 0xE4, 0x77, 0xC6, 0x0A - }, - { - 0x46, 0xA7, 0x3A, 0x8D, 0xD3, 0xE7, 0x0F, 0x59, - 0xD3, 0x94, 0x2C, 0x01, 0xDF, 0x59, 0x9D, 0xEF, - 0x78, 0x3C, 0x9D, 0xA8, 0x2F, 0xD8, 0x32, 0x22, - 0xCD, 0x66, 0x2B, 0x53, 0xDC, 0xE7, 0xDB, 0xDF - }, - { - 0xAD, 0x03, 0x8F, 0xF9, 0xB1, 0x4D, 0xE8, 0x4A, - 0x80, 0x1E, 0x4E, 0x62, 0x1C, 0xE5, 0xDF, 0x02, - 0x9D, 0xD9, 0x35, 0x20, 0xD0, 0xC2, 0xFA, 0x38, - 0xBF, 0xF1, 0x76, 0xA8, 0xB1, 0xD1, 0x69, 0x8C - }, - { - 0xAB, 0x70, 0xC5, 0xDF, 0xBD, 0x1E, 0xA8, 0x17, - 0xFE, 0xD0, 0xCD, 0x06, 0x72, 0x93, 0xAB, 0xF3, - 0x19, 0xE5, 0xD7, 0x90, 0x1C, 0x21, 0x41, 0xD5, - 0xD9, 0x9B, 0x23, 0xF0, 0x3A, 0x38, 0xE7, 0x48 - }, - { - 0x1F, 0xFF, 0xDA, 0x67, 0x93, 0x2B, 0x73, 0xC8, - 0xEC, 0xAF, 0x00, 0x9A, 0x34, 0x91, 0xA0, 0x26, - 0x95, 0x3B, 0xAB, 0xFE, 0x1F, 0x66, 0x3B, 0x06, - 0x97, 0xC3, 0xC4, 0xAE, 0x8B, 0x2E, 0x7D, 0xCB - }, - { - 0xB0, 0xD2, 0xCC, 0x19, 0x47, 0x2D, 0xD5, 0x7F, - 0x2B, 0x17, 0xEF, 0xC0, 0x3C, 0x8D, 0x58, 0xC2, - 0x28, 0x3D, 0xBB, 0x19, 0xDA, 0x57, 0x2F, 0x77, - 0x55, 0x85, 0x5A, 0xA9, 0x79, 0x43, 0x17, 0xA0 - }, - { - 0xA0, 0xD1, 0x9A, 0x6E, 0xE3, 0x39, 0x79, 0xC3, - 0x25, 0x51, 0x0E, 0x27, 0x66, 0x22, 0xDF, 0x41, - 0xF7, 0x15, 0x83, 0xD0, 0x75, 0x01, 0xB8, 0x70, - 0x71, 0x12, 0x9A, 0x0A, 0xD9, 0x47, 0x32, 0xA5 - }, - { - 0x72, 0x46, 0x42, 0xA7, 0x03, 0x2D, 0x10, 0x62, - 0xB8, 0x9E, 0x52, 0xBE, 0xA3, 0x4B, 0x75, 0xDF, - 0x7D, 0x8F, 0xE7, 0x72, 0xD9, 0xFE, 0x3C, 0x93, - 0xDD, 0xF3, 0xC4, 0x54, 0x5A, 0xB5, 0xA9, 0x9B - }, - { - 0xAD, 0xE5, 0xEA, 0xA7, 0xE6, 0x1F, 0x67, 0x2D, - 0x58, 0x7E, 0xA0, 0x3D, 0xAE, 0x7D, 0x7B, 0x55, - 0x22, 0x9C, 0x01, 0xD0, 0x6B, 0xC0, 0xA5, 0x70, - 0x14, 0x36, 0xCB, 0xD1, 0x83, 0x66, 0xA6, 0x26 - }, - { - 0x01, 0x3B, 0x31, 0xEB, 0xD2, 0x28, 0xFC, 0xDD, - 0xA5, 0x1F, 0xAB, 0xB0, 0x3B, 0xB0, 0x2D, 0x60, - 0xAC, 0x20, 0xCA, 0x21, 0x5A, 0xAF, 0xA8, 0x3B, - 0xDD, 0x85, 0x5E, 0x37, 0x55, 0xA3, 0x5F, 0x0B - }, - { - 0x33, 0x2E, 0xD4, 0x0B, 0xB1, 0x0D, 0xDE, 0x3C, - 0x95, 0x4A, 0x75, 0xD7, 0xB8, 0x99, 0x9D, 0x4B, - 0x26, 0xA1, 0xC0, 0x63, 0xC1, 0xDC, 0x6E, 0x32, - 0xC1, 0xD9, 0x1B, 0xAB, 0x7B, 0xBB, 0x7D, 0x16 - }, - { - 0xC7, 0xA1, 0x97, 0xB3, 0xA0, 0x5B, 0x56, 0x6B, - 0xCC, 0x9F, 0xAC, 0xD2, 0x0E, 0x44, 0x1D, 0x6F, - 0x6C, 0x28, 0x60, 0xAC, 0x96, 0x51, 0xCD, 0x51, - 0xD6, 0xB9, 0xD2, 0xCD, 0xEE, 0xEA, 0x03, 0x90 - }, - { - 0xBD, 0x9C, 0xF6, 0x4E, 0xA8, 0x95, 0x3C, 0x03, - 0x71, 0x08, 0xE6, 0xF6, 0x54, 0x91, 0x4F, 0x39, - 0x58, 0xB6, 0x8E, 0x29, 0xC1, 0x67, 0x00, 0xDC, - 0x18, 0x4D, 0x94, 0xA2, 0x17, 0x08, 0xFF, 0x60 - }, - { - 0x88, 0x35, 0xB0, 0xAC, 0x02, 0x11, 0x51, 0xDF, - 0x71, 0x64, 0x74, 0xCE, 0x27, 0xCE, 0x4D, 0x3C, - 0x15, 0xF0, 0xB2, 0xDA, 0xB4, 0x80, 0x03, 0xCF, - 0x3F, 0x3E, 0xFD, 0x09, 0x45, 0x10, 0x6B, 0x9A - }, - { - 0x3B, 0xFE, 0xFA, 0x33, 0x01, 0xAA, 0x55, 0xC0, - 0x80, 0x19, 0x0C, 0xFF, 0xDA, 0x8E, 0xAE, 0x51, - 0xD9, 0xAF, 0x48, 0x8B, 0x4C, 0x1F, 0x24, 0xC3, - 0xD9, 0xA7, 0x52, 0x42, 0xFD, 0x8E, 0xA0, 0x1D - }, - { - 0x08, 0x28, 0x4D, 0x14, 0x99, 0x3C, 0xD4, 0x7D, - 0x53, 0xEB, 0xAE, 0xCF, 0x0D, 0xF0, 0x47, 0x8C, - 0xC1, 0x82, 0xC8, 0x9C, 0x00, 0xE1, 0x85, 0x9C, - 0x84, 0x85, 0x16, 0x86, 0xDD, 0xF2, 0xC1, 0xB7 - }, - { - 0x1E, 0xD7, 0xEF, 0x9F, 0x04, 0xC2, 0xAC, 0x8D, - 0xB6, 0xA8, 0x64, 0xDB, 0x13, 0x10, 0x87, 0xF2, - 0x70, 0x65, 0x09, 0x8E, 0x69, 0xC3, 0xFE, 0x78, - 0x71, 0x8D, 0x9B, 0x94, 0x7F, 0x4A, 0x39, 0xD0 - }, - { - 0xC1, 0x61, 0xF2, 0xDC, 0xD5, 0x7E, 0x9C, 0x14, - 0x39, 0xB3, 0x1A, 0x9D, 0xD4, 0x3D, 0x8F, 0x3D, - 0x7D, 0xD8, 0xF0, 0xEB, 0x7C, 0xFA, 0xC6, 0xFB, - 0x25, 0xA0, 0xF2, 0x8E, 0x30, 0x6F, 0x06, 0x61 - }, - { - 0xC0, 0x19, 0x69, 0xAD, 0x34, 0xC5, 0x2C, 0xAF, - 0x3D, 0xC4, 0xD8, 0x0D, 0x19, 0x73, 0x5C, 0x29, - 0x73, 0x1A, 0xC6, 0xE7, 0xA9, 0x20, 0x85, 0xAB, - 0x92, 0x50, 0xC4, 0x8D, 0xEA, 0x48, 0xA3, 0xFC - }, - { - 0x17, 0x20, 0xB3, 0x65, 0x56, 0x19, 0xD2, 0xA5, - 0x2B, 0x35, 0x21, 0xAE, 0x0E, 0x49, 0xE3, 0x45, - 0xCB, 0x33, 0x89, 0xEB, 0xD6, 0x20, 0x8A, 0xCA, - 0xF9, 0xF1, 0x3F, 0xDA, 0xCC, 0xA8, 0xBE, 0x49 - }, - { - 0x75, 0x62, 0x88, 0x36, 0x1C, 0x83, 0xE2, 0x4C, - 0x61, 0x7C, 0xF9, 0x5C, 0x90, 0x5B, 0x22, 0xD0, - 0x17, 0xCD, 0xC8, 0x6F, 0x0B, 0xF1, 0xD6, 0x58, - 0xF4, 0x75, 0x6C, 0x73, 0x79, 0x87, 0x3B, 0x7F - }, - { - 0xE7, 0xD0, 0xED, 0xA3, 0x45, 0x26, 0x93, 0xB7, - 0x52, 0xAB, 0xCD, 0xA1, 0xB5, 0x5E, 0x27, 0x6F, - 0x82, 0x69, 0x8F, 0x5F, 0x16, 0x05, 0x40, 0x3E, - 0xFF, 0x83, 0x0B, 0xEA, 0x00, 0x71, 0xA3, 0x94 - }, - { - 0x2C, 0x82, 0xEC, 0xAA, 0x6B, 0x84, 0x80, 0x3E, - 0x04, 0x4A, 0xF6, 0x31, 0x18, 0xAF, 0xE5, 0x44, - 0x68, 0x7C, 0xB6, 0xE6, 0xC7, 0xDF, 0x49, 0xED, - 0x76, 0x2D, 0xFD, 0x7C, 0x86, 0x93, 0xA1, 0xBC - }, - { - 0x61, 0x36, 0xCB, 0xF4, 0xB4, 0x41, 0x05, 0x6F, - 0xA1, 0xE2, 0x72, 0x24, 0x98, 0x12, 0x5D, 0x6D, - 0xED, 0x45, 0xE1, 0x7B, 0x52, 0x14, 0x39, 0x59, - 0xC7, 0xF4, 0xD4, 0xE3, 0x95, 0x21, 0x8A, 0xC2 - }, - { - 0x72, 0x1D, 0x32, 0x45, 0xAA, 0xFE, 0xF2, 0x7F, - 0x6A, 0x62, 0x4F, 0x47, 0x95, 0x4B, 0x6C, 0x25, - 0x50, 0x79, 0x52, 0x6F, 0xFA, 0x25, 0xE9, 0xFF, - 0x77, 0xE5, 0xDC, 0xFF, 0x47, 0x3B, 0x15, 0x97 - }, - { - 0x9D, 0xD2, 0xFB, 0xD8, 0xCE, 0xF1, 0x6C, 0x35, - 0x3C, 0x0A, 0xC2, 0x11, 0x91, 0xD5, 0x09, 0xEB, - 0x28, 0xDD, 0x9E, 0x3E, 0x0D, 0x8C, 0xEA, 0x5D, - 0x26, 0xCA, 0x83, 0x93, 0x93, 0x85, 0x1C, 0x3A - }, - { - 0xB2, 0x39, 0x4C, 0xEA, 0xCD, 0xEB, 0xF2, 0x1B, - 0xF9, 0xDF, 0x2C, 0xED, 0x98, 0xE5, 0x8F, 0x1C, - 0x3A, 0x4B, 0xBB, 0xFF, 0x66, 0x0D, 0xD9, 0x00, - 0xF6, 0x22, 0x02, 0xD6, 0x78, 0x5C, 0xC4, 0x6E - }, - { - 0x57, 0x08, 0x9F, 0x22, 0x27, 0x49, 0xAD, 0x78, - 0x71, 0x76, 0x5F, 0x06, 0x2B, 0x11, 0x4F, 0x43, - 0xBA, 0x20, 0xEC, 0x56, 0x42, 0x2A, 0x8B, 0x1E, - 0x3F, 0x87, 0x19, 0x2C, 0x0E, 0xA7, 0x18, 0xC6 - }, - { - 0xE4, 0x9A, 0x94, 0x59, 0x96, 0x1C, 0xD3, 0x3C, - 0xDF, 0x4A, 0xAE, 0x1B, 0x10, 0x78, 0xA5, 0xDE, - 0xA7, 0xC0, 0x40, 0xE0, 0xFE, 0xA3, 0x40, 0xC9, - 0x3A, 0x72, 0x48, 0x72, 0xFC, 0x4A, 0xF8, 0x06 - }, - { - 0xED, 0xE6, 0x7F, 0x72, 0x0E, 0xFF, 0xD2, 0xCA, - 0x9C, 0x88, 0x99, 0x41, 0x52, 0xD0, 0x20, 0x1D, - 0xEE, 0x6B, 0x0A, 0x2D, 0x2C, 0x07, 0x7A, 0xCA, - 0x6D, 0xAE, 0x29, 0xF7, 0x3F, 0x8B, 0x63, 0x09 - }, - { - 0xE0, 0xF4, 0x34, 0xBF, 0x22, 0xE3, 0x08, 0x80, - 0x39, 0xC2, 0x1F, 0x71, 0x9F, 0xFC, 0x67, 0xF0, - 0xF2, 0xCB, 0x5E, 0x98, 0xA7, 0xA0, 0x19, 0x4C, - 0x76, 0xE9, 0x6B, 0xF4, 0xE8, 0xE1, 0x7E, 0x61 - }, - { - 0x27, 0x7C, 0x04, 0xE2, 0x85, 0x34, 0x84, 0xA4, - 0xEB, 0xA9, 0x10, 0xAD, 0x33, 0x6D, 0x01, 0xB4, - 0x77, 0xB6, 0x7C, 0xC2, 0x00, 0xC5, 0x9F, 0x3C, - 0x8D, 0x77, 0xEE, 0xF8, 0x49, 0x4F, 0x29, 0xCD - }, - { - 0x15, 0x6D, 0x57, 0x47, 0xD0, 0xC9, 0x9C, 0x7F, - 0x27, 0x09, 0x7D, 0x7B, 0x7E, 0x00, 0x2B, 0x2E, - 0x18, 0x5C, 0xB7, 0x2D, 0x8D, 0xD7, 0xEB, 0x42, - 0x4A, 0x03, 0x21, 0x52, 0x81, 0x61, 0x21, 0x9F - }, - { - 0x20, 0xDD, 0xD1, 0xED, 0x9B, 0x1C, 0xA8, 0x03, - 0x94, 0x6D, 0x64, 0xA8, 0x3A, 0xE4, 0x65, 0x9D, - 0xA6, 0x7F, 0xBA, 0x7A, 0x1A, 0x3E, 0xDD, 0xB1, - 0xE1, 0x03, 0xC0, 0xF5, 0xE0, 0x3E, 0x3A, 0x2C - }, - { - 0xF0, 0xAF, 0x60, 0x4D, 0x3D, 0xAB, 0xBF, 0x9A, - 0x0F, 0x2A, 0x7D, 0x3D, 0xDA, 0x6B, 0xD3, 0x8B, - 0xBA, 0x72, 0xC6, 0xD0, 0x9B, 0xE4, 0x94, 0xFC, - 0xEF, 0x71, 0x3F, 0xF1, 0x01, 0x89, 0xB6, 0xE6 - }, - { - 0x98, 0x02, 0xBB, 0x87, 0xDE, 0xF4, 0xCC, 0x10, - 0xC4, 0xA5, 0xFD, 0x49, 0xAA, 0x58, 0xDF, 0xE2, - 0xF3, 0xFD, 0xDB, 0x46, 0xB4, 0x70, 0x88, 0x14, - 0xEA, 0xD8, 0x1D, 0x23, 0xBA, 0x95, 0x13, 0x9B - }, - { - 0x4F, 0x8C, 0xE1, 0xE5, 0x1D, 0x2F, 0xE7, 0xF2, - 0x40, 0x43, 0xA9, 0x04, 0xD8, 0x98, 0xEB, 0xFC, - 0x91, 0x97, 0x54, 0x18, 0x75, 0x34, 0x13, 0xAA, - 0x09, 0x9B, 0x79, 0x5E, 0xCB, 0x35, 0xCE, 0xDB - }, - { - 0xBD, 0xDC, 0x65, 0x14, 0xD7, 0xEE, 0x6A, 0xCE, - 0x0A, 0x4A, 0xC1, 0xD0, 0xE0, 0x68, 0x11, 0x22, - 0x88, 0xCB, 0xCF, 0x56, 0x04, 0x54, 0x64, 0x27, - 0x05, 0x63, 0x01, 0x77, 0xCB, 0xA6, 0x08, 0xBD - }, - { - 0xD6, 0x35, 0x99, 0x4F, 0x62, 0x91, 0x51, 0x7B, - 0x02, 0x81, 0xFF, 0xDD, 0x49, 0x6A, 0xFA, 0x86, - 0x27, 0x12, 0xE5, 0xB3, 0xC4, 0xE5, 0x2E, 0x4C, - 0xD5, 0xFD, 0xAE, 0x8C, 0x0E, 0x72, 0xFB, 0x08 - }, - { - 0x87, 0x8D, 0x9C, 0xA6, 0x00, 0xCF, 0x87, 0xE7, - 0x69, 0xCC, 0x30, 0x5C, 0x1B, 0x35, 0x25, 0x51, - 0x86, 0x61, 0x5A, 0x73, 0xA0, 0xDA, 0x61, 0x3B, - 0x5F, 0x1C, 0x98, 0xDB, 0xF8, 0x12, 0x83, 0xEA - }, - { - 0xA6, 0x4E, 0xBE, 0x5D, 0xC1, 0x85, 0xDE, 0x9F, - 0xDD, 0xE7, 0x60, 0x7B, 0x69, 0x98, 0x70, 0x2E, - 0xB2, 0x34, 0x56, 0x18, 0x49, 0x57, 0x30, 0x7D, - 0x2F, 0xA7, 0x2E, 0x87, 0xA4, 0x77, 0x02, 0xD6 - }, - { - 0xCE, 0x50, 0xEA, 0xB7, 0xB5, 0xEB, 0x52, 0xBD, - 0xC9, 0xAD, 0x8E, 0x5A, 0x48, 0x0A, 0xB7, 0x80, - 0xCA, 0x93, 0x20, 0xE4, 0x43, 0x60, 0xB1, 0xFE, - 0x37, 0xE0, 0x3F, 0x2F, 0x7A, 0xD7, 0xDE, 0x01 - }, - { - 0xEE, 0xDD, 0xB7, 0xC0, 0xDB, 0x6E, 0x30, 0xAB, - 0xE6, 0x6D, 0x79, 0xE3, 0x27, 0x51, 0x1E, 0x61, - 0xFC, 0xEB, 0xBC, 0x29, 0xF1, 0x59, 0xB4, 0x0A, - 0x86, 0xB0, 0x46, 0xEC, 0xF0, 0x51, 0x38, 0x23 - }, - { - 0x78, 0x7F, 0xC9, 0x34, 0x40, 0xC1, 0xEC, 0x96, - 0xB5, 0xAD, 0x01, 0xC1, 0x6C, 0xF7, 0x79, 0x16, - 0xA1, 0x40, 0x5F, 0x94, 0x26, 0x35, 0x6E, 0xC9, - 0x21, 0xD8, 0xDF, 0xF3, 0xEA, 0x63, 0xB7, 0xE0 - }, - { - 0x7F, 0x0D, 0x5E, 0xAB, 0x47, 0xEE, 0xFD, 0xA6, - 0x96, 0xC0, 0xBF, 0x0F, 0xBF, 0x86, 0xAB, 0x21, - 0x6F, 0xCE, 0x46, 0x1E, 0x93, 0x03, 0xAB, 0xA6, - 0xAC, 0x37, 0x41, 0x20, 0xE8, 0x90, 0xE8, 0xDF - }, - { - 0xB6, 0x80, 0x04, 0xB4, 0x2F, 0x14, 0xAD, 0x02, - 0x9F, 0x4C, 0x2E, 0x03, 0xB1, 0xD5, 0xEB, 0x76, - 0xD5, 0x71, 0x60, 0xE2, 0x64, 0x76, 0xD2, 0x11, - 0x31, 0xBE, 0xF2, 0x0A, 0xDA, 0x7D, 0x27, 0xF4 - }, - { - 0xB0, 0xC4, 0xEB, 0x18, 0xAE, 0x25, 0x0B, 0x51, - 0xA4, 0x13, 0x82, 0xEA, 0xD9, 0x2D, 0x0D, 0xC7, - 0x45, 0x5F, 0x93, 0x79, 0xFC, 0x98, 0x84, 0x42, - 0x8E, 0x47, 0x70, 0x60, 0x8D, 0xB0, 0xFA, 0xEC - }, - { - 0xF9, 0x2B, 0x7A, 0x87, 0x0C, 0x05, 0x9F, 0x4D, - 0x46, 0x46, 0x4C, 0x82, 0x4E, 0xC9, 0x63, 0x55, - 0x14, 0x0B, 0xDC, 0xE6, 0x81, 0x32, 0x2C, 0xC3, - 0xA9, 0x92, 0xFF, 0x10, 0x3E, 0x3F, 0xEA, 0x52 - }, - { - 0x53, 0x64, 0x31, 0x26, 0x14, 0x81, 0x33, 0x98, - 0xCC, 0x52, 0x5D, 0x4C, 0x4E, 0x14, 0x6E, 0xDE, - 0xB3, 0x71, 0x26, 0x5F, 0xBA, 0x19, 0x13, 0x3A, - 0x2C, 0x3D, 0x21, 0x59, 0x29, 0x8A, 0x17, 0x42 - }, - { - 0xF6, 0x62, 0x0E, 0x68, 0xD3, 0x7F, 0xB2, 0xAF, - 0x50, 0x00, 0xFC, 0x28, 0xE2, 0x3B, 0x83, 0x22, - 0x97, 0xEC, 0xD8, 0xBC, 0xE9, 0x9E, 0x8B, 0xE4, - 0xD0, 0x4E, 0x85, 0x30, 0x9E, 0x3D, 0x33, 0x74 - }, - { - 0x53, 0x16, 0xA2, 0x79, 0x69, 0xD7, 0xFE, 0x04, - 0xFF, 0x27, 0xB2, 0x83, 0x96, 0x1B, 0xFF, 0xC3, - 0xBF, 0x5D, 0xFB, 0x32, 0xFB, 0x6A, 0x89, 0xD1, - 0x01, 0xC6, 0xC3, 0xB1, 0x93, 0x7C, 0x28, 0x71 - }, - { - 0x81, 0xD1, 0x66, 0x4F, 0xDF, 0x3C, 0xB3, 0x3C, - 0x24, 0xEE, 0xBA, 0xC0, 0xBD, 0x64, 0x24, 0x4B, - 0x77, 0xC4, 0xAB, 0xEA, 0x90, 0xBB, 0xE8, 0xB5, - 0xEE, 0x0B, 0x2A, 0xAF, 0xCF, 0x2D, 0x6A, 0x53 - }, - { - 0x34, 0x57, 0x82, 0xF2, 0x95, 0xB0, 0x88, 0x03, - 0x52, 0xE9, 0x24, 0xA0, 0x46, 0x7B, 0x5F, 0xBC, - 0x3E, 0x8F, 0x3B, 0xFB, 0xC3, 0xC7, 0xE4, 0x8B, - 0x67, 0x09, 0x1F, 0xB5, 0xE8, 0x0A, 0x94, 0x42 - }, - { - 0x79, 0x41, 0x11, 0xEA, 0x6C, 0xD6, 0x5E, 0x31, - 0x1F, 0x74, 0xEE, 0x41, 0xD4, 0x76, 0xCB, 0x63, - 0x2C, 0xE1, 0xE4, 0xB0, 0x51, 0xDC, 0x1D, 0x9E, - 0x9D, 0x06, 0x1A, 0x19, 0xE1, 0xD0, 0xBB, 0x49 - }, - { - 0x2A, 0x85, 0xDA, 0xF6, 0x13, 0x88, 0x16, 0xB9, - 0x9B, 0xF8, 0xD0, 0x8B, 0xA2, 0x11, 0x4B, 0x7A, - 0xB0, 0x79, 0x75, 0xA7, 0x84, 0x20, 0xC1, 0xA3, - 0xB0, 0x6A, 0x77, 0x7C, 0x22, 0xDD, 0x8B, 0xCB - }, - { - 0x89, 0xB0, 0xD5, 0xF2, 0x89, 0xEC, 0x16, 0x40, - 0x1A, 0x06, 0x9A, 0x96, 0x0D, 0x0B, 0x09, 0x3E, - 0x62, 0x5D, 0xA3, 0xCF, 0x41, 0xEE, 0x29, 0xB5, - 0x9B, 0x93, 0x0C, 0x58, 0x20, 0x14, 0x54, 0x55 - }, - { - 0xD0, 0xFD, 0xCB, 0x54, 0x39, 0x43, 0xFC, 0x27, - 0xD2, 0x08, 0x64, 0xF5, 0x21, 0x81, 0x47, 0x1B, - 0x94, 0x2C, 0xC7, 0x7C, 0xA6, 0x75, 0xBC, 0xB3, - 0x0D, 0xF3, 0x1D, 0x35, 0x8E, 0xF7, 0xB1, 0xEB - }, - { - 0xB1, 0x7E, 0xA8, 0xD7, 0x70, 0x63, 0xC7, 0x09, - 0xD4, 0xDC, 0x6B, 0x87, 0x94, 0x13, 0xC3, 0x43, - 0xE3, 0x79, 0x0E, 0x9E, 0x62, 0xCA, 0x85, 0xB7, - 0x90, 0x0B, 0x08, 0x6F, 0x6B, 0x75, 0xC6, 0x72 - }, - { - 0xE7, 0x1A, 0x3E, 0x2C, 0x27, 0x4D, 0xB8, 0x42, - 0xD9, 0x21, 0x14, 0xF2, 0x17, 0xE2, 0xC0, 0xEA, - 0xC8, 0xB4, 0x50, 0x93, 0xFD, 0xFD, 0x9D, 0xF4, - 0xCA, 0x71, 0x62, 0x39, 0x48, 0x62, 0xD5, 0x01 - }, - { - 0xC0, 0x47, 0x67, 0x59, 0xAB, 0x7A, 0xA3, 0x33, - 0x23, 0x4F, 0x6B, 0x44, 0xF5, 0xFD, 0x85, 0x83, - 0x90, 0xEC, 0x23, 0x69, 0x4C, 0x62, 0x2C, 0xB9, - 0x86, 0xE7, 0x69, 0xC7, 0x8E, 0xDD, 0x73, 0x3E - }, - { - 0x9A, 0xB8, 0xEA, 0xBB, 0x14, 0x16, 0x43, 0x4D, - 0x85, 0x39, 0x13, 0x41, 0xD5, 0x69, 0x93, 0xC5, - 0x54, 0x58, 0x16, 0x7D, 0x44, 0x18, 0xB1, 0x9A, - 0x0F, 0x2A, 0xD8, 0xB7, 0x9A, 0x83, 0xA7, 0x5B - }, - { - 0x79, 0x92, 0xD0, 0xBB, 0xB1, 0x5E, 0x23, 0x82, - 0x6F, 0x44, 0x3E, 0x00, 0x50, 0x5D, 0x68, 0xD3, - 0xED, 0x73, 0x72, 0x99, 0x5A, 0x5C, 0x3E, 0x49, - 0x86, 0x54, 0x10, 0x2F, 0xBC, 0xD0, 0x96, 0x4E - }, - { - 0xC0, 0x21, 0xB3, 0x00, 0x85, 0x15, 0x14, 0x35, - 0xDF, 0x33, 0xB0, 0x07, 0xCC, 0xEC, 0xC6, 0x9D, - 0xF1, 0x26, 0x9F, 0x39, 0xBA, 0x25, 0x09, 0x2B, - 0xED, 0x59, 0xD9, 0x32, 0xAC, 0x0F, 0xDC, 0x28 - }, - { - 0x91, 0xA2, 0x5E, 0xC0, 0xEC, 0x0D, 0x9A, 0x56, - 0x7F, 0x89, 0xC4, 0xBF, 0xE1, 0xA6, 0x5A, 0x0E, - 0x43, 0x2D, 0x07, 0x06, 0x4B, 0x41, 0x90, 0xE2, - 0x7D, 0xFB, 0x81, 0x90, 0x1F, 0xD3, 0x13, 0x9B - }, - { - 0x59, 0x50, 0xD3, 0x9A, 0x23, 0xE1, 0x54, 0x5F, - 0x30, 0x12, 0x70, 0xAA, 0x1A, 0x12, 0xF2, 0xE6, - 0xC4, 0x53, 0x77, 0x6E, 0x4D, 0x63, 0x55, 0xDE, - 0x42, 0x5C, 0xC1, 0x53, 0xF9, 0x81, 0x88, 0x67 - }, - { - 0xD7, 0x9F, 0x14, 0x72, 0x0C, 0x61, 0x0A, 0xF1, - 0x79, 0xA3, 0x76, 0x5D, 0x4B, 0x7C, 0x09, 0x68, - 0xF9, 0x77, 0x96, 0x2D, 0xBF, 0x65, 0x5B, 0x52, - 0x12, 0x72, 0xB6, 0xF1, 0xE1, 0x94, 0x48, 0x8E - }, - { - 0xE9, 0x53, 0x1B, 0xFC, 0x8B, 0x02, 0x99, 0x5A, - 0xEA, 0xA7, 0x5B, 0xA2, 0x70, 0x31, 0xFA, 0xDB, - 0xCB, 0xF4, 0xA0, 0xDA, 0xB8, 0x96, 0x1D, 0x92, - 0x96, 0xCD, 0x7E, 0x84, 0xD2, 0x5D, 0x60, 0x06 - }, - { - 0x34, 0xE9, 0xC2, 0x6A, 0x01, 0xD7, 0xF1, 0x61, - 0x81, 0xB4, 0x54, 0xA9, 0xD1, 0x62, 0x3C, 0x23, - 0x3C, 0xB9, 0x9D, 0x31, 0xC6, 0x94, 0x65, 0x6E, - 0x94, 0x13, 0xAC, 0xA3, 0xE9, 0x18, 0x69, 0x2F - }, - { - 0xD9, 0xD7, 0x42, 0x2F, 0x43, 0x7B, 0xD4, 0x39, - 0xDD, 0xD4, 0xD8, 0x83, 0xDA, 0xE2, 0xA0, 0x83, - 0x50, 0x17, 0x34, 0x14, 0xBE, 0x78, 0x15, 0x51, - 0x33, 0xFF, 0xF1, 0x96, 0x4C, 0x3D, 0x79, 0x72 - }, - { - 0x4A, 0xEE, 0x0C, 0x7A, 0xAF, 0x07, 0x54, 0x14, - 0xFF, 0x17, 0x93, 0xEA, 0xD7, 0xEA, 0xCA, 0x60, - 0x17, 0x75, 0xC6, 0x15, 0xDB, 0xD6, 0x0B, 0x64, - 0x0B, 0x0A, 0x9F, 0x0C, 0xE5, 0x05, 0xD4, 0x35 - }, - { - 0x6B, 0xFD, 0xD1, 0x54, 0x59, 0xC8, 0x3B, 0x99, - 0xF0, 0x96, 0xBF, 0xB4, 0x9E, 0xE8, 0x7B, 0x06, - 0x3D, 0x69, 0xC1, 0x97, 0x4C, 0x69, 0x28, 0xAC, - 0xFC, 0xFB, 0x40, 0x99, 0xF8, 0xC4, 0xEF, 0x67 - }, - { - 0x9F, 0xD1, 0xC4, 0x08, 0xFD, 0x75, 0xC3, 0x36, - 0x19, 0x3A, 0x2A, 0x14, 0xD9, 0x4F, 0x6A, 0xF5, - 0xAD, 0xF0, 0x50, 0xB8, 0x03, 0x87, 0xB4, 0xB0, - 0x10, 0xFB, 0x29, 0xF4, 0xCC, 0x72, 0x70, 0x7C - }, - { - 0x13, 0xC8, 0x84, 0x80, 0xA5, 0xD0, 0x0D, 0x6C, - 0x8C, 0x7A, 0xD2, 0x11, 0x0D, 0x76, 0xA8, 0x2D, - 0x9B, 0x70, 0xF4, 0xFA, 0x66, 0x96, 0xD4, 0xE5, - 0xDD, 0x42, 0xA0, 0x66, 0xDC, 0xAF, 0x99, 0x20 - }, - { - 0x82, 0x0E, 0x72, 0x5E, 0xE2, 0x5F, 0xE8, 0xFD, - 0x3A, 0x8D, 0x5A, 0xBE, 0x4C, 0x46, 0xC3, 0xBA, - 0x88, 0x9D, 0xE6, 0xFA, 0x91, 0x91, 0xAA, 0x22, - 0xBA, 0x67, 0xD5, 0x70, 0x54, 0x21, 0x54, 0x2B - }, - { - 0x32, 0xD9, 0x3A, 0x0E, 0xB0, 0x2F, 0x42, 0xFB, - 0xBC, 0xAF, 0x2B, 0xAD, 0x00, 0x85, 0xB2, 0x82, - 0xE4, 0x60, 0x46, 0xA4, 0xDF, 0x7A, 0xD1, 0x06, - 0x57, 0xC9, 0xD6, 0x47, 0x63, 0x75, 0xB9, 0x3E - }, - { - 0xAD, 0xC5, 0x18, 0x79, 0x05, 0xB1, 0x66, 0x9C, - 0xD8, 0xEC, 0x9C, 0x72, 0x1E, 0x19, 0x53, 0x78, - 0x6B, 0x9D, 0x89, 0xA9, 0xBA, 0xE3, 0x07, 0x80, - 0xF1, 0xE1, 0xEA, 0xB2, 0x4A, 0x00, 0x52, 0x3C - }, - { - 0xE9, 0x07, 0x56, 0xFF, 0x7F, 0x9A, 0xD8, 0x10, - 0xB2, 0x39, 0xA1, 0x0C, 0xED, 0x2C, 0xF9, 0xB2, - 0x28, 0x43, 0x54, 0xC1, 0xF8, 0xC7, 0xE0, 0xAC, - 0xCC, 0x24, 0x61, 0xDC, 0x79, 0x6D, 0x6E, 0x89 - }, - { - 0x12, 0x51, 0xF7, 0x6E, 0x56, 0x97, 0x84, 0x81, - 0x87, 0x53, 0x59, 0x80, 0x1D, 0xB5, 0x89, 0xA0, - 0xB2, 0x2F, 0x86, 0xD8, 0xD6, 0x34, 0xDC, 0x04, - 0x50, 0x6F, 0x32, 0x2E, 0xD7, 0x8F, 0x17, 0xE8 - }, - { - 0x3A, 0xFA, 0x89, 0x9F, 0xD9, 0x80, 0xE7, 0x3E, - 0xCB, 0x7F, 0x4D, 0x8B, 0x8F, 0x29, 0x1D, 0xC9, - 0xAF, 0x79, 0x6B, 0xC6, 0x5D, 0x27, 0xF9, 0x74, - 0xC6, 0xF1, 0x93, 0xC9, 0x19, 0x1A, 0x09, 0xFD - }, - { - 0xAA, 0x30, 0x5B, 0xE2, 0x6E, 0x5D, 0xED, 0xDC, - 0x3C, 0x10, 0x10, 0xCB, 0xC2, 0x13, 0xF9, 0x5F, - 0x05, 0x1C, 0x78, 0x5C, 0x5B, 0x43, 0x1E, 0x6A, - 0x7C, 0xD0, 0x48, 0xF1, 0x61, 0x78, 0x75, 0x28 - }, - { - 0x8E, 0xA1, 0x88, 0x4F, 0xF3, 0x2E, 0x9D, 0x10, - 0xF0, 0x39, 0xB4, 0x07, 0xD0, 0xD4, 0x4E, 0x7E, - 0x67, 0x0A, 0xBD, 0x88, 0x4A, 0xEE, 0xE0, 0xFB, - 0x75, 0x7A, 0xE9, 0x4E, 0xAA, 0x97, 0x37, 0x3D - }, - { - 0xD4, 0x82, 0xB2, 0x15, 0x5D, 0x4D, 0xEC, 0x6B, - 0x47, 0x36, 0xA1, 0xF1, 0x61, 0x7B, 0x53, 0xAA, - 0xA3, 0x73, 0x10, 0x27, 0x7D, 0x3F, 0xEF, 0x0C, - 0x37, 0xAD, 0x41, 0x76, 0x8F, 0xC2, 0x35, 0xB4 - }, - { - 0x4D, 0x41, 0x39, 0x71, 0x38, 0x7E, 0x7A, 0x88, - 0x98, 0xA8, 0xDC, 0x2A, 0x27, 0x50, 0x07, 0x78, - 0x53, 0x9E, 0xA2, 0x14, 0xA2, 0xDF, 0xE9, 0xB3, - 0xD7, 0xE8, 0xEB, 0xDC, 0xE5, 0xCF, 0x3D, 0xB3 - }, - { - 0x69, 0x6E, 0x5D, 0x46, 0xE6, 0xC5, 0x7E, 0x87, - 0x96, 0xE4, 0x73, 0x5D, 0x08, 0x91, 0x6E, 0x0B, - 0x79, 0x29, 0xB3, 0xCF, 0x29, 0x8C, 0x29, 0x6D, - 0x22, 0xE9, 0xD3, 0x01, 0x96, 0x53, 0x37, 0x1C - }, - { - 0x1F, 0x56, 0x47, 0xC1, 0xD3, 0xB0, 0x88, 0x22, - 0x88, 0x85, 0x86, 0x5C, 0x89, 0x40, 0x90, 0x8B, - 0xF4, 0x0D, 0x1A, 0x82, 0x72, 0x82, 0x19, 0x73, - 0xB1, 0x60, 0x00, 0x8E, 0x7A, 0x3C, 0xE2, 0xEB - }, - { - 0xB6, 0xE7, 0x6C, 0x33, 0x0F, 0x02, 0x1A, 0x5B, - 0xDA, 0x65, 0x87, 0x50, 0x10, 0xB0, 0xED, 0xF0, - 0x91, 0x26, 0xC0, 0xF5, 0x10, 0xEA, 0x84, 0x90, - 0x48, 0x19, 0x20, 0x03, 0xAE, 0xF4, 0xC6, 0x1C - }, - { - 0x3C, 0xD9, 0x52, 0xA0, 0xBE, 0xAD, 0xA4, 0x1A, - 0xBB, 0x42, 0x4C, 0xE4, 0x7F, 0x94, 0xB4, 0x2B, - 0xE6, 0x4E, 0x1F, 0xFB, 0x0F, 0xD0, 0x78, 0x22, - 0x76, 0x80, 0x79, 0x46, 0xD0, 0xD0, 0xBC, 0x55 - }, - { - 0x98, 0xD9, 0x26, 0x77, 0x43, 0x9B, 0x41, 0xB7, - 0xBB, 0x51, 0x33, 0x12, 0xAF, 0xB9, 0x2B, 0xCC, - 0x8E, 0xE9, 0x68, 0xB2, 0xE3, 0xB2, 0x38, 0xCE, - 0xCB, 0x9B, 0x0F, 0x34, 0xC9, 0xBB, 0x63, 0xD0 - }, - { - 0xEC, 0xBC, 0xA2, 0xCF, 0x08, 0xAE, 0x57, 0xD5, - 0x17, 0xAD, 0x16, 0x15, 0x8A, 0x32, 0xBF, 0xA7, - 0xDC, 0x03, 0x82, 0xEA, 0xED, 0xA1, 0x28, 0xE9, - 0x18, 0x86, 0x73, 0x4C, 0x24, 0xA0, 0xB2, 0x9D - }, - { - 0x94, 0x2C, 0xC7, 0xC0, 0xB5, 0x2E, 0x2B, 0x16, - 0xA4, 0xB8, 0x9F, 0xA4, 0xFC, 0x7E, 0x0B, 0xF6, - 0x09, 0xE2, 0x9A, 0x08, 0xC1, 0xA8, 0x54, 0x34, - 0x52, 0xB7, 0x7C, 0x7B, 0xFD, 0x11, 0xBB, 0x28 - }, - { - 0x8A, 0x06, 0x5D, 0x8B, 0x61, 0xA0, 0xDF, 0xFB, - 0x17, 0x0D, 0x56, 0x27, 0x73, 0x5A, 0x76, 0xB0, - 0xE9, 0x50, 0x60, 0x37, 0x80, 0x8C, 0xBA, 0x16, - 0xC3, 0x45, 0x00, 0x7C, 0x9F, 0x79, 0xCF, 0x8F - }, - { - 0x1B, 0x9F, 0xA1, 0x97, 0x14, 0x65, 0x9C, 0x78, - 0xFF, 0x41, 0x38, 0x71, 0x84, 0x92, 0x15, 0x36, - 0x10, 0x29, 0xAC, 0x80, 0x2B, 0x1C, 0xBC, 0xD5, - 0x4E, 0x40, 0x8B, 0xD8, 0x72, 0x87, 0xF8, 0x1F - }, - { - 0x8D, 0xAB, 0x07, 0x1B, 0xCD, 0x6C, 0x72, 0x92, - 0xA9, 0xEF, 0x72, 0x7B, 0x4A, 0xE0, 0xD8, 0x67, - 0x13, 0x30, 0x1D, 0xA8, 0x61, 0x8D, 0x9A, 0x48, - 0xAD, 0xCE, 0x55, 0xF3, 0x03, 0xA8, 0x69, 0xA1 - }, - { - 0x82, 0x53, 0xE3, 0xE7, 0xC7, 0xB6, 0x84, 0xB9, - 0xCB, 0x2B, 0xEB, 0x01, 0x4C, 0xE3, 0x30, 0xFF, - 0x3D, 0x99, 0xD1, 0x7A, 0xBB, 0xDB, 0xAB, 0xE4, - 0xF4, 0xD6, 0x74, 0xDE, 0xD5, 0x3F, 0xFC, 0x6B - }, - { - 0xF1, 0x95, 0xF3, 0x21, 0xE9, 0xE3, 0xD6, 0xBD, - 0x7D, 0x07, 0x45, 0x04, 0xDD, 0x2A, 0xB0, 0xE6, - 0x24, 0x1F, 0x92, 0xE7, 0x84, 0xB1, 0xAA, 0x27, - 0x1F, 0xF6, 0x48, 0xB1, 0xCA, 0xB6, 0xD7, 0xF6 - }, - { - 0x27, 0xE4, 0xCC, 0x72, 0x09, 0x0F, 0x24, 0x12, - 0x66, 0x47, 0x6A, 0x7C, 0x09, 0x49, 0x5F, 0x2D, - 0xB1, 0x53, 0xD5, 0xBC, 0xBD, 0x76, 0x19, 0x03, - 0xEF, 0x79, 0x27, 0x5E, 0xC5, 0x6B, 0x2E, 0xD8 - }, - { - 0x89, 0x9C, 0x24, 0x05, 0x78, 0x8E, 0x25, 0xB9, - 0x9A, 0x18, 0x46, 0x35, 0x5E, 0x64, 0x6D, 0x77, - 0xCF, 0x40, 0x00, 0x83, 0x41, 0x5F, 0x7D, 0xC5, - 0xAF, 0xE6, 0x9D, 0x6E, 0x17, 0xC0, 0x00, 0x23 - }, - { - 0xA5, 0x9B, 0x78, 0xC4, 0x90, 0x57, 0x44, 0x07, - 0x6B, 0xFE, 0xE8, 0x94, 0xDE, 0x70, 0x7D, 0x4F, - 0x12, 0x0B, 0x5C, 0x68, 0x93, 0xEA, 0x04, 0x00, - 0x29, 0x7D, 0x0B, 0xB8, 0x34, 0x72, 0x76, 0x32 - }, - { - 0x59, 0xDC, 0x78, 0xB1, 0x05, 0x64, 0x97, 0x07, - 0xA2, 0xBB, 0x44, 0x19, 0xC4, 0x8F, 0x00, 0x54, - 0x00, 0xD3, 0x97, 0x3D, 0xE3, 0x73, 0x66, 0x10, - 0x23, 0x04, 0x35, 0xB1, 0x04, 0x24, 0xB2, 0x4F - }, - { - 0xC0, 0x14, 0x9D, 0x1D, 0x7E, 0x7A, 0x63, 0x53, - 0xA6, 0xD9, 0x06, 0xEF, 0xE7, 0x28, 0xF2, 0xF3, - 0x29, 0xFE, 0x14, 0xA4, 0x14, 0x9A, 0x3E, 0xA7, - 0x76, 0x09, 0xBC, 0x42, 0xB9, 0x75, 0xDD, 0xFA - }, - { - 0xA3, 0x2F, 0x24, 0x14, 0x74, 0xA6, 0xC1, 0x69, - 0x32, 0xE9, 0x24, 0x3B, 0xE0, 0xCF, 0x09, 0xBC, - 0xDC, 0x7E, 0x0C, 0xA0, 0xE7, 0xA6, 0xA1, 0xB9, - 0xB1, 0xA0, 0xF0, 0x1E, 0x41, 0x50, 0x23, 0x77 - }, - { - 0xB2, 0x39, 0xB2, 0xE4, 0xF8, 0x18, 0x41, 0x36, - 0x1C, 0x13, 0x39, 0xF6, 0x8E, 0x2C, 0x35, 0x9F, - 0x92, 0x9A, 0xF9, 0xAD, 0x9F, 0x34, 0xE0, 0x1A, - 0xAB, 0x46, 0x31, 0xAD, 0x6D, 0x55, 0x00, 0xB0 - }, - { - 0x85, 0xFB, 0x41, 0x9C, 0x70, 0x02, 0xA3, 0xE0, - 0xB4, 0xB6, 0xEA, 0x09, 0x3B, 0x4C, 0x1A, 0xC6, - 0x93, 0x66, 0x45, 0xB6, 0x5D, 0xAC, 0x5A, 0xC1, - 0x5A, 0x85, 0x28, 0xB7, 0xB9, 0x4C, 0x17, 0x54 - }, - { - 0x96, 0x19, 0x72, 0x06, 0x25, 0xF1, 0x90, 0xB9, - 0x3A, 0x3F, 0xAD, 0x18, 0x6A, 0xB3, 0x14, 0x18, - 0x96, 0x33, 0xC0, 0xD3, 0xA0, 0x1E, 0x6F, 0x9B, - 0xC8, 0xC4, 0xA8, 0xF8, 0x2F, 0x38, 0x3D, 0xBF - }, - { - 0x7D, 0x62, 0x0D, 0x90, 0xFE, 0x69, 0xFA, 0x46, - 0x9A, 0x65, 0x38, 0x38, 0x89, 0x70, 0xA1, 0xAA, - 0x09, 0xBB, 0x48, 0xA2, 0xD5, 0x9B, 0x34, 0x7B, - 0x97, 0xE8, 0xCE, 0x71, 0xF4, 0x8C, 0x7F, 0x46 - }, - { - 0x29, 0x43, 0x83, 0x56, 0x85, 0x96, 0xFB, 0x37, - 0xC7, 0x5B, 0xBA, 0xCD, 0x97, 0x9C, 0x5F, 0xF6, - 0xF2, 0x0A, 0x55, 0x6B, 0xF8, 0x87, 0x9C, 0xC7, - 0x29, 0x24, 0x85, 0x5D, 0xF9, 0xB8, 0x24, 0x0E - }, - { - 0x16, 0xB1, 0x8A, 0xB3, 0x14, 0x35, 0x9C, 0x2B, - 0x83, 0x3C, 0x1C, 0x69, 0x86, 0xD4, 0x8C, 0x55, - 0xA9, 0xFC, 0x97, 0xCD, 0xE9, 0xA3, 0xC1, 0xF1, - 0x0A, 0x31, 0x77, 0x14, 0x0F, 0x73, 0xF7, 0x38 - }, - { - 0x8C, 0xBB, 0xDD, 0x14, 0xBC, 0x33, 0xF0, 0x4C, - 0xF4, 0x58, 0x13, 0xE4, 0xA1, 0x53, 0xA2, 0x73, - 0xD3, 0x6A, 0xDA, 0xD5, 0xCE, 0x71, 0xF4, 0x99, - 0xEE, 0xB8, 0x7F, 0xB8, 0xAC, 0x63, 0xB7, 0x29 - }, - { - 0x69, 0xC9, 0xA4, 0x98, 0xDB, 0x17, 0x4E, 0xCA, - 0xEF, 0xCC, 0x5A, 0x3A, 0xC9, 0xFD, 0xED, 0xF0, - 0xF8, 0x13, 0xA5, 0xBE, 0xC7, 0x27, 0xF1, 0xE7, - 0x75, 0xBA, 0xBD, 0xEC, 0x77, 0x18, 0x81, 0x6E - }, - { - 0xB4, 0x62, 0xC3, 0xBE, 0x40, 0x44, 0x8F, 0x1D, - 0x4F, 0x80, 0x62, 0x62, 0x54, 0xE5, 0x35, 0xB0, - 0x8B, 0xC9, 0xCD, 0xCF, 0xF5, 0x99, 0xA7, 0x68, - 0x57, 0x8D, 0x4B, 0x28, 0x81, 0xA8, 0xE3, 0xF0 - }, - { - 0x55, 0x3E, 0x9D, 0x9C, 0x5F, 0x36, 0x0A, 0xC0, - 0xB7, 0x4A, 0x7D, 0x44, 0xE5, 0xA3, 0x91, 0xDA, - 0xD4, 0xCE, 0xD0, 0x3E, 0x0C, 0x24, 0x18, 0x3B, - 0x7E, 0x8E, 0xCA, 0xBD, 0xF1, 0x71, 0x5A, 0x64 - }, - { - 0x7A, 0x7C, 0x55, 0xA5, 0x6F, 0xA9, 0xAE, 0x51, - 0xE6, 0x55, 0xE0, 0x19, 0x75, 0xD8, 0xA6, 0xFF, - 0x4A, 0xE9, 0xE4, 0xB4, 0x86, 0xFC, 0xBE, 0x4E, - 0xAC, 0x04, 0x45, 0x88, 0xF2, 0x45, 0xEB, 0xEA - }, - { - 0x2A, 0xFD, 0xF3, 0xC8, 0x2A, 0xBC, 0x48, 0x67, - 0xF5, 0xDE, 0x11, 0x12, 0x86, 0xC2, 0xB3, 0xBE, - 0x7D, 0x6E, 0x48, 0x65, 0x7B, 0xA9, 0x23, 0xCF, - 0xBF, 0x10, 0x1A, 0x6D, 0xFC, 0xF9, 0xDB, 0x9A - }, - { - 0x41, 0x03, 0x7D, 0x2E, 0xDC, 0xDC, 0xE0, 0xC4, - 0x9B, 0x7F, 0xB4, 0xA6, 0xAA, 0x09, 0x99, 0xCA, - 0x66, 0x97, 0x6C, 0x74, 0x83, 0xAF, 0xE6, 0x31, - 0xD4, 0xED, 0xA2, 0x83, 0x14, 0x4F, 0x6D, 0xFC - }, - { - 0xC4, 0x46, 0x6F, 0x84, 0x97, 0xCA, 0x2E, 0xEB, - 0x45, 0x83, 0xA0, 0xB0, 0x8E, 0x9D, 0x9A, 0xC7, - 0x43, 0x95, 0x70, 0x9F, 0xDA, 0x10, 0x9D, 0x24, - 0xF2, 0xE4, 0x46, 0x21, 0x96, 0x77, 0x9C, 0x5D - }, - { - 0x75, 0xF6, 0x09, 0x33, 0x8A, 0xA6, 0x7D, 0x96, - 0x9A, 0x2A, 0xE2, 0xA2, 0x36, 0x2B, 0x2D, 0xA9, - 0xD7, 0x7C, 0x69, 0x5D, 0xFD, 0x1D, 0xF7, 0x22, - 0x4A, 0x69, 0x01, 0xDB, 0x93, 0x2C, 0x33, 0x64 - }, - { - 0x68, 0x60, 0x6C, 0xEB, 0x98, 0x9D, 0x54, 0x88, - 0xFC, 0x7C, 0xF6, 0x49, 0xF3, 0xD7, 0xC2, 0x72, - 0xEF, 0x05, 0x5D, 0xA1, 0xA9, 0x3F, 0xAE, 0xCD, - 0x55, 0xFE, 0x06, 0xF6, 0x96, 0x70, 0x98, 0xCA - }, - { - 0x44, 0x34, 0x6B, 0xDE, 0xB7, 0xE0, 0x52, 0xF6, - 0x25, 0x50, 0x48, 0xF0, 0xD9, 0xB4, 0x2C, 0x42, - 0x5B, 0xAB, 0x9C, 0x3D, 0xD2, 0x41, 0x68, 0x21, - 0x2C, 0x3E, 0xCF, 0x1E, 0xBF, 0x34, 0xE6, 0xAE - }, - { - 0x8E, 0x9C, 0xF6, 0xE1, 0xF3, 0x66, 0x47, 0x1F, - 0x2A, 0xC7, 0xD2, 0xEE, 0x9B, 0x5E, 0x62, 0x66, - 0xFD, 0xA7, 0x1F, 0x8F, 0x2E, 0x41, 0x09, 0xF2, - 0x23, 0x7E, 0xD5, 0xF8, 0x81, 0x3F, 0xC7, 0x18 - }, - { - 0x84, 0xBB, 0xEB, 0x84, 0x06, 0xD2, 0x50, 0x95, - 0x1F, 0x8C, 0x1B, 0x3E, 0x86, 0xA7, 0xC0, 0x10, - 0x08, 0x29, 0x21, 0x83, 0x3D, 0xFD, 0x95, 0x55, - 0xA2, 0xF9, 0x09, 0xB1, 0x08, 0x6E, 0xB4, 0xB8 - }, - { - 0xEE, 0x66, 0x6F, 0x3E, 0xEF, 0x0F, 0x7E, 0x2A, - 0x9C, 0x22, 0x29, 0x58, 0xC9, 0x7E, 0xAF, 0x35, - 0xF5, 0x1C, 0xED, 0x39, 0x3D, 0x71, 0x44, 0x85, - 0xAB, 0x09, 0xA0, 0x69, 0x34, 0x0F, 0xDF, 0x88 - }, - { - 0xC1, 0x53, 0xD3, 0x4A, 0x65, 0xC4, 0x7B, 0x4A, - 0x62, 0xC5, 0xCA, 0xCF, 0x24, 0x01, 0x09, 0x75, - 0xD0, 0x35, 0x6B, 0x2F, 0x32, 0xC8, 0xF5, 0xDA, - 0x53, 0x0D, 0x33, 0x88, 0x16, 0xAD, 0x5D, 0xE6 - }, - { - 0x9F, 0xC5, 0x45, 0x01, 0x09, 0xE1, 0xB7, 0x79, - 0xF6, 0xC7, 0xAE, 0x79, 0xD5, 0x6C, 0x27, 0x63, - 0x5C, 0x8D, 0xD4, 0x26, 0xC5, 0xA9, 0xD5, 0x4E, - 0x25, 0x78, 0xDB, 0x98, 0x9B, 0x8C, 0x3B, 0x4E - }, - { - 0xD1, 0x2B, 0xF3, 0x73, 0x2E, 0xF4, 0xAF, 0x5C, - 0x22, 0xFA, 0x90, 0x35, 0x6A, 0xF8, 0xFC, 0x50, - 0xFC, 0xB4, 0x0F, 0x8F, 0x2E, 0xA5, 0xC8, 0x59, - 0x47, 0x37, 0xA3, 0xB3, 0xD5, 0xAB, 0xDB, 0xD7 - }, - { - 0x11, 0x03, 0x0B, 0x92, 0x89, 0xBB, 0xA5, 0xAF, - 0x65, 0x26, 0x06, 0x72, 0xAB, 0x6F, 0xEE, 0x88, - 0xB8, 0x74, 0x20, 0xAC, 0xEF, 0x4A, 0x17, 0x89, - 0xA2, 0x07, 0x3B, 0x7E, 0xC2, 0xF2, 0xA0, 0x9E - }, - { - 0x69, 0xCB, 0x19, 0x2B, 0x84, 0x44, 0x00, 0x5C, - 0x8C, 0x0C, 0xEB, 0x12, 0xC8, 0x46, 0x86, 0x07, - 0x68, 0x18, 0x8C, 0xDA, 0x0A, 0xEC, 0x27, 0xA9, - 0xC8, 0xA5, 0x5C, 0xDE, 0xE2, 0x12, 0x36, 0x32 - }, - { - 0xDB, 0x44, 0x4C, 0x15, 0x59, 0x7B, 0x5F, 0x1A, - 0x03, 0xD1, 0xF9, 0xED, 0xD1, 0x6E, 0x4A, 0x9F, - 0x43, 0xA6, 0x67, 0xCC, 0x27, 0x51, 0x75, 0xDF, - 0xA2, 0xB7, 0x04, 0xE3, 0xBB, 0x1A, 0x9B, 0x83 - }, - { - 0x3F, 0xB7, 0x35, 0x06, 0x1A, 0xBC, 0x51, 0x9D, - 0xFE, 0x97, 0x9E, 0x54, 0xC1, 0xEE, 0x5B, 0xFA, - 0xD0, 0xA9, 0xD8, 0x58, 0xB3, 0x31, 0x5B, 0xAD, - 0x34, 0xBD, 0xE9, 0x99, 0xEF, 0xD7, 0x24, 0xDD - }, -}; - - - - -static const uint8_t blake2b_kat[KAT_LENGTH][BLAKE2B_OUTBYTES] = -{ - { - 0x78, 0x6A, 0x02, 0xF7, 0x42, 0x01, 0x59, 0x03, - 0xC6, 0xC6, 0xFD, 0x85, 0x25, 0x52, 0xD2, 0x72, - 0x91, 0x2F, 0x47, 0x40, 0xE1, 0x58, 0x47, 0x61, - 0x8A, 0x86, 0xE2, 0x17, 0xF7, 0x1F, 0x54, 0x19, - 0xD2, 0x5E, 0x10, 0x31, 0xAF, 0xEE, 0x58, 0x53, - 0x13, 0x89, 0x64, 0x44, 0x93, 0x4E, 0xB0, 0x4B, - 0x90, 0x3A, 0x68, 0x5B, 0x14, 0x48, 0xB7, 0x55, - 0xD5, 0x6F, 0x70, 0x1A, 0xFE, 0x9B, 0xE2, 0xCE - }, - { - 0x2F, 0xA3, 0xF6, 0x86, 0xDF, 0x87, 0x69, 0x95, - 0x16, 0x7E, 0x7C, 0x2E, 0x5D, 0x74, 0xC4, 0xC7, - 0xB6, 0xE4, 0x8F, 0x80, 0x68, 0xFE, 0x0E, 0x44, - 0x20, 0x83, 0x44, 0xD4, 0x80, 0xF7, 0x90, 0x4C, - 0x36, 0x96, 0x3E, 0x44, 0x11, 0x5F, 0xE3, 0xEB, - 0x2A, 0x3A, 0xC8, 0x69, 0x4C, 0x28, 0xBC, 0xB4, - 0xF5, 0xA0, 0xF3, 0x27, 0x6F, 0x2E, 0x79, 0x48, - 0x7D, 0x82, 0x19, 0x05, 0x7A, 0x50, 0x6E, 0x4B - }, - { - 0x1C, 0x08, 0x79, 0x8D, 0xC6, 0x41, 0xAB, 0xA9, - 0xDE, 0xE4, 0x35, 0xE2, 0x25, 0x19, 0xA4, 0x72, - 0x9A, 0x09, 0xB2, 0xBF, 0xE0, 0xFF, 0x00, 0xEF, - 0x2D, 0xCD, 0x8E, 0xD6, 0xF8, 0xA0, 0x7D, 0x15, - 0xEA, 0xF4, 0xAE, 0xE5, 0x2B, 0xBF, 0x18, 0xAB, - 0x56, 0x08, 0xA6, 0x19, 0x0F, 0x70, 0xB9, 0x04, - 0x86, 0xC8, 0xA7, 0xD4, 0x87, 0x37, 0x10, 0xB1, - 0x11, 0x5D, 0x3D, 0xEB, 0xBB, 0x43, 0x27, 0xB5 - }, - { - 0x40, 0xA3, 0x74, 0x72, 0x73, 0x02, 0xD9, 0xA4, - 0x76, 0x9C, 0x17, 0xB5, 0xF4, 0x09, 0xFF, 0x32, - 0xF5, 0x8A, 0xA2, 0x4F, 0xF1, 0x22, 0xD7, 0x60, - 0x3E, 0x4F, 0xDA, 0x15, 0x09, 0xE9, 0x19, 0xD4, - 0x10, 0x7A, 0x52, 0xC5, 0x75, 0x70, 0xA6, 0xD9, - 0x4E, 0x50, 0x96, 0x7A, 0xEA, 0x57, 0x3B, 0x11, - 0xF8, 0x6F, 0x47, 0x3F, 0x53, 0x75, 0x65, 0xC6, - 0x6F, 0x70, 0x39, 0x83, 0x0A, 0x85, 0xD1, 0x86 - }, - { - 0x77, 0xDD, 0xF4, 0xB1, 0x44, 0x25, 0xEB, 0x3D, - 0x05, 0x3C, 0x1E, 0x84, 0xE3, 0x46, 0x9D, 0x92, - 0xC4, 0xCD, 0x91, 0x0E, 0xD2, 0x0F, 0x92, 0x03, - 0x5E, 0x0C, 0x99, 0xD8, 0xA7, 0xA8, 0x6C, 0xEC, - 0xAF, 0x69, 0xF9, 0x66, 0x3C, 0x20, 0xA7, 0xAA, - 0x23, 0x0B, 0xC8, 0x2F, 0x60, 0xD2, 0x2F, 0xB4, - 0xA0, 0x0B, 0x09, 0xD3, 0xEB, 0x8F, 0xC6, 0x5E, - 0xF5, 0x47, 0xFE, 0x63, 0xC8, 0xD3, 0xDD, 0xCE - }, - { - 0xCB, 0xAA, 0x0B, 0xA7, 0xD4, 0x82, 0xB1, 0xF3, - 0x01, 0x10, 0x9A, 0xE4, 0x10, 0x51, 0x99, 0x1A, - 0x32, 0x89, 0xBC, 0x11, 0x98, 0x00, 0x5A, 0xF2, - 0x26, 0xC5, 0xE4, 0xF1, 0x03, 0xB6, 0x65, 0x79, - 0xF4, 0x61, 0x36, 0x10, 0x44, 0xC8, 0xBA, 0x34, - 0x39, 0xFF, 0x12, 0xC5, 0x15, 0xFB, 0x29, 0xC5, - 0x21, 0x61, 0xB7, 0xEB, 0x9C, 0x28, 0x37, 0xB7, - 0x6A, 0x5D, 0xC3, 0x3F, 0x7C, 0xB2, 0xE2, 0xE8 - }, - { - 0xF9, 0x5D, 0x45, 0xCF, 0x69, 0xAF, 0x5C, 0x20, - 0x23, 0xBD, 0xB5, 0x05, 0x82, 0x1E, 0x62, 0xE8, - 0x5D, 0x7C, 0xAE, 0xDF, 0x7B, 0xED, 0xA1, 0x2C, - 0x02, 0x48, 0x77, 0x5B, 0x0C, 0x88, 0x20, 0x5E, - 0xEB, 0x35, 0xAF, 0x3A, 0x90, 0x81, 0x6F, 0x66, - 0x08, 0xCE, 0x7D, 0xD4, 0x4E, 0xC2, 0x8D, 0xB1, - 0x14, 0x06, 0x14, 0xE1, 0xDD, 0xEB, 0xF3, 0xAA, - 0x9C, 0xD1, 0x84, 0x3E, 0x0F, 0xAD, 0x2C, 0x36 - }, - { - 0x8F, 0x94, 0x5B, 0xA7, 0x00, 0xF2, 0x53, 0x0E, - 0x5C, 0x2A, 0x7D, 0xF7, 0xD5, 0xDC, 0xE0, 0xF8, - 0x3F, 0x9E, 0xFC, 0x78, 0xC0, 0x73, 0xFE, 0x71, - 0xAE, 0x1F, 0x88, 0x20, 0x4A, 0x4F, 0xD1, 0xCF, - 0x70, 0xA0, 0x73, 0xF5, 0xD1, 0xF9, 0x42, 0xED, - 0x62, 0x3A, 0xA1, 0x6E, 0x90, 0xA8, 0x71, 0x24, - 0x6C, 0x90, 0xC4, 0x5B, 0x62, 0x1B, 0x34, 0x01, - 0xA5, 0xDD, 0xBD, 0x9D, 0xF6, 0x26, 0x41, 0x65 - }, - { - 0xE9, 0x98, 0xE0, 0xDC, 0x03, 0xEC, 0x30, 0xEB, - 0x99, 0xBB, 0x6B, 0xFA, 0xAF, 0x66, 0x18, 0xAC, - 0xC6, 0x20, 0x32, 0x0D, 0x72, 0x20, 0xB3, 0xAF, - 0x2B, 0x23, 0xD1, 0x12, 0xD8, 0xE9, 0xCB, 0x12, - 0x62, 0xF3, 0xC0, 0xD6, 0x0D, 0x18, 0x3B, 0x1E, - 0xE7, 0xF0, 0x96, 0xD1, 0x2D, 0xAE, 0x42, 0xC9, - 0x58, 0x41, 0x86, 0x00, 0x21, 0x4D, 0x04, 0xF5, - 0xED, 0x6F, 0x5E, 0x71, 0x8B, 0xE3, 0x55, 0x66 - }, - { - 0x6A, 0x9A, 0x09, 0x0C, 0x61, 0xB3, 0x41, 0x0A, - 0xED, 0xE7, 0xEC, 0x91, 0x38, 0x14, 0x6C, 0xEB, - 0x2C, 0x69, 0x66, 0x2F, 0x46, 0x0C, 0x3D, 0xA5, - 0x3C, 0x65, 0x15, 0xC1, 0xEB, 0x31, 0xF4, 0x1C, - 0xA3, 0xD2, 0x80, 0xE5, 0x67, 0x88, 0x2F, 0x95, - 0xCF, 0x66, 0x4A, 0x94, 0x14, 0x7D, 0x78, 0xF4, - 0x2C, 0xFC, 0x71, 0x4A, 0x40, 0xD2, 0x2E, 0xF1, - 0x94, 0x70, 0xE0, 0x53, 0x49, 0x35, 0x08, 0xA2 - }, - { - 0x29, 0x10, 0x25, 0x11, 0xD7, 0x49, 0xDB, 0x3C, - 0xC9, 0xB4, 0xE3, 0x35, 0xFA, 0x1F, 0x5E, 0x8F, - 0xAC, 0xA8, 0x42, 0x1D, 0x55, 0x8F, 0x6A, 0x3F, - 0x33, 0x21, 0xD5, 0x0D, 0x04, 0x4A, 0x24, 0x8B, - 0xA5, 0x95, 0xCF, 0xC3, 0xEF, 0xD3, 0xD2, 0xAD, - 0xC9, 0x73, 0x34, 0xDA, 0x73, 0x24, 0x13, 0xF5, - 0xCB, 0xF4, 0x75, 0x1C, 0x36, 0x2B, 0xA1, 0xD5, - 0x38, 0x62, 0xAC, 0x1E, 0x8D, 0xAB, 0xEE, 0xE8 - }, - { - 0xC9, 0x7A, 0x47, 0x79, 0xD4, 0x7E, 0x6F, 0x77, - 0x72, 0x9B, 0x59, 0x17, 0xD0, 0x13, 0x8A, 0xBB, - 0x35, 0x98, 0x0A, 0xB6, 0x41, 0xBD, 0x73, 0xA8, - 0x85, 0x9E, 0xB1, 0xAC, 0x98, 0xC0, 0x53, 0x62, - 0xED, 0x7D, 0x60, 0x8F, 0x2E, 0x95, 0x87, 0xD6, - 0xBA, 0x9E, 0x27, 0x1D, 0x34, 0x31, 0x25, 0xD4, - 0x0D, 0x93, 0x3A, 0x8E, 0xD0, 0x4E, 0xC1, 0xFE, - 0x75, 0xEC, 0x40, 0x7C, 0x7A, 0x53, 0xC3, 0x4E - }, - { - 0x10, 0xF0, 0xDC, 0x91, 0xB9, 0xF8, 0x45, 0xFB, - 0x95, 0xFA, 0xD6, 0x86, 0x0E, 0x6C, 0xE1, 0xAD, - 0xFA, 0x00, 0x2C, 0x7F, 0xC3, 0x27, 0x11, 0x6D, - 0x44, 0xD0, 0x47, 0xCD, 0x7D, 0x58, 0x70, 0xD7, - 0x72, 0xBB, 0x12, 0xB5, 0xFA, 0xC0, 0x0E, 0x02, - 0xB0, 0x8A, 0xC2, 0xA0, 0x17, 0x4D, 0x04, 0x46, - 0xC3, 0x6A, 0xB3, 0x5F, 0x14, 0xCA, 0x31, 0x89, - 0x4C, 0xD6, 0x1C, 0x78, 0xC8, 0x49, 0xB4, 0x8A - }, - { - 0xDE, 0xA9, 0x10, 0x1C, 0xAC, 0x62, 0xB8, 0xF6, - 0xA3, 0xC6, 0x50, 0xF9, 0x0E, 0xEA, 0x5B, 0xFA, - 0xE2, 0x65, 0x3A, 0x4E, 0xAF, 0xD6, 0x3A, 0x6D, - 0x1F, 0x0F, 0x13, 0x2D, 0xB9, 0xE4, 0xF2, 0xB1, - 0xB6, 0x62, 0x43, 0x2E, 0xC8, 0x5B, 0x17, 0xBC, - 0xAC, 0x41, 0xE7, 0x75, 0x63, 0x78, 0x81, 0xF6, - 0xAA, 0xB3, 0x8D, 0xD6, 0x6D, 0xCB, 0xD0, 0x80, - 0xF0, 0x99, 0x0A, 0x7A, 0x6E, 0x98, 0x54, 0xFE - }, - { - 0x44, 0x1F, 0xFA, 0xA0, 0x8C, 0xD7, 0x9D, 0xFF, - 0x4A, 0xFC, 0x9B, 0x9E, 0x5B, 0x56, 0x20, 0xEE, - 0xC0, 0x86, 0x73, 0x0C, 0x25, 0xF6, 0x61, 0xB1, - 0xD6, 0xFB, 0xFB, 0xD1, 0xCE, 0xC3, 0x14, 0x8D, - 0xD7, 0x22, 0x58, 0xC6, 0x56, 0x41, 0xF2, 0xFC, - 0xA5, 0xEB, 0x15, 0x5F, 0xAD, 0xBC, 0xAB, 0xB1, - 0x3C, 0x6E, 0x21, 0xDC, 0x11, 0xFA, 0xF7, 0x2C, - 0x2A, 0x28, 0x1B, 0x7D, 0x56, 0x14, 0x5F, 0x19 - }, - { - 0x44, 0x4B, 0x24, 0x0F, 0xE3, 0xED, 0x86, 0xD0, - 0xE2, 0xEF, 0x4C, 0xE7, 0xD8, 0x51, 0xED, 0xDE, - 0x22, 0x15, 0x55, 0x82, 0xAA, 0x09, 0x14, 0x79, - 0x7B, 0x72, 0x6C, 0xD0, 0x58, 0xB6, 0xF4, 0x59, - 0x32, 0xE0, 0xE1, 0x29, 0x51, 0x68, 0x76, 0x52, - 0x7B, 0x1D, 0xD8, 0x8F, 0xC6, 0x6D, 0x71, 0x19, - 0xF4, 0xAB, 0x3B, 0xED, 0x93, 0xA6, 0x1A, 0x0E, - 0x2D, 0x2D, 0x2A, 0xEA, 0xC3, 0x36, 0xD9, 0x58 - }, - { - 0xBF, 0xBA, 0xBB, 0xEF, 0x45, 0x55, 0x4C, 0xCF, - 0xA0, 0xDC, 0x83, 0x75, 0x2A, 0x19, 0xCC, 0x35, - 0xD5, 0x92, 0x09, 0x56, 0xB3, 0x01, 0xD5, 0x58, - 0xD7, 0x72, 0x28, 0x2B, 0xC8, 0x67, 0x00, 0x91, - 0x68, 0xE9, 0xE9, 0x86, 0x06, 0xBB, 0x5B, 0xA7, - 0x3A, 0x38, 0x5D, 0xE5, 0x74, 0x92, 0x28, 0xC9, - 0x25, 0xA8, 0x50, 0x19, 0xB7, 0x1F, 0x72, 0xFE, - 0x29, 0xB3, 0xCD, 0x37, 0xCA, 0x52, 0xEF, 0xE6 - }, - { - 0x9C, 0x4D, 0x0C, 0x3E, 0x1C, 0xDB, 0xBF, 0x48, - 0x5B, 0xEC, 0x86, 0xF4, 0x1C, 0xEC, 0x7C, 0x98, - 0x37, 0x3F, 0x0E, 0x09, 0xF3, 0x92, 0x84, 0x9A, - 0xAA, 0x22, 0x9E, 0xBF, 0xBF, 0x39, 0x7B, 0x22, - 0x08, 0x55, 0x29, 0xCB, 0x7E, 0xF3, 0x9F, 0x9C, - 0x7C, 0x22, 0x22, 0xA5, 0x14, 0x18, 0x2B, 0x1E, - 0xFF, 0xAA, 0x17, 0x8C, 0xC3, 0x68, 0x7B, 0x1B, - 0x2B, 0x6C, 0xBC, 0xB6, 0xFD, 0xEB, 0x96, 0xF8 - }, - { - 0x47, 0x71, 0x76, 0xB3, 0xBF, 0xCB, 0xAD, 0xD7, - 0x65, 0x7C, 0x23, 0xC2, 0x46, 0x25, 0xE4, 0xD0, - 0xD6, 0x74, 0xD1, 0x86, 0x8F, 0x00, 0x60, 0x06, - 0x39, 0x8A, 0xF9, 0x7A, 0xA4, 0x18, 0x77, 0xC8, - 0xE7, 0x0D, 0x3D, 0x14, 0xC3, 0xBB, 0xC9, 0xBB, - 0xCD, 0xCE, 0xA8, 0x01, 0xBD, 0x0E, 0x15, 0x99, - 0xAF, 0x1F, 0x3E, 0xEC, 0x67, 0x40, 0x51, 0x70, - 0xF4, 0xE2, 0x6C, 0x96, 0x4A, 0x57, 0xA8, 0xB7 - }, - { - 0xA7, 0x8C, 0x49, 0x0E, 0xDA, 0x31, 0x73, 0xBB, - 0x3F, 0x10, 0xDE, 0xE5, 0x2F, 0x11, 0x0F, 0xB1, - 0xC0, 0x8E, 0x03, 0x02, 0x23, 0x0B, 0x85, 0xDD, - 0xD7, 0xC1, 0x12, 0x57, 0xD9, 0x2D, 0xE1, 0x48, - 0x78, 0x5E, 0xF0, 0x0C, 0x03, 0x9C, 0x0B, 0xB8, - 0xEB, 0x98, 0x08, 0xA3, 0x5B, 0x2D, 0x8C, 0x08, - 0x0F, 0x57, 0x28, 0x59, 0x71, 0x4C, 0x9D, 0x40, - 0x69, 0xC5, 0xBC, 0xAF, 0x09, 0x0E, 0x89, 0x8E - }, - { - 0x58, 0xD0, 0x23, 0x39, 0x7B, 0xEB, 0x5B, 0x41, - 0x45, 0xCB, 0x22, 0x55, 0xB0, 0x7D, 0x74, 0x29, - 0x0B, 0x36, 0xD9, 0xFD, 0x1E, 0x59, 0x4A, 0xFB, - 0xD8, 0xEE, 0xA4, 0x7C, 0x20, 0x5B, 0x2E, 0xFB, - 0xFE, 0x6F, 0x46, 0x19, 0x0F, 0xAF, 0x95, 0xAF, - 0x50, 0x4A, 0xB0, 0x72, 0xE3, 0x6F, 0x6C, 0x85, - 0xD7, 0x67, 0xA3, 0x21, 0xBF, 0xD7, 0xF2, 0x26, - 0x87, 0xA4, 0xAB, 0xBF, 0x49, 0x4A, 0x68, 0x9C - }, - { - 0x40, 0x01, 0xEC, 0x74, 0xD5, 0xA4, 0x6F, 0xD2, - 0x9C, 0x2C, 0x3C, 0xDB, 0xE5, 0xD1, 0xB9, 0xF2, - 0x0E, 0x51, 0xA9, 0x41, 0xBE, 0x98, 0xD2, 0xA4, - 0xE1, 0xE2, 0xFB, 0xF8, 0x66, 0xA6, 0x72, 0x12, - 0x1D, 0xB6, 0xF8, 0x1A, 0x51, 0x4C, 0xFD, 0x10, - 0xE7, 0x35, 0x8D, 0x57, 0x1B, 0xDB, 0xA4, 0x8E, - 0x4C, 0xE7, 0x08, 0xB9, 0xD1, 0x24, 0x89, 0x4B, - 0xC0, 0xB5, 0xED, 0x55, 0x49, 0x35, 0xF7, 0x3A - }, - { - 0xCC, 0xD1, 0xB2, 0x2D, 0xAB, 0x65, 0x11, 0x22, - 0x5D, 0x24, 0x01, 0xEA, 0x2D, 0x86, 0x25, 0xD2, - 0x06, 0xA1, 0x24, 0x73, 0xCC, 0x73, 0x2B, 0x61, - 0x5E, 0x56, 0x40, 0xCE, 0xFF, 0xF0, 0xA4, 0xAD, - 0xF9, 0x71, 0xB0, 0xE8, 0x27, 0xA6, 0x19, 0xE0, - 0xA8, 0x0F, 0x5D, 0xB9, 0xCC, 0xD0, 0x96, 0x23, - 0x29, 0x01, 0x0D, 0x07, 0xE3, 0x4A, 0x20, 0x64, - 0xE7, 0x31, 0xC5, 0x20, 0x81, 0x7B, 0x21, 0x83 - }, - { - 0xB4, 0xA0, 0xA9, 0xE3, 0x57, 0x4E, 0xDB, 0x9E, - 0x1E, 0x72, 0xAA, 0x31, 0xE3, 0x9C, 0xC5, 0xF3, - 0x0D, 0xBF, 0x94, 0x3F, 0x8C, 0xAB, 0xC4, 0x08, - 0x44, 0x96, 0x54, 0xA3, 0x91, 0x31, 0xE6, 0x6D, - 0x71, 0x8A, 0x18, 0x81, 0x91, 0x43, 0xE3, 0xEA, - 0x96, 0xB4, 0xA1, 0x89, 0x59, 0x88, 0xA1, 0xC0, - 0x05, 0x6C, 0xF2, 0xB6, 0xE0, 0x4F, 0x9A, 0xC1, - 0x9D, 0x65, 0x73, 0x83, 0xC2, 0x91, 0x0C, 0x44 - }, - { - 0x44, 0x7B, 0xEC, 0xAB, 0x16, 0x63, 0x06, 0x08, - 0xD3, 0x9F, 0x4F, 0x05, 0x8B, 0x16, 0xF7, 0xAF, - 0x95, 0xB8, 0x5A, 0x76, 0xAA, 0x0F, 0xA7, 0xCE, - 0xA2, 0xB8, 0x07, 0x55, 0xFB, 0x76, 0xE9, 0xC8, - 0x04, 0xF2, 0xCA, 0x78, 0xF0, 0x26, 0x43, 0xC9, - 0x15, 0xFB, 0xF2, 0xFC, 0xE5, 0xE1, 0x9D, 0xE8, - 0x60, 0x00, 0xDE, 0x03, 0xB1, 0x88, 0x61, 0x81, - 0x5A, 0x83, 0x12, 0x60, 0x71, 0xF8, 0xA3, 0x7B - }, - { - 0x54, 0xE6, 0xDA, 0xB9, 0x97, 0x73, 0x80, 0xA5, - 0x66, 0x58, 0x22, 0xDB, 0x93, 0x37, 0x4E, 0xDA, - 0x52, 0x8D, 0x9B, 0xEB, 0x62, 0x6F, 0x9B, 0x94, - 0x02, 0x70, 0x71, 0xCB, 0x26, 0x67, 0x5E, 0x11, - 0x2B, 0x4A, 0x7F, 0xEC, 0x94, 0x1E, 0xE6, 0x0A, - 0x81, 0xE4, 0xD2, 0xEA, 0x3F, 0xF7, 0xBC, 0x52, - 0xCF, 0xC4, 0x5D, 0xFB, 0xFE, 0x73, 0x5A, 0x1C, - 0x64, 0x6B, 0x2C, 0xF6, 0xD6, 0xA4, 0x9B, 0x62 - }, - { - 0x3E, 0xA6, 0x26, 0x25, 0x94, 0x9E, 0x36, 0x46, - 0x70, 0x4D, 0x7E, 0x3C, 0x90, 0x6F, 0x82, 0xF6, - 0xC0, 0x28, 0xF5, 0x40, 0xF5, 0xF7, 0x2A, 0x79, - 0x4B, 0x0C, 0x57, 0xBF, 0x97, 0xB7, 0x64, 0x9B, - 0xFE, 0xB9, 0x0B, 0x01, 0xD3, 0xCA, 0x3E, 0x82, - 0x9D, 0xE2, 0x1B, 0x38, 0x26, 0xE6, 0xF8, 0x70, - 0x14, 0xD3, 0xC7, 0x73, 0x50, 0xCB, 0x5A, 0x15, - 0xFF, 0x5D, 0x46, 0x8A, 0x81, 0xBE, 0xC1, 0x60 - }, - { - 0x21, 0x3C, 0xFE, 0x14, 0x5C, 0x54, 0xA3, 0x36, - 0x91, 0x56, 0x99, 0x80, 0xE5, 0x93, 0x8C, 0x88, - 0x83, 0xA4, 0x6D, 0x84, 0xD1, 0x49, 0xC8, 0xFF, - 0x1A, 0x67, 0xCD, 0x28, 0x7B, 0x4D, 0x49, 0xC6, - 0xDA, 0x69, 0xD3, 0xA0, 0x35, 0x44, 0x3D, 0xB0, - 0x85, 0x98, 0x3D, 0x0E, 0xFE, 0x63, 0x70, 0x6B, - 0xD5, 0xB6, 0xF1, 0x5A, 0x7D, 0xA4, 0x59, 0xE8, - 0xD5, 0x0A, 0x19, 0x09, 0x3D, 0xB5, 0x5E, 0x80 - }, - { - 0x57, 0x16, 0xC4, 0xA3, 0x8F, 0x38, 0xDB, 0x10, - 0x4E, 0x49, 0x4A, 0x0A, 0x27, 0xCB, 0xE8, 0x9A, - 0x26, 0xA6, 0xBB, 0x6F, 0x49, 0x9E, 0xC0, 0x1C, - 0x8C, 0x01, 0xAA, 0x7C, 0xB8, 0x84, 0x97, 0xE7, - 0x51, 0x48, 0xCD, 0x6E, 0xEE, 0x12, 0xA7, 0x16, - 0x8B, 0x6F, 0x78, 0xAB, 0x74, 0xE4, 0xBE, 0x74, - 0x92, 0x51, 0xA1, 0xA7, 0x4C, 0x38, 0xC8, 0x6D, - 0x61, 0x29, 0x17, 0x7E, 0x28, 0x89, 0xE0, 0xB6 - }, - { - 0x03, 0x04, 0x60, 0xA9, 0x8B, 0xDF, 0x9F, 0xF1, - 0x7C, 0xD9, 0x64, 0x04, 0xF2, 0x8F, 0xC3, 0x04, - 0xF2, 0xB7, 0xC0, 0x4E, 0xAA, 0xDE, 0x53, 0x67, - 0x7F, 0xD2, 0x8F, 0x78, 0x8C, 0xA2, 0x21, 0x86, - 0xB8, 0xBC, 0x80, 0xDD, 0x21, 0xD1, 0x7F, 0x85, - 0x49, 0xC7, 0x11, 0xAF, 0xF0, 0xE5, 0x14, 0xE1, - 0x9D, 0x4E, 0x15, 0xF5, 0x99, 0x02, 0x52, 0xA0, - 0x3E, 0x08, 0x2F, 0x28, 0xDC, 0x20, 0x52, 0xF6 - }, - { - 0x19, 0xE7, 0xF1, 0xCC, 0xEE, 0x88, 0xA1, 0x06, - 0x72, 0x33, 0x3E, 0x39, 0x0C, 0xF2, 0x20, 0x13, - 0xA8, 0xC7, 0x34, 0xC6, 0xCB, 0x9E, 0xAB, 0x41, - 0xF1, 0x7C, 0x3C, 0x80, 0x32, 0xA2, 0xE4, 0xAC, - 0xA0, 0x56, 0x9E, 0xA3, 0x6F, 0x08, 0x60, 0xC7, - 0xA1, 0xAF, 0x28, 0xFA, 0x47, 0x68, 0x40, 0xD6, - 0x60, 0x11, 0x16, 0x88, 0x59, 0x33, 0x4A, 0x9E, - 0x4E, 0xF9, 0xCC, 0x2E, 0x61, 0xA0, 0xE2, 0x9E - }, - { - 0x29, 0xF8, 0xB8, 0xC7, 0x8C, 0x80, 0xF2, 0xFC, - 0xB4, 0xBD, 0xF7, 0x82, 0x5E, 0xD9, 0x0A, 0x70, - 0xD6, 0x25, 0xFF, 0x78, 0x5D, 0x26, 0x26, 0x77, - 0xE2, 0x50, 0xC0, 0x4F, 0x37, 0x20, 0xC8, 0x88, - 0xD0, 0x3F, 0x80, 0x45, 0xE4, 0xED, 0xF3, 0xF5, - 0x28, 0x5B, 0xD3, 0x9D, 0x92, 0x8A, 0x10, 0xA7, - 0xD0, 0xA5, 0xDF, 0x00, 0xB8, 0x48, 0x4A, 0xC2, - 0x86, 0x81, 0x42, 0xA1, 0xE8, 0xBE, 0xA3, 0x51 - }, - { - 0x5C, 0x52, 0x92, 0x0A, 0x72, 0x63, 0xE3, 0x9D, - 0x57, 0x92, 0x0C, 0xA0, 0xCB, 0x75, 0x2A, 0xC6, - 0xD7, 0x9A, 0x04, 0xFE, 0xF8, 0xA7, 0xA2, 0x16, - 0xA1, 0xEC, 0xB7, 0x11, 0x5C, 0xE0, 0x6D, 0x89, - 0xFD, 0x7D, 0x73, 0x5B, 0xD6, 0xF4, 0x27, 0x25, - 0x55, 0xDB, 0xA2, 0x2C, 0x2D, 0x1C, 0x96, 0xE6, - 0x35, 0x23, 0x22, 0xC6, 0x2C, 0x56, 0x30, 0xFD, - 0xE0, 0xF4, 0x77, 0x7A, 0x76, 0xC3, 0xDE, 0x2C - }, - { - 0x83, 0xB0, 0x98, 0xF2, 0x62, 0x25, 0x1B, 0xF6, - 0x60, 0x06, 0x4A, 0x9D, 0x35, 0x11, 0xCE, 0x76, - 0x87, 0xA0, 0x9E, 0x6D, 0xFB, 0xB8, 0x78, 0x29, - 0x9C, 0x30, 0xE9, 0x3D, 0xFB, 0x43, 0xA9, 0x31, - 0x4D, 0xB9, 0xA6, 0x00, 0x33, 0x7D, 0xB2, 0x6E, - 0xBE, 0xED, 0xAF, 0x22, 0x56, 0xA9, 0x6D, 0xAB, - 0xE9, 0xB2, 0x9E, 0x75, 0x73, 0xAD, 0x11, 0xC3, - 0x52, 0x3D, 0x87, 0x4D, 0xDE, 0x5B, 0xE7, 0xED - }, - { - 0x94, 0x47, 0xD9, 0x8A, 0xA5, 0xC9, 0x33, 0x13, - 0x52, 0xF4, 0x3D, 0x3E, 0x56, 0xD0, 0xA9, 0xA9, - 0xF9, 0x58, 0x18, 0x65, 0x99, 0x8E, 0x28, 0x85, - 0xCC, 0x56, 0xDD, 0x0A, 0x0B, 0xD5, 0xA7, 0xB5, - 0x05, 0x95, 0xBD, 0x10, 0xF7, 0x52, 0x9B, 0xCD, - 0x31, 0xF3, 0x7D, 0xC1, 0x6A, 0x14, 0x65, 0xD5, - 0x94, 0x07, 0x96, 0x67, 0xDA, 0x2A, 0x3F, 0xCB, - 0x70, 0x40, 0x14, 0x98, 0x83, 0x7C, 0xED, 0xEB - }, - { - 0x86, 0x77, 0x32, 0xF2, 0xFE, 0xEB, 0x23, 0x89, - 0x30, 0x97, 0x56, 0x1A, 0xC7, 0x10, 0xA4, 0xBF, - 0xF4, 0x53, 0xBE, 0x9C, 0xFB, 0xED, 0xBA, 0x8B, - 0xA3, 0x24, 0xF9, 0xD3, 0x12, 0xA8, 0x2D, 0x73, - 0x2E, 0x1B, 0x83, 0xB8, 0x29, 0xFD, 0xCD, 0x17, - 0x7B, 0x88, 0x2C, 0xA0, 0xC1, 0xBF, 0x54, 0x4B, - 0x22, 0x3B, 0xE5, 0x29, 0x92, 0x4A, 0x24, 0x6A, - 0x63, 0xCF, 0x05, 0x9B, 0xFD, 0xC5, 0x0A, 0x1B - }, - { - 0xF1, 0x5A, 0xB2, 0x6D, 0x4C, 0xDF, 0xCF, 0x56, - 0xE1, 0x96, 0xBB, 0x6B, 0xA1, 0x70, 0xA8, 0xFC, - 0xCC, 0x41, 0x4D, 0xE9, 0x28, 0x5A, 0xFD, 0x98, - 0xA3, 0xD3, 0xCF, 0x2F, 0xB8, 0x8F, 0xCB, 0xC0, - 0xF1, 0x98, 0x32, 0xAC, 0x43, 0x3A, 0x5B, 0x2C, - 0xC2, 0x39, 0x2A, 0x4C, 0xE3, 0x43, 0x32, 0x98, - 0x7D, 0x8D, 0x2C, 0x2B, 0xEF, 0x6C, 0x34, 0x66, - 0x13, 0x8D, 0xB0, 0xC6, 0xE4, 0x2F, 0xA4, 0x7B - }, - { - 0x28, 0x13, 0x51, 0x6D, 0x68, 0xED, 0x4A, 0x08, - 0xB3, 0x9D, 0x64, 0x8A, 0xA6, 0xAA, 0xCD, 0x81, - 0xE9, 0xD6, 0x55, 0xEC, 0xD5, 0xF0, 0xC1, 0x35, - 0x56, 0xC6, 0x0F, 0xDF, 0x0D, 0x33, 0x3E, 0xA3, - 0x84, 0x64, 0xB3, 0x6C, 0x02, 0xBA, 0xCC, 0xD7, - 0x46, 0xE9, 0x57, 0x5E, 0x96, 0xC6, 0x30, 0x14, - 0xF0, 0x74, 0xAE, 0x34, 0xA0, 0xA2, 0x5B, 0x32, - 0x0F, 0x0F, 0xBE, 0xDD, 0x6A, 0xCF, 0x76, 0x65 - }, - { - 0xD3, 0x25, 0x9A, 0xFC, 0xA8, 0xA4, 0x89, 0x62, - 0xFA, 0x89, 0x2E, 0x14, 0x5A, 0xCF, 0x54, 0x7F, - 0x26, 0x92, 0x3A, 0xE8, 0xD4, 0x92, 0x4C, 0x8A, - 0x53, 0x15, 0x81, 0x52, 0x6B, 0x04, 0xB4, 0x4C, - 0x7A, 0xF8, 0x3C, 0x64, 0x3E, 0xF5, 0xA0, 0xBC, - 0x28, 0x2D, 0x36, 0xF3, 0xFB, 0x04, 0xC8, 0x4E, - 0x28, 0xB3, 0x51, 0xF4, 0x0C, 0x74, 0xB6, 0x9D, - 0xC7, 0x84, 0x0B, 0xC7, 0x17, 0xB6, 0xF1, 0x5F - }, - { - 0xF1, 0x4B, 0x06, 0x1A, 0xE3, 0x59, 0xFA, 0x31, - 0xB9, 0x89, 0xE3, 0x03, 0x32, 0xBF, 0xE8, 0xDE, - 0x8C, 0xC8, 0xCD, 0xB5, 0x68, 0xE1, 0x4B, 0xE2, - 0x14, 0xA2, 0x22, 0x3B, 0x84, 0xCA, 0xAB, 0x74, - 0x19, 0x54, 0x9E, 0xCF, 0xCC, 0x96, 0xCE, 0x2A, - 0xCE, 0xC1, 0x19, 0x48, 0x5D, 0x87, 0xD1, 0x57, - 0xD3, 0xA8, 0x73, 0x4F, 0xC4, 0x26, 0x59, 0x7D, - 0x64, 0xF3, 0x65, 0x70, 0xCE, 0xAF, 0x22, 0x4D - }, - { - 0x55, 0xE7, 0x0B, 0x01, 0xD1, 0xFB, 0xF8, 0xB2, - 0x3B, 0x57, 0xFB, 0x62, 0xE2, 0x6C, 0x2C, 0xE5, - 0x4F, 0x13, 0xF8, 0xFA, 0x24, 0x64, 0xE6, 0xEB, - 0x98, 0xD1, 0x6A, 0x61, 0x17, 0x02, 0x6D, 0x8B, - 0x90, 0x81, 0x90, 0x12, 0x49, 0x6D, 0x40, 0x71, - 0xEB, 0xE2, 0xE5, 0x95, 0x57, 0xEC, 0xE3, 0x51, - 0x9A, 0x7A, 0xA4, 0x58, 0x02, 0xF9, 0x61, 0x53, - 0x74, 0x87, 0x73, 0x32, 0xB7, 0x34, 0x90, 0xB3 - }, - { - 0x25, 0x26, 0x1E, 0xB2, 0x96, 0x97, 0x1D, 0x6E, - 0x4A, 0x71, 0xB2, 0x92, 0x8E, 0x64, 0x83, 0x9C, - 0x67, 0xD4, 0x22, 0x87, 0x2B, 0xF9, 0xF3, 0xC3, - 0x19, 0x93, 0x61, 0x52, 0x22, 0xDE, 0x9F, 0x8F, - 0x0B, 0x2C, 0x4B, 0xE8, 0x54, 0x85, 0x59, 0xB4, - 0xB3, 0x54, 0xE7, 0x36, 0x41, 0x6E, 0x32, 0x18, - 0xD4, 0xE8, 0xA1, 0xE2, 0x19, 0xA4, 0xA6, 0xD4, - 0x3E, 0x1A, 0x9A, 0x52, 0x1D, 0x0E, 0x75, 0xFC - }, - { - 0x08, 0x30, 0x7F, 0x34, 0x7C, 0x41, 0x29, 0x4E, - 0x34, 0xBB, 0x54, 0xCB, 0x42, 0xB1, 0x52, 0x2D, - 0x22, 0xF8, 0x24, 0xF7, 0xB6, 0xE5, 0xDB, 0x50, - 0xFD, 0xA0, 0x96, 0x79, 0x8E, 0x18, 0x1A, 0x8F, - 0x02, 0x6F, 0xA2, 0x7B, 0x4A, 0xE4, 0x5D, 0x52, - 0xA6, 0x2C, 0xAF, 0x9D, 0x51, 0x98, 0xE2, 0x4A, - 0x49, 0x13, 0xC6, 0x67, 0x17, 0x75, 0xB2, 0xD7, - 0x23, 0xC1, 0x23, 0x9B, 0xFB, 0xF0, 0x16, 0xD7 - }, - { - 0x1E, 0x5C, 0x62, 0xE7, 0xE9, 0xBF, 0xA1, 0xB1, - 0x18, 0x74, 0x7A, 0x2D, 0xE0, 0x8B, 0x3C, 0xA1, - 0x01, 0x12, 0xAF, 0x96, 0xA4, 0x6E, 0x4B, 0x22, - 0xC3, 0xFC, 0x06, 0xF9, 0xBF, 0xEE, 0x4E, 0xB5, - 0xC4, 0x9E, 0x05, 0x7A, 0x4A, 0x48, 0x86, 0x23, - 0x43, 0x24, 0x57, 0x25, 0x76, 0xBB, 0x9B, 0x5E, - 0xCF, 0xDE, 0x0D, 0x99, 0xB0, 0xDE, 0x4F, 0x98, - 0xEC, 0x16, 0xE4, 0xD1, 0xB8, 0x5F, 0xA9, 0x47 - }, - { - 0xC7, 0x4A, 0x77, 0x39, 0x5F, 0xB8, 0xBC, 0x12, - 0x64, 0x47, 0x45, 0x48, 0x38, 0xE5, 0x61, 0xE9, - 0x62, 0x85, 0x3D, 0xC7, 0xEB, 0x49, 0xA1, 0xE3, - 0xCB, 0x67, 0xC3, 0xD0, 0x85, 0x1F, 0x3E, 0x39, - 0x51, 0x7B, 0xE8, 0xC3, 0x50, 0xAC, 0x91, 0x09, - 0x03, 0xD4, 0x9C, 0xD2, 0xBF, 0xDF, 0x54, 0x5C, - 0x99, 0x31, 0x6D, 0x03, 0x46, 0x17, 0x0B, 0x73, - 0x9F, 0x0A, 0xDD, 0x5D, 0x53, 0x3C, 0x2C, 0xFC - }, - { - 0x0D, 0xD5, 0x7B, 0x42, 0x3C, 0xC0, 0x1E, 0xB2, - 0x86, 0x13, 0x91, 0xEB, 0x88, 0x6A, 0x0D, 0x17, - 0x07, 0x9B, 0x93, 0x3F, 0xC7, 0x6E, 0xB3, 0xFC, - 0x08, 0xA1, 0x9F, 0x8A, 0x74, 0x95, 0x2C, 0xB6, - 0x8F, 0x6B, 0xCD, 0xC6, 0x44, 0xF7, 0x73, 0x70, - 0x96, 0x6E, 0x4D, 0x13, 0xE8, 0x05, 0x60, 0xBC, - 0xF0, 0x82, 0xEF, 0x04, 0x79, 0xD4, 0x8F, 0xBB, - 0xAB, 0x4D, 0xF0, 0x3B, 0x53, 0xA4, 0xE1, 0x78 - }, - { - 0x4D, 0x8D, 0xC3, 0x92, 0x3E, 0xDC, 0xCD, 0xFC, - 0xE7, 0x00, 0x72, 0x39, 0x8B, 0x8A, 0x3D, 0xA5, - 0xC3, 0x1F, 0xCB, 0x3E, 0xE3, 0xB6, 0x45, 0xC8, - 0x5F, 0x71, 0x7C, 0xBA, 0xEB, 0x4B, 0x67, 0x3A, - 0x19, 0x39, 0x44, 0x25, 0xA5, 0x85, 0xBF, 0xB4, - 0x64, 0xD9, 0x2F, 0x15, 0x97, 0xD0, 0xB7, 0x54, - 0xD1, 0x63, 0xF9, 0x7C, 0xED, 0x34, 0x3B, 0x25, - 0xDB, 0x5A, 0x70, 0xEF, 0x48, 0xEB, 0xB3, 0x4F - }, - { - 0xF0, 0xA5, 0x05, 0x53, 0xE4, 0xDF, 0xB0, 0xC4, - 0xE3, 0xE3, 0xD3, 0xBA, 0x82, 0x03, 0x48, 0x57, - 0xE3, 0xB1, 0xE5, 0x09, 0x18, 0xF5, 0xB8, 0xA7, - 0xD6, 0x98, 0xE1, 0x0D, 0x24, 0x2B, 0x0F, 0xB5, - 0x44, 0xAF, 0x6C, 0x92, 0xD0, 0xC3, 0xAA, 0xF9, - 0x93, 0x22, 0x20, 0x41, 0x61, 0x17, 0xB4, 0xE7, - 0x8E, 0xCB, 0x8A, 0x8F, 0x43, 0x0E, 0x13, 0xB8, - 0x2A, 0x59, 0x15, 0x29, 0x0A, 0x58, 0x19, 0xC5 - }, - { - 0xB1, 0x55, 0x43, 0xF3, 0xF7, 0x36, 0x08, 0x66, - 0x27, 0xCC, 0x53, 0x65, 0xE7, 0xE8, 0x98, 0x8C, - 0x2E, 0xF1, 0x55, 0xC0, 0xFD, 0x4F, 0x42, 0x89, - 0x61, 0xB0, 0x0D, 0x15, 0x26, 0xF0, 0x4D, 0x6D, - 0x6A, 0x65, 0x8B, 0x4B, 0x8E, 0xD3, 0x2C, 0x5D, - 0x86, 0x21, 0xE7, 0xF4, 0xF8, 0xE8, 0xA9, 0x33, - 0xD9, 0xEC, 0xC9, 0xDD, 0x1B, 0x83, 0x33, 0xCB, - 0xE2, 0x8C, 0xFC, 0x37, 0xD9, 0x71, 0x9E, 0x1C - }, - { - 0x7B, 0x4F, 0xA1, 0x58, 0xE4, 0x15, 0xFE, 0xF0, - 0x23, 0x24, 0x72, 0x64, 0xCB, 0xBE, 0x15, 0xD1, - 0x6D, 0x91, 0xA4, 0x44, 0x24, 0xA8, 0xDB, 0x70, - 0x7E, 0xB1, 0xE2, 0x03, 0x3C, 0x30, 0xE9, 0xE1, - 0xE7, 0xC8, 0xC0, 0x86, 0x45, 0x95, 0xD2, 0xCB, - 0x8C, 0x58, 0x0E, 0xB4, 0x7E, 0x9D, 0x16, 0xAB, - 0xBD, 0x7E, 0x44, 0xE8, 0x24, 0xF7, 0xCE, 0xDB, - 0x7D, 0xEF, 0x57, 0x13, 0x0E, 0x52, 0xCF, 0xE9 - }, - { - 0x60, 0x42, 0x4F, 0xF2, 0x32, 0x34, 0xC3, 0x4D, - 0xC9, 0x68, 0x7A, 0xD5, 0x02, 0x86, 0x93, 0x72, - 0xCC, 0x31, 0xA5, 0x93, 0x80, 0x18, 0x6B, 0xC2, - 0x36, 0x1C, 0x83, 0x5D, 0x97, 0x2F, 0x49, 0x66, - 0x6E, 0xB1, 0xAC, 0x69, 0x62, 0x9D, 0xE6, 0x46, - 0xF0, 0x3F, 0x9B, 0x4D, 0xB9, 0xE2, 0xAC, 0xE0, - 0x93, 0xFB, 0xFD, 0xF8, 0xF2, 0x0A, 0xB5, 0xF9, - 0x85, 0x41, 0x97, 0x8B, 0xE8, 0xEF, 0x54, 0x9F - }, - { - 0x74, 0x06, 0x01, 0x8C, 0xE7, 0x04, 0xD8, 0x4F, - 0x5E, 0xB9, 0xC7, 0x9F, 0xEA, 0x97, 0xDA, 0x34, - 0x56, 0x99, 0x46, 0x8A, 0x35, 0x0E, 0xE0, 0xB2, - 0xD0, 0xF3, 0xA4, 0xBF, 0x20, 0x70, 0x30, 0x4E, - 0xA8, 0x62, 0xD7, 0x2A, 0x51, 0xC5, 0x7D, 0x30, - 0x64, 0x94, 0x72, 0x86, 0xF5, 0x31, 0xE0, 0xEA, - 0xF7, 0x56, 0x37, 0x02, 0x26, 0x2E, 0x6C, 0x72, - 0x4A, 0xBF, 0x5E, 0xD8, 0xC8, 0x39, 0x8D, 0x17 - }, - { - 0x14, 0xEF, 0x5C, 0x6D, 0x64, 0x7B, 0x3B, 0xD1, - 0xE6, 0xE3, 0x20, 0x06, 0xC2, 0x31, 0x19, 0x98, - 0x10, 0xDE, 0x5C, 0x4D, 0xC8, 0x8E, 0x70, 0x24, - 0x02, 0x73, 0xB0, 0xEA, 0x18, 0xE6, 0x51, 0xA3, - 0xEB, 0x4F, 0x5C, 0xA3, 0x11, 0x4B, 0x8A, 0x56, - 0x71, 0x69, 0x69, 0xC7, 0xCD, 0xA2, 0x7E, 0x0C, - 0x8D, 0xB8, 0x32, 0xAD, 0x5E, 0x89, 0xA2, 0xDC, - 0x6C, 0xB0, 0xAD, 0xBE, 0x7D, 0x93, 0xAB, 0xD1 - }, - { - 0x38, 0xCF, 0x6C, 0x24, 0xE3, 0xE0, 0x8B, 0xCF, - 0x1F, 0x6C, 0xF3, 0xD1, 0xB1, 0xF6, 0x5B, 0x90, - 0x52, 0x39, 0xA3, 0x11, 0x80, 0x33, 0x24, 0x9E, - 0x44, 0x81, 0x13, 0xEC, 0x63, 0x2E, 0xA6, 0xDC, - 0x34, 0x6F, 0xEE, 0xB2, 0x57, 0x1C, 0x38, 0xBD, - 0x9A, 0x73, 0x98, 0xB2, 0x22, 0x12, 0x80, 0x32, - 0x80, 0x02, 0xB2, 0x3E, 0x1A, 0x45, 0xAD, 0xAF, - 0xFE, 0x66, 0xD9, 0x3F, 0x65, 0x64, 0xEA, 0xA2 - }, - { - 0x6C, 0xD7, 0x20, 0x8A, 0x4B, 0xC7, 0xE7, 0xE5, - 0x62, 0x01, 0xBB, 0xBA, 0x02, 0xA0, 0xF4, 0x89, - 0xCD, 0x38, 0x4A, 0xBE, 0x40, 0xAF, 0xD4, 0x22, - 0x2F, 0x15, 0x8B, 0x3D, 0x98, 0x6E, 0xE7, 0x2A, - 0x54, 0xC5, 0x0F, 0xB6, 0x4F, 0xD4, 0xED, 0x25, - 0x30, 0xED, 0xA2, 0xC8, 0xAF, 0x29, 0x28, 0xA0, - 0xDA, 0x6D, 0x4F, 0x83, 0x0A, 0xE1, 0xC9, 0xDB, - 0x46, 0x9D, 0xFD, 0x97, 0x0F, 0x12, 0xA5, 0x6F - }, - { - 0x65, 0x98, 0x58, 0xF0, 0xB5, 0xC9, 0xED, 0xAB, - 0x5B, 0x94, 0xFD, 0x73, 0x2F, 0x6E, 0x6B, 0x17, - 0xC5, 0x1C, 0xC0, 0x96, 0x10, 0x4F, 0x09, 0xBE, - 0xB3, 0xAF, 0xC3, 0xAA, 0x46, 0x7C, 0x2E, 0xCF, - 0x88, 0x5C, 0x4C, 0x65, 0x41, 0xEF, 0xFA, 0x90, - 0x23, 0xD3, 0xB5, 0x73, 0x8A, 0xE5, 0xA1, 0x4D, - 0x86, 0x7E, 0x15, 0xDB, 0x06, 0xFE, 0x1F, 0x9D, - 0x11, 0x27, 0xB7, 0x7E, 0x1A, 0xAB, 0xB5, 0x16 - }, - { - 0x26, 0xCC, 0xA0, 0x12, 0x6F, 0x5D, 0x1A, 0x81, - 0x3C, 0x62, 0xE5, 0xC7, 0x10, 0x01, 0xC0, 0x46, - 0xF9, 0xC9, 0x20, 0x95, 0x70, 0x45, 0x50, 0xBE, - 0x58, 0x73, 0xA4, 0x95, 0xA9, 0x99, 0xAD, 0x01, - 0x0A, 0x4F, 0x79, 0x49, 0x1F, 0x24, 0xF2, 0x86, - 0x50, 0x0A, 0xDC, 0xE1, 0xA1, 0x37, 0xBC, 0x20, - 0x84, 0xE4, 0x94, 0x9F, 0x5B, 0x72, 0x94, 0xCE, - 0xFE, 0x51, 0xEC, 0xAF, 0xF8, 0xE9, 0x5C, 0xBA - }, - { - 0x41, 0x47, 0xC1, 0xF5, 0x51, 0x72, 0x78, 0x8C, - 0x55, 0x67, 0xC5, 0x61, 0xFE, 0xEF, 0x87, 0x6F, - 0x62, 0x1F, 0xFF, 0x1C, 0xE8, 0x77, 0x86, 0xB8, - 0x46, 0x76, 0x37, 0xE7, 0x0D, 0xFB, 0xCD, 0x0D, - 0xBD, 0xB6, 0x41, 0x5C, 0xB6, 0x00, 0x95, 0x4A, - 0xB9, 0xC0, 0x4C, 0x0E, 0x45, 0x7E, 0x62, 0x5B, - 0x40, 0x72, 0x22, 0xC0, 0xFE, 0x1A, 0xE2, 0x1B, - 0x21, 0x43, 0x68, 0x8A, 0xDA, 0x94, 0xDC, 0x58 - }, - { - 0x5B, 0x1B, 0xF1, 0x54, 0xC6, 0x2A, 0x8A, 0xF6, - 0xE9, 0x3D, 0x35, 0xF1, 0x8F, 0x7F, 0x90, 0xAB, - 0xB1, 0x6A, 0x6E, 0xF0, 0xE8, 0xD1, 0xAE, 0xCD, - 0x11, 0x8B, 0xF7, 0x01, 0x67, 0xBA, 0xB2, 0xAF, - 0x08, 0x93, 0x5C, 0x6F, 0xDC, 0x06, 0x63, 0xCE, - 0x74, 0x48, 0x2D, 0x17, 0xA8, 0xE5, 0x4B, 0x54, - 0x6D, 0x1C, 0x29, 0x66, 0x31, 0xC6, 0x5F, 0x3B, - 0x52, 0x2A, 0x51, 0x58, 0x39, 0xD4, 0x3D, 0x71 - }, - { - 0x9F, 0x60, 0x04, 0x19, 0xA4, 0xE8, 0xF4, 0xFB, - 0x83, 0x4C, 0x24, 0xB0, 0xF7, 0xFC, 0x13, 0xBF, - 0x4E, 0x27, 0x9D, 0x98, 0xE8, 0xA3, 0xC7, 0x65, - 0xEE, 0x93, 0x49, 0x17, 0x40, 0x3E, 0x3A, 0x66, - 0x09, 0x71, 0x82, 0xEA, 0x21, 0x45, 0x3C, 0xB6, - 0x3E, 0xBB, 0xE8, 0xB7, 0x3A, 0x9C, 0x21, 0x67, - 0x59, 0x64, 0x46, 0x43, 0x8C, 0x57, 0x62, 0x7F, - 0x33, 0x0B, 0xAD, 0xD4, 0xF5, 0x69, 0xF7, 0xD6 - }, - { - 0x45, 0x7E, 0xF6, 0x46, 0x6A, 0x89, 0x24, 0xFD, - 0x80, 0x11, 0xA3, 0x44, 0x71, 0xA5, 0xA1, 0xAC, - 0x8C, 0xCD, 0x9B, 0xD0, 0xD0, 0x7A, 0x97, 0x41, - 0x4A, 0xC9, 0x43, 0x02, 0x1C, 0xE4, 0xB9, 0xE4, - 0xB9, 0xC8, 0xDB, 0x0A, 0x28, 0xF0, 0x16, 0xED, - 0x43, 0xB1, 0x54, 0x24, 0x81, 0x99, 0x00, 0x22, - 0x14, 0x7B, 0x31, 0x3E, 0x19, 0x46, 0x71, 0x13, - 0x1E, 0x70, 0x8D, 0xD4, 0x3A, 0x3E, 0xD7, 0xDC - }, - { - 0x99, 0x97, 0xB2, 0x19, 0x4D, 0x9A, 0xF6, 0xDF, - 0xCB, 0x91, 0x43, 0xF4, 0x1C, 0x0E, 0xD8, 0x3D, - 0x3A, 0x3F, 0x43, 0x88, 0x36, 0x11, 0x03, 0xD3, - 0x8C, 0x2A, 0x49, 0xB2, 0x80, 0xA5, 0x81, 0x21, - 0x27, 0x15, 0xFD, 0x90, 0x8D, 0x41, 0xC6, 0x51, - 0xF5, 0xC7, 0x15, 0xCA, 0x38, 0xC0, 0xCE, 0x28, - 0x30, 0xA3, 0x7E, 0x00, 0xE5, 0x08, 0xCE, 0xD1, - 0xBC, 0xDC, 0x32, 0x0E, 0x5E, 0x4D, 0x1E, 0x2E - }, - { - 0x5C, 0x6B, 0xBF, 0x16, 0xBA, 0xA1, 0x80, 0xF9, - 0x86, 0xBD, 0x40, 0xA1, 0x28, 0x7E, 0xD4, 0xC5, - 0x49, 0x77, 0x0E, 0x72, 0x84, 0x85, 0x8F, 0xC4, - 0x7B, 0xC2, 0x1A, 0xB9, 0x5E, 0xBB, 0xF3, 0x37, - 0x4B, 0x4E, 0xE3, 0xFD, 0x9F, 0x2A, 0xF6, 0x0F, - 0x33, 0x95, 0x22, 0x1B, 0x2A, 0xCC, 0x76, 0xF2, - 0xD3, 0x4C, 0x13, 0x29, 0x54, 0x04, 0x9F, 0x8A, - 0x3A, 0x99, 0x6F, 0x1E, 0x32, 0xEC, 0x84, 0xE5 - }, - { - 0xD1, 0x0B, 0xF9, 0xA1, 0x5B, 0x1C, 0x9F, 0xC8, - 0xD4, 0x1F, 0x89, 0xBB, 0x14, 0x0B, 0xF0, 0xBE, - 0x08, 0xD2, 0xF3, 0x66, 0x61, 0x76, 0xD1, 0x3B, - 0xAA, 0xC4, 0xD3, 0x81, 0x35, 0x8A, 0xD0, 0x74, - 0xC9, 0xD4, 0x74, 0x8C, 0x30, 0x05, 0x20, 0xEB, - 0x02, 0x6D, 0xAE, 0xAE, 0xA7, 0xC5, 0xB1, 0x58, - 0x89, 0x2F, 0xDE, 0x4E, 0x8E, 0xC1, 0x7D, 0xC9, - 0x98, 0xDC, 0xD5, 0x07, 0xDF, 0x26, 0xEB, 0x63 - }, - { - 0x2F, 0xC6, 0xE6, 0x9F, 0xA2, 0x6A, 0x89, 0xA5, - 0xED, 0x26, 0x90, 0x92, 0xCB, 0x9B, 0x2A, 0x44, - 0x9A, 0x44, 0x09, 0xA7, 0xA4, 0x40, 0x11, 0xEE, - 0xCA, 0xD1, 0x3D, 0x7C, 0x4B, 0x04, 0x56, 0x60, - 0x2D, 0x40, 0x2F, 0xA5, 0x84, 0x4F, 0x1A, 0x7A, - 0x75, 0x81, 0x36, 0xCE, 0x3D, 0x5D, 0x8D, 0x0E, - 0x8B, 0x86, 0x92, 0x1F, 0xFF, 0xF4, 0xF6, 0x92, - 0xDD, 0x95, 0xBD, 0xC8, 0xE5, 0xFF, 0x00, 0x52 - }, - { - 0xFC, 0xBE, 0x8B, 0xE7, 0xDC, 0xB4, 0x9A, 0x32, - 0xDB, 0xDF, 0x23, 0x94, 0x59, 0xE2, 0x63, 0x08, - 0xB8, 0x4D, 0xFF, 0x1E, 0xA4, 0x80, 0xDF, 0x8D, - 0x10, 0x4E, 0xEF, 0xF3, 0x4B, 0x46, 0xFA, 0xE9, - 0x86, 0x27, 0xB4, 0x50, 0xC2, 0x26, 0x7D, 0x48, - 0xC0, 0x94, 0x6A, 0x69, 0x7C, 0x5B, 0x59, 0x53, - 0x14, 0x52, 0xAC, 0x04, 0x84, 0xF1, 0xC8, 0x4E, - 0x3A, 0x33, 0xD0, 0xC3, 0x39, 0xBB, 0x2E, 0x28 - }, - { - 0xA1, 0x90, 0x93, 0xA6, 0xE3, 0xBC, 0xF5, 0x95, - 0x2F, 0x85, 0x0F, 0x20, 0x30, 0xF6, 0x9B, 0x96, - 0x06, 0xF1, 0x47, 0xF9, 0x0B, 0x8B, 0xAE, 0xE3, - 0x36, 0x2D, 0xA7, 0x1D, 0x9F, 0x35, 0xB4, 0x4E, - 0xF9, 0xD8, 0xF0, 0xA7, 0x71, 0x2B, 0xA1, 0x87, - 0x7F, 0xDD, 0xCD, 0x2D, 0x8E, 0xA8, 0xF1, 0xE5, - 0xA7, 0x73, 0xD0, 0xB7, 0x45, 0xD4, 0x72, 0x56, - 0x05, 0x98, 0x3A, 0x2D, 0xE9, 0x01, 0xF8, 0x03 - }, - { - 0x3C, 0x20, 0x06, 0x42, 0x3F, 0x73, 0xE2, 0x68, - 0xFA, 0x59, 0xD2, 0x92, 0x03, 0x77, 0xEB, 0x29, - 0xA4, 0xF9, 0xA8, 0xB4, 0x62, 0xBE, 0x15, 0x98, - 0x3E, 0xE3, 0xB8, 0x5A, 0xE8, 0xA7, 0x8E, 0x99, - 0x26, 0x33, 0x58, 0x1A, 0x90, 0x99, 0x89, 0x3B, - 0x63, 0xDB, 0x30, 0x24, 0x1C, 0x34, 0xF6, 0x43, - 0x02, 0x7D, 0xC8, 0x78, 0x27, 0x9A, 0xF5, 0x85, - 0x0D, 0x7E, 0x2D, 0x4A, 0x26, 0x53, 0x07, 0x3A - }, - { - 0xD0, 0xF2, 0xF2, 0xE3, 0x78, 0x76, 0x53, 0xF7, - 0x7C, 0xCE, 0x2F, 0xA2, 0x48, 0x35, 0x78, 0x5B, - 0xBD, 0x0C, 0x43, 0x3F, 0xC7, 0x79, 0x46, 0x5A, - 0x11, 0x51, 0x49, 0x90, 0x5A, 0x9D, 0xD1, 0xCB, - 0x82, 0x7A, 0x62, 0x85, 0x06, 0xD4, 0x57, 0xFC, - 0xF1, 0x24, 0xA0, 0xC2, 0xAE, 0xF9, 0xCE, 0x2D, - 0x2A, 0x0A, 0x0F, 0x63, 0x54, 0x55, 0x70, 0xD8, - 0x66, 0x7F, 0xF9, 0xE2, 0xEB, 0xA0, 0x73, 0x34 - }, - { - 0x78, 0xA9, 0xFC, 0x04, 0x8E, 0x25, 0xC6, 0xDC, - 0xB5, 0xDE, 0x45, 0x66, 0x7D, 0xE8, 0xFF, 0xDD, - 0x3A, 0x93, 0x71, 0x11, 0x41, 0xD5, 0x94, 0xE9, - 0xFA, 0x62, 0xA9, 0x59, 0x47, 0x5D, 0xA6, 0x07, - 0x5E, 0xA8, 0xF0, 0x91, 0x6E, 0x84, 0xE4, 0x5A, - 0xD9, 0x11, 0xB7, 0x54, 0x67, 0x07, 0x7E, 0xE5, - 0x2D, 0x2C, 0x9A, 0xEB, 0xF4, 0xD5, 0x8F, 0x20, - 0xCE, 0x4A, 0x3A, 0x00, 0x45, 0x8B, 0x05, 0xD4 - }, - { - 0x45, 0x81, 0x3F, 0x44, 0x17, 0x69, 0xAB, 0x6E, - 0xD3, 0x7D, 0x34, 0x9F, 0xF6, 0xE7, 0x22, 0x67, - 0xD7, 0x6A, 0xE6, 0xBB, 0x3E, 0x3C, 0x61, 0x2E, - 0xC0, 0x5C, 0x6E, 0x02, 0xA1, 0x2A, 0xF5, 0xA3, - 0x7C, 0x91, 0x8B, 0x52, 0xBF, 0x74, 0x26, 0x7C, - 0x3F, 0x6A, 0x3F, 0x18, 0x3A, 0x80, 0x64, 0xFF, - 0x84, 0xC0, 0x7B, 0x19, 0x3D, 0x08, 0x06, 0x67, - 0x89, 0xA0, 0x1A, 0xCC, 0xDB, 0x6F, 0x93, 0x40 - }, - { - 0x95, 0x6D, 0xA1, 0xC6, 0x8D, 0x83, 0xA7, 0xB8, - 0x81, 0xE0, 0x1B, 0x9A, 0x96, 0x6C, 0x3C, 0x0B, - 0xF2, 0x7F, 0x68, 0x60, 0x6A, 0x8B, 0x71, 0xD4, - 0x57, 0xBD, 0x01, 0x6D, 0x4C, 0x41, 0xDD, 0x8A, - 0x38, 0x0C, 0x70, 0x9A, 0x29, 0x6C, 0xB4, 0xC6, - 0x54, 0x47, 0x92, 0x92, 0x0F, 0xD7, 0x88, 0x83, - 0x57, 0x71, 0xA0, 0x7D, 0x4A, 0x16, 0xFB, 0x52, - 0xED, 0x48, 0x05, 0x03, 0x31, 0xDC, 0x4C, 0x8B - }, - { - 0xDF, 0x18, 0x6C, 0x2D, 0xC0, 0x9C, 0xAA, 0x48, - 0xE1, 0x4E, 0x94, 0x2F, 0x75, 0xDE, 0x5A, 0xC1, - 0xB7, 0xA2, 0x1E, 0x4F, 0x9F, 0x07, 0x2A, 0x5B, - 0x37, 0x1E, 0x09, 0xE0, 0x73, 0x45, 0xB0, 0x74, - 0x0C, 0x76, 0x17, 0x7B, 0x01, 0x27, 0x88, 0x08, - 0xFE, 0xC0, 0x25, 0xED, 0xED, 0x98, 0x22, 0xC1, - 0x22, 0xAF, 0xD1, 0xC6, 0x3E, 0x6F, 0x0C, 0xE2, - 0xE3, 0x26, 0x31, 0x04, 0x10, 0x63, 0x14, 0x5C - }, - { - 0x87, 0x47, 0x56, 0x40, 0x96, 0x6A, 0x9F, 0xDC, - 0xD6, 0xD3, 0xA3, 0xB5, 0xA2, 0xCC, 0xA5, 0xC0, - 0x8F, 0x0D, 0x88, 0x2B, 0x10, 0x24, 0x3C, 0x0E, - 0xC1, 0xBF, 0x3C, 0x6B, 0x1C, 0x37, 0xF2, 0xCD, - 0x32, 0x12, 0xF1, 0x9A, 0x05, 0x78, 0x64, 0x47, - 0x7D, 0x5E, 0xAF, 0x8F, 0xAE, 0xD7, 0x3F, 0x29, - 0x37, 0xC7, 0x68, 0xA0, 0xAF, 0x41, 0x5E, 0x84, - 0xBB, 0xCE, 0x6B, 0xD7, 0xDE, 0x23, 0xB6, 0x60 - }, - { - 0xC3, 0xB5, 0x73, 0xBB, 0xE1, 0x09, 0x49, 0xA0, - 0xFB, 0xD4, 0xFF, 0x88, 0x4C, 0x44, 0x6F, 0x22, - 0x29, 0xB7, 0x69, 0x02, 0xF9, 0xDF, 0xDB, 0xB8, - 0xA0, 0x35, 0x3D, 0xA5, 0xC8, 0x3C, 0xA1, 0x4E, - 0x81, 0x51, 0xBB, 0xAA, 0xC8, 0x2F, 0xD1, 0x57, - 0x6A, 0x00, 0x9A, 0xDC, 0x6F, 0x19, 0x35, 0xCF, - 0x26, 0xED, 0xD4, 0xF1, 0xFB, 0x8D, 0xA4, 0x83, - 0xE6, 0xC5, 0xCD, 0x9D, 0x89, 0x23, 0xAD, 0xC3 - }, - { - 0xB0, 0x9D, 0x8D, 0x0B, 0xBA, 0x8A, 0x72, 0x86, - 0xE4, 0x35, 0x68, 0xF7, 0x90, 0x75, 0x50, 0xE4, - 0x20, 0x36, 0xD6, 0x74, 0xE3, 0xC8, 0xFC, 0x34, - 0xD8, 0xCA, 0x46, 0xF7, 0x71, 0xD6, 0x46, 0x6B, - 0x70, 0xFB, 0x60, 0x58, 0x75, 0xF6, 0xA8, 0x63, - 0xC8, 0x77, 0xD1, 0x2F, 0x07, 0x06, 0x3F, 0xDC, - 0x2E, 0x90, 0xCC, 0xD4, 0x59, 0xB1, 0x91, 0x0D, - 0xCD, 0x52, 0xD8, 0xF1, 0x0B, 0x2B, 0x0A, 0x15 - }, - { - 0xAF, 0x3A, 0x22, 0xBF, 0x75, 0xB2, 0x1A, 0xBF, - 0xB0, 0xAC, 0xD5, 0x44, 0x22, 0xBA, 0x1B, 0x73, - 0x00, 0xA9, 0x52, 0xEF, 0xF0, 0x2E, 0xBE, 0xB6, - 0x5B, 0x5C, 0x23, 0x44, 0x71, 0xA9, 0x8D, 0xF3, - 0x2F, 0x4F, 0x96, 0x43, 0xCE, 0x19, 0x04, 0x10, - 0x8A, 0x16, 0x87, 0x67, 0x92, 0x42, 0x80, 0xBD, - 0x76, 0xC8, 0x3F, 0x8C, 0x82, 0xD9, 0xA7, 0x9D, - 0x92, 0x59, 0xB1, 0x95, 0x36, 0x2A, 0x2A, 0x04 - }, - { - 0xBF, 0x4F, 0xF2, 0x22, 0x1B, 0x7E, 0x69, 0x57, - 0xA7, 0x24, 0xCD, 0x96, 0x4A, 0xA3, 0xD5, 0xD0, - 0xD9, 0x94, 0x1F, 0x54, 0x04, 0x13, 0x75, 0x2F, - 0x46, 0x99, 0xD8, 0x10, 0x1B, 0x3E, 0x53, 0x75, - 0x08, 0xBF, 0x09, 0xF8, 0x50, 0x8B, 0x31, 0x77, - 0x36, 0xFF, 0xD2, 0x65, 0xF2, 0x84, 0x7A, 0xA7, - 0xD8, 0x4B, 0xD2, 0xD9, 0x75, 0x69, 0xC4, 0x9D, - 0x63, 0x2A, 0xED, 0x99, 0x45, 0xE5, 0xFA, 0x5E - }, - { - 0x9C, 0x6B, 0x6B, 0x78, 0x19, 0x9B, 0x1B, 0xDA, - 0xCB, 0x43, 0x00, 0xE3, 0x14, 0x79, 0xFA, 0x62, - 0x2A, 0x6B, 0x5B, 0xC8, 0x0D, 0x46, 0x78, 0xA6, - 0x07, 0x8F, 0x88, 0xA8, 0x26, 0x8C, 0xD7, 0x20, - 0x6A, 0x27, 0x99, 0xE8, 0xD4, 0x62, 0x1A, 0x46, - 0x4E, 0xF6, 0xB4, 0x3D, 0xD8, 0xAD, 0xFF, 0xE9, - 0x7C, 0xAF, 0x22, 0x1B, 0x22, 0xB6, 0xB8, 0x77, - 0x8B, 0x14, 0x9A, 0x82, 0x2A, 0xEF, 0xBB, 0x09 - }, - { - 0x89, 0x06, 0x56, 0xF0, 0x9C, 0x99, 0xD2, 0x80, - 0xB5, 0xEC, 0xB3, 0x81, 0xF5, 0x64, 0x27, 0xB8, - 0x13, 0x75, 0x1B, 0xC6, 0x52, 0xC7, 0x82, 0x80, - 0x78, 0xB2, 0x3A, 0x4A, 0xF8, 0x3B, 0x4E, 0x3A, - 0x61, 0xFD, 0xBA, 0xC6, 0x1F, 0x89, 0xBE, 0xE8, - 0x4E, 0xA6, 0xBE, 0xE7, 0x60, 0xC0, 0x47, 0xF2, - 0x5C, 0x6B, 0x0A, 0x20, 0x1C, 0x69, 0xA3, 0x8F, - 0xD6, 0xFD, 0x97, 0x1A, 0xF1, 0x85, 0x88, 0xBB - }, - { - 0x31, 0xA0, 0x46, 0xF7, 0x88, 0x2F, 0xFE, 0x6F, - 0x83, 0xCE, 0x47, 0x2E, 0x9A, 0x07, 0x01, 0x83, - 0x2E, 0xC7, 0xB3, 0xF7, 0x6F, 0xBC, 0xFD, 0x1D, - 0xF6, 0x0F, 0xE3, 0xEA, 0x48, 0xFD, 0xE1, 0x65, - 0x12, 0x54, 0x24, 0x7C, 0x3F, 0xD9, 0x5E, 0x10, - 0x0F, 0x91, 0x72, 0x73, 0x1E, 0x17, 0xFD, 0x52, - 0x97, 0xC1, 0x1F, 0x4B, 0xB3, 0x28, 0x36, 0x3C, - 0xA3, 0x61, 0x62, 0x4A, 0x81, 0xAF, 0x79, 0x7C - }, - { - 0x27, 0xA6, 0x0B, 0x2D, 0x00, 0xE7, 0xA6, 0x71, - 0xD4, 0x7D, 0x0A, 0xEC, 0x2A, 0x68, 0x6A, 0x0A, - 0xC0, 0x4B, 0x52, 0xF4, 0x0A, 0xB6, 0x62, 0x90, - 0x28, 0xEB, 0x7D, 0x13, 0xF4, 0xBA, 0xA9, 0x9A, - 0xC0, 0xFE, 0x46, 0xEE, 0x6C, 0x81, 0x49, 0x44, - 0xF2, 0xF4, 0xB4, 0xD2, 0x0E, 0x93, 0x78, 0xE4, - 0x84, 0x7E, 0xA4, 0x4C, 0x13, 0x17, 0x80, 0x91, - 0xE2, 0x77, 0xB8, 0x7E, 0xA7, 0xA5, 0x57, 0x11 - }, - { - 0x8B, 0x5C, 0xCE, 0xF1, 0x94, 0x16, 0x2C, 0x1F, - 0x19, 0xD6, 0x8F, 0x91, 0xE0, 0xB0, 0x92, 0x8F, - 0x28, 0x9E, 0xC5, 0x28, 0x37, 0x20, 0x84, 0x0C, - 0x2F, 0x73, 0xD2, 0x53, 0x11, 0x12, 0x38, 0xDC, - 0xFE, 0x94, 0xAF, 0x2B, 0x59, 0xC2, 0xC1, 0xCA, - 0x25, 0x91, 0x90, 0x1A, 0x7B, 0xC0, 0x60, 0xE7, - 0x45, 0x9B, 0x6C, 0x47, 0xDF, 0x0F, 0x71, 0x70, - 0x1A, 0x35, 0xCC, 0x0A, 0xA8, 0x31, 0xB5, 0xB6 - }, - { - 0x57, 0xAB, 0x6C, 0x4B, 0x22, 0x29, 0xAE, 0xB3, - 0xB7, 0x04, 0x76, 0xD8, 0x03, 0xCD, 0x63, 0x81, - 0x2F, 0x10, 0x7C, 0xE6, 0xDA, 0x17, 0xFE, 0xD9, - 0xB1, 0x78, 0x75, 0xE8, 0xF8, 0x6C, 0x72, 0x4F, - 0x49, 0xE0, 0x24, 0xCB, 0xF3, 0xA1, 0xB8, 0xB1, - 0x19, 0xC5, 0x03, 0x57, 0x65, 0x2B, 0x81, 0x87, - 0x9D, 0x2A, 0xDE, 0x2D, 0x58, 0x8B, 0x9E, 0x4F, - 0x7C, 0xED, 0xBA, 0x0E, 0x46, 0x44, 0xC9, 0xEE - }, - { - 0x01, 0x90, 0xA8, 0xDA, 0xC3, 0x20, 0xA7, 0x39, - 0xF3, 0x22, 0xE1, 0x57, 0x31, 0xAA, 0x14, 0x0D, - 0xDA, 0xF5, 0xBE, 0xD2, 0x94, 0xD5, 0xC8, 0x2E, - 0x54, 0xFE, 0xF2, 0x9F, 0x21, 0x4E, 0x18, 0xAA, - 0xFA, 0xA8, 0x4F, 0x8B, 0xE9, 0x9A, 0xF6, 0x29, - 0x50, 0x26, 0x6B, 0x8F, 0x90, 0x1F, 0x15, 0xDD, - 0x4C, 0x5D, 0x35, 0x51, 0x6F, 0xC3, 0x5B, 0x4C, - 0xAB, 0x2E, 0x96, 0xE4, 0x69, 0x5B, 0xBE, 0x1C - }, - { - 0xD1, 0x4D, 0x7C, 0x4C, 0x41, 0x5E, 0xEB, 0x0E, - 0x10, 0xB1, 0x59, 0x22, 0x4B, 0xEA, 0x12, 0x7E, - 0xBD, 0x84, 0xF9, 0x59, 0x1C, 0x70, 0x2A, 0x33, - 0x0F, 0x5B, 0xB7, 0xBB, 0x7A, 0xA4, 0x4E, 0xA3, - 0x9D, 0xE6, 0xED, 0x01, 0xF1, 0x8D, 0xA7, 0xAD, - 0xF4, 0x0C, 0xFB, 0x97, 0xC5, 0xD1, 0x52, 0xC2, - 0x75, 0x28, 0x82, 0x4B, 0x21, 0xE2, 0x39, 0x52, - 0x6A, 0xF8, 0xF3, 0x6B, 0x21, 0x4E, 0x0C, 0xFB - }, - { - 0xBE, 0x28, 0xC4, 0xBE, 0x70, 0x69, 0x70, 0x48, - 0x8F, 0xAC, 0x7D, 0x29, 0xC3, 0xBD, 0x5C, 0x4E, - 0x98, 0x60, 0x85, 0xC4, 0xC3, 0x33, 0x2F, 0x1F, - 0x3F, 0xD3, 0x09, 0x73, 0xDB, 0x61, 0x41, 0x64, - 0xBA, 0x2F, 0x31, 0xA7, 0x88, 0x75, 0xFF, 0xDC, - 0x15, 0x03, 0x25, 0xC8, 0x83, 0x27, 0xA9, 0x44, - 0x3E, 0xD0, 0x4F, 0xDF, 0xE5, 0xBE, 0x93, 0x87, - 0x6D, 0x16, 0x28, 0x56, 0x0C, 0x76, 0x4A, 0x80 - }, - { - 0x03, 0x1D, 0xA1, 0x06, 0x9E, 0x3A, 0x2E, 0x9C, - 0x33, 0x82, 0xE4, 0x36, 0xFF, 0xD7, 0x9D, 0xF7, - 0x4B, 0x1C, 0xA6, 0xA8, 0xAD, 0xB2, 0xDE, 0xAB, - 0xE6, 0x76, 0xAB, 0x45, 0x99, 0x4C, 0xBC, 0x05, - 0x4F, 0x03, 0x7D, 0x2F, 0x0E, 0xAC, 0xE8, 0x58, - 0xD3, 0x2C, 0x14, 0xE2, 0xD1, 0xC8, 0xB4, 0x60, - 0x77, 0x30, 0x8E, 0x3B, 0xDC, 0x2C, 0x1B, 0x53, - 0x17, 0x2E, 0xCF, 0x7A, 0x8C, 0x14, 0xE3, 0x49 - }, - { - 0x46, 0x65, 0xCE, 0xF8, 0xBA, 0x4D, 0xB4, 0xD0, - 0xAC, 0xB1, 0x18, 0xF2, 0x98, 0x7F, 0x0B, 0xB0, - 0x9F, 0x8F, 0x86, 0xAA, 0x44, 0x5A, 0xA3, 0xD5, - 0xFC, 0x9A, 0x8B, 0x34, 0x68, 0x64, 0x78, 0x74, - 0x89, 0xE8, 0xFC, 0xEC, 0xC1, 0x25, 0xD1, 0x7E, - 0x9B, 0x56, 0xE1, 0x29, 0x88, 0xEA, 0xC5, 0xEC, - 0xC7, 0x28, 0x68, 0x83, 0xDB, 0x06, 0x61, 0xB8, - 0xFF, 0x05, 0xDA, 0x2A, 0xFF, 0xF3, 0x0F, 0xE4 - }, - { - 0x63, 0xB7, 0x03, 0x2E, 0x5F, 0x93, 0x0C, 0xC9, - 0x93, 0x95, 0x17, 0xF9, 0xE9, 0x86, 0x81, 0x6C, - 0xFB, 0xEC, 0x2B, 0xE5, 0x9B, 0x95, 0x68, 0xB1, - 0x3F, 0x2E, 0xAD, 0x05, 0xBA, 0xE7, 0x77, 0x7C, - 0xAB, 0x62, 0x0C, 0x66, 0x59, 0x40, 0x4F, 0x74, - 0x09, 0xE4, 0x19, 0x9A, 0x3B, 0xE5, 0xF7, 0x86, - 0x5A, 0xA7, 0xCB, 0xDF, 0x8C, 0x42, 0x53, 0xF7, - 0xE8, 0x21, 0x9B, 0x1B, 0xD5, 0xF4, 0x6F, 0xEA - }, - { - 0x9F, 0x09, 0xBF, 0x09, 0x3A, 0x2B, 0x0F, 0xF8, - 0xC2, 0x63, 0x4B, 0x49, 0xE3, 0x7F, 0x1B, 0x21, - 0x35, 0xB4, 0x47, 0xAA, 0x91, 0x44, 0xC9, 0x78, - 0x7D, 0xBF, 0xD9, 0x21, 0x29, 0x31, 0x6C, 0x99, - 0xE8, 0x8A, 0xAB, 0x8A, 0x21, 0xFD, 0xEF, 0x23, - 0x72, 0xD1, 0x18, 0x9A, 0xEC, 0x50, 0x0F, 0x95, - 0x77, 0x5F, 0x1F, 0x92, 0xBF, 0xB4, 0x55, 0x45, - 0xE4, 0x25, 0x9F, 0xB9, 0xB7, 0xB0, 0x2D, 0x14 - }, - { - 0xF9, 0xF8, 0x49, 0x3C, 0x68, 0x08, 0x88, 0x07, - 0xDF, 0x7F, 0x6A, 0x26, 0x93, 0xD6, 0x4E, 0xA5, - 0x9F, 0x03, 0xE9, 0xE0, 0x5A, 0x22, 0x3E, 0x68, - 0x52, 0x4C, 0xA3, 0x21, 0x95, 0xA4, 0x73, 0x4B, - 0x65, 0x4F, 0xCE, 0xA4, 0xD2, 0x73, 0x4C, 0x86, - 0x6C, 0xF9, 0x5C, 0x88, 0x9F, 0xB1, 0x0C, 0x49, - 0x15, 0x9B, 0xE2, 0xF5, 0x04, 0x3D, 0xC9, 0x8B, - 0xB5, 0x5E, 0x02, 0xEF, 0x7B, 0xDC, 0xB0, 0x82 - }, - { - 0x3C, 0x9A, 0x73, 0x59, 0xAB, 0x4F, 0xEB, 0xCE, - 0x07, 0xB2, 0x0A, 0xC4, 0x47, 0xB0, 0x6A, 0x24, - 0x0B, 0x7F, 0xE1, 0xDA, 0xE5, 0x43, 0x9C, 0x49, - 0xB6, 0x0B, 0x58, 0x19, 0xF7, 0x81, 0x2E, 0x4C, - 0x17, 0x24, 0x06, 0xC1, 0xAA, 0xC3, 0x16, 0x71, - 0x3C, 0xF0, 0xDD, 0xED, 0x10, 0x38, 0x07, 0x72, - 0x58, 0xE2, 0xEF, 0xF5, 0xB3, 0x39, 0x13, 0xD9, - 0xD9, 0x5C, 0xAE, 0xB4, 0xE6, 0xC6, 0xB9, 0x70 - }, - { - 0xAD, 0x6A, 0xAB, 0x80, 0x84, 0x51, 0x0E, 0x82, - 0x2C, 0xFC, 0xE8, 0x62, 0x5D, 0x62, 0xCF, 0x4D, - 0xE6, 0x55, 0xF4, 0x76, 0x38, 0x84, 0xC7, 0x1E, - 0x80, 0xBA, 0xB9, 0xAC, 0x9D, 0x53, 0x18, 0xDB, - 0xA4, 0xA6, 0x03, 0x3E, 0xD2, 0x90, 0x84, 0xE6, - 0x52, 0x16, 0xC0, 0x31, 0x60, 0x6C, 0xA1, 0x76, - 0x15, 0xDC, 0xFE, 0x3B, 0xA1, 0x1D, 0x26, 0x85, - 0x1A, 0xE0, 0x99, 0x9C, 0xA6, 0xE2, 0x32, 0xCF - }, - { - 0x15, 0x6E, 0x9E, 0x62, 0x61, 0x37, 0x4C, 0x9D, - 0xC8, 0x84, 0xF3, 0x6E, 0x70, 0xF0, 0xFE, 0x1A, - 0xB9, 0x29, 0x79, 0x97, 0xB8, 0x36, 0xFA, 0x7D, - 0x17, 0x0A, 0x9C, 0x9E, 0xBF, 0x57, 0x5B, 0x88, - 0x1E, 0x7B, 0xCE, 0xA4, 0x4D, 0x6C, 0x02, 0x48, - 0xD3, 0x55, 0x97, 0x90, 0x71, 0x54, 0x82, 0x89, - 0x55, 0xBE, 0x19, 0x13, 0x58, 0x52, 0xF9, 0x22, - 0x88, 0x15, 0xEC, 0xA0, 0x24, 0xA8, 0xAD, 0xFB - }, - { - 0x42, 0x15, 0x40, 0x76, 0x33, 0xF4, 0xCC, 0xA9, - 0xB6, 0x78, 0x8B, 0xE9, 0x3E, 0x6A, 0xA3, 0xD9, - 0x63, 0xC7, 0xD6, 0xCE, 0x4B, 0x14, 0x72, 0x47, - 0x09, 0x9F, 0x46, 0xA3, 0xAC, 0xB5, 0x00, 0xA3, - 0x00, 0x38, 0xCB, 0x3E, 0x78, 0x8C, 0x3D, 0x29, - 0xF1, 0x32, 0xAD, 0x84, 0x4E, 0x80, 0xE9, 0xE9, - 0x92, 0x51, 0xF6, 0xDB, 0x96, 0xAC, 0xD8, 0xA0, - 0x91, 0xCF, 0xC7, 0x70, 0xAF, 0x53, 0x84, 0x7B - }, - { - 0x1C, 0x07, 0x7E, 0x27, 0x9D, 0xE6, 0x54, 0x85, - 0x23, 0x50, 0x2B, 0x6D, 0xF8, 0x00, 0xFF, 0xDA, - 0xB5, 0xE2, 0xC3, 0xE9, 0x44, 0x2E, 0xB8, 0x38, - 0xF5, 0x8C, 0x29, 0x5F, 0x3B, 0x14, 0x7C, 0xEF, - 0x9D, 0x70, 0x1C, 0x41, 0xC3, 0x21, 0x28, 0x3F, - 0x00, 0xC7, 0x1A, 0xFF, 0xA0, 0x61, 0x93, 0x10, - 0x39, 0x91, 0x26, 0x29, 0x5B, 0x78, 0xDD, 0x4D, - 0x1A, 0x74, 0x57, 0x2E, 0xF9, 0xED, 0x51, 0x35 - }, - { - 0xF0, 0x7A, 0x55, 0x5F, 0x49, 0xFE, 0x48, 0x1C, - 0xF4, 0xCD, 0x0A, 0x87, 0xB7, 0x1B, 0x82, 0xE4, - 0xA9, 0x50, 0x64, 0xD0, 0x66, 0x77, 0xFD, 0xD9, - 0x0A, 0x0E, 0xB5, 0x98, 0x87, 0x7B, 0xA1, 0xC8, - 0x3D, 0x46, 0x77, 0xB3, 0x93, 0xC3, 0xA3, 0xB6, - 0x66, 0x1C, 0x42, 0x1F, 0x5B, 0x12, 0xCB, 0x99, - 0xD2, 0x03, 0x76, 0xBA, 0x72, 0x75, 0xC2, 0xF3, - 0xA8, 0xF5, 0xA9, 0xB7, 0x82, 0x17, 0x20, 0xDA - }, - { - 0xB5, 0x91, 0x1B, 0x38, 0x0D, 0x20, 0xC7, 0xB0, - 0x43, 0x23, 0xE4, 0x02, 0x6B, 0x38, 0xE2, 0x00, - 0xF5, 0x34, 0x25, 0x92, 0x33, 0xB5, 0x81, 0xE0, - 0x2C, 0x1E, 0x3E, 0x2D, 0x84, 0x38, 0xD6, 0xC6, - 0x6D, 0x5A, 0x4E, 0xB2, 0x01, 0xD5, 0xA8, 0xB7, - 0x50, 0x72, 0xC4, 0xEC, 0x29, 0x10, 0x63, 0x34, - 0xDA, 0x70, 0xBC, 0x79, 0x52, 0x1B, 0x0C, 0xED, - 0x2C, 0xFD, 0x53, 0x3F, 0x5F, 0xF8, 0x4F, 0x95 - }, - { - 0x01, 0xF0, 0x70, 0xA0, 0x9B, 0xAE, 0x91, 0x12, - 0x96, 0x36, 0x1F, 0x91, 0xAA, 0x0E, 0x8E, 0x0D, - 0x09, 0xA7, 0x72, 0x54, 0x78, 0x53, 0x6D, 0x9D, - 0x48, 0xC5, 0xFE, 0x1E, 0x5E, 0x7C, 0x3C, 0x5B, - 0x9B, 0x9D, 0x6E, 0xB0, 0x77, 0x96, 0xF6, 0xDA, - 0x57, 0xAE, 0x56, 0x2A, 0x7D, 0x70, 0xE8, 0x82, - 0xE3, 0x7A, 0xDF, 0xDE, 0x83, 0xF0, 0xC4, 0x33, - 0xC2, 0xCD, 0x36, 0x35, 0x36, 0xBB, 0x22, 0xC8 - }, - { - 0x6F, 0x79, 0x3E, 0xB4, 0x37, 0x4A, 0x48, 0xB0, - 0x77, 0x5A, 0xCA, 0xF9, 0xAD, 0xCF, 0x8E, 0x45, - 0xE5, 0x42, 0x70, 0xC9, 0x47, 0x5F, 0x00, 0x4A, - 0xD8, 0xD5, 0x97, 0x3E, 0x2A, 0xCA, 0x52, 0x74, - 0x7F, 0xF4, 0xED, 0x04, 0xAE, 0x96, 0x72, 0x75, - 0xB9, 0xF9, 0xEB, 0x0E, 0x1F, 0xF7, 0x5F, 0xB4, - 0xF7, 0x94, 0xFA, 0x8B, 0xE9, 0xAD, 0xD7, 0xA4, - 0x13, 0x04, 0x86, 0x8D, 0x10, 0x3F, 0xAB, 0x10 - }, - { - 0x96, 0x5F, 0x20, 0xF1, 0x39, 0x76, 0x5F, 0xCC, - 0x4C, 0xE4, 0xBA, 0x37, 0x94, 0x67, 0x58, 0x63, - 0xCA, 0xC2, 0x4D, 0xB4, 0x72, 0xCD, 0x2B, 0x79, - 0x9D, 0x03, 0x5B, 0xCE, 0x3D, 0xBE, 0xA5, 0x02, - 0xDA, 0x7B, 0x52, 0x48, 0x65, 0xF6, 0xB8, 0x11, - 0xD8, 0xC5, 0x82, 0x8D, 0x3A, 0x88, 0x96, 0x46, - 0xFE, 0x64, 0xA3, 0x80, 0xDA, 0x1A, 0xA7, 0xC7, - 0x04, 0x4E, 0x9F, 0x24, 0x5D, 0xCE, 0xD1, 0x28 - }, - { - 0xEC, 0x29, 0x5B, 0x57, 0x83, 0x60, 0x12, 0x44, - 0xC3, 0x0E, 0x46, 0x41, 0xE3, 0xB4, 0x5B, 0xE2, - 0x22, 0xC4, 0xDC, 0xE7, 0x7A, 0x58, 0x70, 0x0F, - 0x53, 0xBC, 0x8E, 0xC5, 0x2A, 0x94, 0x16, 0x90, - 0xB4, 0xD0, 0xB0, 0x87, 0xFB, 0x6F, 0xCB, 0x3F, - 0x39, 0x83, 0x2B, 0x9D, 0xE8, 0xF7, 0x5E, 0xC2, - 0x0B, 0xD4, 0x30, 0x79, 0x81, 0x17, 0x49, 0xCD, - 0xC9, 0x07, 0xED, 0xB9, 0x41, 0x57, 0xD1, 0x80 - }, - { - 0x61, 0xC7, 0x2F, 0x8C, 0xCC, 0x91, 0xDB, 0xB5, - 0x4C, 0xA6, 0x75, 0x0B, 0xC4, 0x89, 0x67, 0x2D, - 0xE0, 0x9F, 0xAE, 0xDB, 0x8F, 0xDD, 0x4F, 0x94, - 0xFF, 0x23, 0x20, 0x90, 0x9A, 0x30, 0x3F, 0x5D, - 0x5A, 0x98, 0x48, 0x1C, 0x0B, 0xC1, 0xA6, 0x25, - 0x41, 0x9F, 0xB4, 0xDE, 0xBF, 0xBF, 0x7F, 0x8A, - 0x53, 0xBB, 0x07, 0xEC, 0x3D, 0x98, 0x5E, 0x8E, - 0xA1, 0x1E, 0x72, 0xD5, 0x59, 0x94, 0x07, 0x80 - }, - { - 0xAF, 0xD8, 0x14, 0x5B, 0x25, 0x9E, 0xEF, 0xC8, - 0xD1, 0x26, 0x20, 0xC3, 0xC5, 0xB0, 0x3E, 0x1E, - 0xD8, 0xFD, 0x2C, 0xCE, 0xFE, 0x03, 0x65, 0x07, - 0x8C, 0x80, 0xFD, 0x42, 0xC1, 0x77, 0x0E, 0x28, - 0xB4, 0x49, 0x48, 0xF2, 0x7E, 0x65, 0xA1, 0x88, - 0x66, 0x90, 0x11, 0x0D, 0xB8, 0x14, 0x39, 0x7B, - 0x68, 0xE4, 0x3D, 0x80, 0xD1, 0xBA, 0x16, 0xDF, - 0xA3, 0x58, 0xE7, 0x39, 0xC8, 0x98, 0xCF, 0xA3 - }, - { - 0x55, 0x2F, 0xC7, 0x89, 0x3C, 0xF1, 0xCE, 0x93, - 0x3A, 0xDA, 0x35, 0xC0, 0xDA, 0x98, 0x84, 0x4E, - 0x41, 0x54, 0x5E, 0x24, 0x4C, 0x31, 0x57, 0xA1, - 0x42, 0x8D, 0x7B, 0x4C, 0x21, 0xF9, 0xCD, 0x7E, - 0x40, 0x71, 0xAE, 0xD7, 0x7B, 0x7C, 0xA9, 0xF1, - 0xC3, 0x8F, 0xBA, 0x32, 0x23, 0x74, 0x12, 0xEF, - 0x21, 0xA3, 0x42, 0x74, 0x2E, 0xC8, 0x32, 0x43, - 0x78, 0xF2, 0x1E, 0x50, 0x7F, 0xAF, 0xDD, 0x88 - }, - { - 0x46, 0x7A, 0x33, 0xFB, 0xAD, 0xF5, 0xEB, 0xC5, - 0x25, 0x96, 0xEF, 0x86, 0xAA, 0xAE, 0xFC, 0x6F, - 0xAB, 0xA8, 0xEE, 0x65, 0x1B, 0x1C, 0xE0, 0x4D, - 0xE3, 0x68, 0xA0, 0x3A, 0x5A, 0x90, 0x40, 0xEF, - 0x28, 0x35, 0xE0, 0x0A, 0xDB, 0x09, 0xAB, 0xB3, - 0xFB, 0xD2, 0xBC, 0xE8, 0x18, 0xA2, 0x41, 0x3D, - 0x0B, 0x02, 0x53, 0xB5, 0xBD, 0xA4, 0xFC, 0x5B, - 0x2F, 0x6F, 0x85, 0xF3, 0xFD, 0x5B, 0x55, 0xF2 - }, - { - 0x22, 0xEF, 0xF8, 0xE6, 0xDD, 0x52, 0x36, 0xF5, - 0xF5, 0x7D, 0x94, 0xED, 0xE8, 0x74, 0xD6, 0xC9, - 0x42, 0x8E, 0x8F, 0x5D, 0x56, 0x6F, 0x17, 0xCD, - 0x6D, 0x18, 0x48, 0xCD, 0x75, 0x2F, 0xE1, 0x3C, - 0x65, 0x5C, 0xB1, 0x0F, 0xBA, 0xAF, 0xF7, 0x68, - 0x72, 0xF2, 0xBF, 0x2D, 0xA9, 0x9E, 0x15, 0xDC, - 0x62, 0x40, 0x75, 0xE1, 0xEC, 0x2F, 0x58, 0xA3, - 0xF6, 0x40, 0x72, 0x12, 0x18, 0x38, 0x56, 0x9E - }, - { - 0x9C, 0xEC, 0x6B, 0xBF, 0x62, 0xC4, 0xBC, 0xE4, - 0x13, 0x8A, 0xBA, 0xE1, 0xCB, 0xEC, 0x8D, 0xAD, - 0x31, 0x95, 0x04, 0x44, 0xE9, 0x03, 0x21, 0xB1, - 0x34, 0x71, 0x96, 0x83, 0x4C, 0x11, 0x4B, 0x86, - 0x4A, 0xF3, 0xF3, 0xCC, 0x35, 0x08, 0xF8, 0x37, - 0x51, 0xFF, 0xB4, 0xED, 0xA7, 0xC8, 0x4D, 0x14, - 0x07, 0x34, 0xBB, 0x42, 0x63, 0xC3, 0x62, 0x5C, - 0x00, 0xF0, 0x4F, 0x4C, 0x80, 0x68, 0x98, 0x1B - }, - { - 0xA8, 0xB6, 0x0F, 0xA4, 0xFC, 0x24, 0x42, 0xF6, - 0xF1, 0x51, 0x4A, 0xD7, 0x40, 0x26, 0x26, 0x92, - 0x0C, 0xC7, 0xC2, 0xC9, 0xF7, 0x21, 0x24, 0xB8, - 0xCB, 0xA8, 0xEE, 0x2C, 0xB7, 0xC4, 0x58, 0x6F, - 0x65, 0x8A, 0x44, 0x10, 0xCF, 0xFC, 0xC0, 0xAB, - 0x88, 0x34, 0x39, 0x55, 0xE0, 0x94, 0xC6, 0xAF, - 0x0D, 0x20, 0xD0, 0xC7, 0x14, 0xFB, 0x0A, 0x98, - 0x8F, 0x54, 0x3F, 0x30, 0x0F, 0x58, 0xD3, 0x89 - }, - { - 0x82, 0x71, 0xCC, 0x45, 0xDF, 0xA5, 0xE4, 0x17, - 0x0E, 0x84, 0x7E, 0x86, 0x30, 0xB9, 0x52, 0xCF, - 0x9C, 0x2A, 0xA7, 0x77, 0xD0, 0x6F, 0x26, 0xA7, - 0x58, 0x5B, 0x83, 0x81, 0xF1, 0x88, 0xDA, 0xCC, - 0x73, 0x37, 0x39, 0x1C, 0xFC, 0xC9, 0x4B, 0x05, - 0x3D, 0xC4, 0xEC, 0x29, 0xCC, 0x17, 0xF0, 0x77, - 0x87, 0x04, 0x28, 0xF1, 0xAC, 0x23, 0xFD, 0xDD, - 0xA1, 0x65, 0xEF, 0x5A, 0x3F, 0x15, 0x5F, 0x39 - }, - { - 0xBF, 0x23, 0xC0, 0xC2, 0x5C, 0x80, 0x60, 0xE4, - 0xF6, 0x99, 0x5F, 0x16, 0x23, 0xA3, 0xBE, 0xBE, - 0xCA, 0xA9, 0x6E, 0x30, 0x86, 0x80, 0x00, 0x0A, - 0x8A, 0xA3, 0xCD, 0x56, 0xBB, 0x1A, 0x6D, 0xA0, - 0x99, 0xE1, 0x0D, 0x92, 0x31, 0xB3, 0x7F, 0x45, - 0x19, 0xB2, 0xEF, 0xD2, 0xC2, 0x4D, 0xE7, 0x2F, - 0x31, 0xA5, 0xF1, 0x95, 0x35, 0x24, 0x1B, 0x4A, - 0x59, 0xFA, 0x3C, 0x03, 0xCE, 0xB7, 0x90, 0xE7 - }, - { - 0x87, 0x7F, 0xD6, 0x52, 0xC0, 0x52, 0x81, 0x00, - 0x9C, 0x0A, 0x52, 0x50, 0xE7, 0xA3, 0xA6, 0x71, - 0xF8, 0xB1, 0x8C, 0x10, 0x88, 0x17, 0xFE, 0x4A, - 0x87, 0x4D, 0xE2, 0x2D, 0xA8, 0xE4, 0x5D, 0xB1, - 0x19, 0x58, 0xA6, 0x00, 0xC5, 0xF6, 0x2E, 0x67, - 0xD3, 0x6C, 0xBF, 0x84, 0x47, 0x4C, 0xF2, 0x44, - 0xA9, 0xC2, 0xB0, 0x3A, 0x9F, 0xB9, 0xDC, 0x71, - 0x1C, 0xD1, 0xA2, 0xCA, 0xB6, 0xF3, 0xFA, 0xE0 - }, - { - 0x29, 0xDF, 0x4D, 0x87, 0xEA, 0x44, 0x4B, 0xAF, - 0x5B, 0xCD, 0xF5, 0xF4, 0xE4, 0x15, 0x79, 0xE2, - 0x8A, 0x67, 0xDE, 0x84, 0x14, 0x9F, 0x06, 0xC0, - 0x3F, 0x11, 0x0E, 0xA8, 0x4F, 0x57, 0x2A, 0x9F, - 0x67, 0x6A, 0xDD, 0xD0, 0x4C, 0x48, 0x78, 0xF4, - 0x9C, 0x5C, 0x00, 0xAC, 0xCD, 0xA4, 0x41, 0xB1, - 0xA3, 0x87, 0xCA, 0xCE, 0xB2, 0xE9, 0x93, 0xBB, - 0x7A, 0x10, 0xCD, 0x8C, 0x2D, 0x67, 0x17, 0xE1 - }, - { - 0x71, 0x0D, 0xAC, 0xB1, 0x66, 0x84, 0x46, 0x39, - 0xCD, 0x7B, 0x63, 0x7C, 0x27, 0x42, 0x09, 0x42, - 0x4E, 0x24, 0x49, 0xDC, 0x35, 0xD7, 0x90, 0xBB, - 0xFA, 0x4F, 0x76, 0x17, 0x70, 0x54, 0xA3, 0x6B, - 0x3B, 0x76, 0xFA, 0xC0, 0xCA, 0x6E, 0x61, 0xDF, - 0x1E, 0x68, 0x70, 0x00, 0x67, 0x8A, 0xC0, 0x74, - 0x6D, 0xF7, 0x5D, 0x0A, 0x39, 0x54, 0x89, 0x76, - 0x81, 0xFD, 0x39, 0x3A, 0x15, 0x5A, 0x1B, 0xB4 - }, - { - 0xC1, 0xD5, 0xF9, 0x3B, 0x8D, 0xEA, 0x1F, 0x25, - 0x71, 0xBA, 0xBC, 0xCB, 0xC0, 0x17, 0x64, 0x54, - 0x1A, 0x0C, 0xDA, 0x87, 0xE4, 0x44, 0xD6, 0x73, - 0xC5, 0x09, 0x66, 0xCA, 0x55, 0x9C, 0x33, 0x35, - 0x4B, 0x3A, 0xCB, 0x26, 0xE5, 0xD5, 0x78, 0x1F, - 0xFB, 0x28, 0x84, 0x7A, 0x4B, 0x47, 0x54, 0xD7, - 0x70, 0x08, 0xC6, 0x2A, 0x83, 0x58, 0x35, 0xF5, - 0x00, 0xDE, 0xA7, 0xC3, 0xB5, 0x8B, 0xDA, 0xE2 - }, - { - 0xA4, 0x1E, 0x41, 0x27, 0x1C, 0xDA, 0xB8, 0xAF, - 0x4D, 0x72, 0xB1, 0x04, 0xBF, 0xB2, 0xAD, 0x04, - 0x1A, 0xC4, 0xDF, 0x14, 0x67, 0x7D, 0xA6, 0x71, - 0xD8, 0x56, 0x40, 0xC4, 0xB1, 0x87, 0xF5, 0x0C, - 0x2B, 0x66, 0x51, 0x3C, 0x46, 0x19, 0xFB, 0xD5, - 0xD5, 0xDC, 0x4F, 0xE6, 0x5D, 0xD3, 0x7B, 0x90, - 0x42, 0xE9, 0x84, 0x8D, 0xDA, 0x55, 0x6A, 0x50, - 0x4C, 0xAA, 0x2B, 0x1C, 0x6A, 0xFE, 0x47, 0x30 - }, - { - 0xE7, 0xBC, 0xBA, 0xCD, 0xC3, 0x79, 0xC4, 0x3D, - 0x81, 0xEB, 0xAD, 0xCB, 0x37, 0x78, 0x15, 0x52, - 0xFC, 0x1D, 0x75, 0x3E, 0x8C, 0xF3, 0x10, 0xD9, - 0x68, 0x39, 0x2D, 0x06, 0xC9, 0x1F, 0x1D, 0x64, - 0xCC, 0x9E, 0x90, 0xCE, 0x1D, 0x22, 0xC3, 0x2D, - 0x27, 0x7F, 0xC6, 0xCD, 0xA4, 0x33, 0xA4, 0xD4, - 0x42, 0xC7, 0x62, 0xE9, 0xEA, 0xCF, 0x2C, 0x25, - 0x9F, 0x32, 0xD6, 0x4C, 0xF9, 0xDA, 0x3A, 0x22 - }, - { - 0x51, 0x75, 0x5B, 0x4A, 0xC5, 0x45, 0x6B, 0x13, - 0x21, 0x8A, 0x19, 0xC5, 0xB9, 0x24, 0x2F, 0x57, - 0xC4, 0xA9, 0x81, 0xE4, 0xD4, 0xEC, 0xDC, 0xE0, - 0x9A, 0x31, 0x93, 0x36, 0x2B, 0x80, 0x8A, 0x57, - 0x93, 0x45, 0xD4, 0x88, 0x1C, 0x26, 0x07, 0xA5, - 0x65, 0x34, 0xDD, 0x7F, 0x21, 0x95, 0x6A, 0xFF, - 0x72, 0xC2, 0xF4, 0x17, 0x3A, 0x6E, 0x7B, 0x6C, - 0xC2, 0x21, 0x2B, 0xA0, 0xE3, 0xDA, 0xEE, 0x1F - }, - { - 0xDC, 0xC2, 0xC4, 0xBE, 0xB9, 0xC1, 0xF2, 0x60, - 0x7B, 0x78, 0x6C, 0x20, 0xC6, 0x31, 0x97, 0x23, - 0x47, 0x03, 0x4C, 0x1C, 0xC0, 0x2F, 0xCC, 0x7D, - 0x02, 0xFF, 0x01, 0x09, 0x9C, 0xFE, 0x1C, 0x69, - 0x89, 0x84, 0x0A, 0xC2, 0x13, 0x92, 0x36, 0x29, - 0x11, 0x3A, 0xA8, 0xBA, 0xD7, 0x13, 0xCC, 0xF0, - 0xFE, 0x4C, 0xE1, 0x32, 0x64, 0xFB, 0x32, 0xB8, - 0xB0, 0xFE, 0x37, 0x2D, 0xA3, 0x82, 0x54, 0x4A - }, - { - 0x3D, 0x55, 0x17, 0x6A, 0xCE, 0xA4, 0xA7, 0xE3, - 0xA6, 0x5F, 0xFA, 0x9F, 0xB1, 0x0A, 0x7A, 0x17, - 0x67, 0x19, 0x9C, 0xF0, 0x77, 0xCE, 0xE9, 0xF7, - 0x15, 0x32, 0xD6, 0x7C, 0xD7, 0xC7, 0x3C, 0x9F, - 0x93, 0xCF, 0xC3, 0x7C, 0xCD, 0xCC, 0x1F, 0xDE, - 0xF5, 0x0A, 0xAD, 0x46, 0xA5, 0x04, 0xA6, 0x50, - 0xD2, 0x98, 0xD5, 0x97, 0xA3, 0xA9, 0xFA, 0x95, - 0xC6, 0xC4, 0x0C, 0xB7, 0x1F, 0xA5, 0xE7, 0x25 - }, - { - 0xD0, 0x77, 0x13, 0xC0, 0x05, 0xDE, 0x96, 0xDD, - 0x21, 0xD2, 0xEB, 0x8B, 0xBE, 0xCA, 0x66, 0x74, - 0x6E, 0xA5, 0x1A, 0x31, 0xAE, 0x92, 0x2A, 0x3E, - 0x74, 0x86, 0x48, 0x89, 0x54, 0x0A, 0x48, 0xDB, - 0x27, 0xD7, 0xE4, 0xC9, 0x03, 0x11, 0x63, 0x8B, - 0x22, 0x4B, 0xF0, 0x20, 0x1B, 0x50, 0x18, 0x91, - 0x75, 0x48, 0x48, 0x11, 0x3C, 0x26, 0x61, 0x08, - 0xD0, 0xAD, 0xB1, 0x3D, 0xB7, 0x19, 0x09, 0xC7 - }, - { - 0x58, 0x98, 0x3C, 0x21, 0x43, 0x3D, 0x95, 0x0C, - 0xAA, 0x23, 0xE4, 0xBC, 0x18, 0x54, 0x3B, 0x8E, - 0x60, 0x1C, 0x20, 0x43, 0x18, 0x53, 0x21, 0x52, - 0xDA, 0xF5, 0xE1, 0x59, 0xA0, 0xCD, 0x14, 0x80, - 0x18, 0x3D, 0x29, 0x28, 0x5C, 0x05, 0xF1, 0x29, - 0xCB, 0x0C, 0xC3, 0x16, 0x46, 0x87, 0x92, 0x80, - 0x86, 0xFF, 0xE3, 0x80, 0x15, 0x8D, 0xF1, 0xD3, - 0x94, 0xC6, 0xAC, 0x0D, 0x42, 0x88, 0xBC, 0xA8 - }, - { - 0x81, 0x00, 0xA8, 0xDC, 0x52, 0x8D, 0x2B, 0x68, - 0x2A, 0xB4, 0x25, 0x08, 0x01, 0xBA, 0x33, 0xF0, - 0x2A, 0x3E, 0x94, 0xC5, 0x4D, 0xAC, 0x0A, 0xE1, - 0x48, 0x2A, 0xA2, 0x1F, 0x51, 0xEF, 0x3A, 0x82, - 0xF3, 0x80, 0x7E, 0x6F, 0xAC, 0xB0, 0xAE, 0xB0, - 0x59, 0x47, 0xBF, 0x7A, 0xA2, 0xAD, 0xCB, 0x03, - 0x43, 0x56, 0xF9, 0x0F, 0xA4, 0x56, 0x0E, 0xDE, - 0x02, 0x20, 0x1A, 0x37, 0xE4, 0x11, 0xEC, 0x1A - }, - { - 0x07, 0x02, 0x5F, 0x1B, 0xB6, 0xC7, 0x84, 0xF3, - 0xFE, 0x49, 0xDE, 0x5C, 0x14, 0xB9, 0x36, 0xA5, - 0xAC, 0xAC, 0xAC, 0xAA, 0xB3, 0x3F, 0x6A, 0xC4, - 0xD0, 0xE0, 0x0A, 0xB6, 0xA1, 0x24, 0x83, 0xD6, - 0xBE, 0xC0, 0x0B, 0x4F, 0xE6, 0x7C, 0x7C, 0xA5, - 0xCC, 0x50, 0x8C, 0x2A, 0x53, 0xEF, 0xB5, 0xBF, - 0xA5, 0x39, 0x87, 0x69, 0xD8, 0x43, 0xFF, 0x0D, - 0x9E, 0x8B, 0x14, 0xD3, 0x6A, 0x01, 0xA7, 0x7F - }, - { - 0xBA, 0x6A, 0xEF, 0xD9, 0x72, 0xB6, 0x18, 0x6E, - 0x02, 0x7A, 0x76, 0x27, 0x3A, 0x4A, 0x72, 0x33, - 0x21, 0xA3, 0xF5, 0x80, 0xCF, 0xA8, 0x94, 0xDA, - 0x5A, 0x9C, 0xE8, 0xE7, 0x21, 0xC8, 0x28, 0x55, - 0x2C, 0x64, 0xDA, 0xCE, 0xE3, 0xA7, 0xFD, 0x2D, - 0x74, 0x3B, 0x5C, 0x35, 0xAD, 0x0C, 0x8E, 0xFA, - 0x71, 0xF8, 0xCE, 0x99, 0xBF, 0x96, 0x33, 0x47, - 0x10, 0xE2, 0xC2, 0x34, 0x6E, 0x8F, 0x3C, 0x52 - }, - { - 0xE0, 0x72, 0x1E, 0x02, 0x51, 0x7A, 0xED, 0xFA, - 0x4E, 0x7E, 0x9B, 0xA5, 0x03, 0xE0, 0x25, 0xFD, - 0x46, 0xE7, 0x14, 0x56, 0x6D, 0xC8, 0x89, 0xA8, - 0x4C, 0xBF, 0xE5, 0x6A, 0x55, 0xDF, 0xBE, 0x2F, - 0xC4, 0x93, 0x8A, 0xC4, 0x12, 0x05, 0x88, 0x33, - 0x5D, 0xEA, 0xC8, 0xEF, 0x3F, 0xA2, 0x29, 0xAD, - 0xC9, 0x64, 0x7F, 0x54, 0xAD, 0x2E, 0x34, 0x72, - 0x23, 0x4F, 0x9B, 0x34, 0xEF, 0xC4, 0x65, 0x43 - }, - { - 0xB6, 0x29, 0x26, 0x69, 0xCC, 0xD3, 0x8D, 0x5F, - 0x01, 0xCA, 0xAE, 0x96, 0xBA, 0x27, 0x2C, 0x76, - 0xA8, 0x79, 0xA4, 0x57, 0x43, 0xAF, 0xA0, 0x72, - 0x5D, 0x83, 0xB9, 0xEB, 0xB2, 0x66, 0x65, 0xB7, - 0x31, 0xF1, 0x84, 0x8C, 0x52, 0xF1, 0x19, 0x72, - 0xB6, 0x64, 0x4F, 0x55, 0x4C, 0x06, 0x4F, 0xA9, - 0x07, 0x80, 0xDB, 0xBB, 0xF3, 0xA8, 0x9D, 0x4F, - 0xC3, 0x1F, 0x67, 0xDF, 0x3E, 0x58, 0x57, 0xEF - }, - { - 0x23, 0x19, 0xE3, 0x78, 0x9C, 0x47, 0xE2, 0xDA, - 0xA5, 0xFE, 0x80, 0x7F, 0x61, 0xBE, 0xC2, 0xA1, - 0xA6, 0x53, 0x7F, 0xA0, 0x3F, 0x19, 0xFF, 0x32, - 0xE8, 0x7E, 0xEC, 0xBF, 0xD6, 0x4B, 0x7E, 0x0E, - 0x8C, 0xCF, 0xF4, 0x39, 0xAC, 0x33, 0x3B, 0x04, - 0x0F, 0x19, 0xB0, 0xC4, 0xDD, 0xD1, 0x1A, 0x61, - 0xE2, 0x4A, 0xC1, 0xFE, 0x0F, 0x10, 0xA0, 0x39, - 0x80, 0x6C, 0x5D, 0xCC, 0x0D, 0xA3, 0xD1, 0x15 - }, - { - 0xF5, 0x97, 0x11, 0xD4, 0x4A, 0x03, 0x1D, 0x5F, - 0x97, 0xA9, 0x41, 0x3C, 0x06, 0x5D, 0x1E, 0x61, - 0x4C, 0x41, 0x7E, 0xDE, 0x99, 0x85, 0x90, 0x32, - 0x5F, 0x49, 0xBA, 0xD2, 0xFD, 0x44, 0x4D, 0x3E, - 0x44, 0x18, 0xBE, 0x19, 0xAE, 0xC4, 0xE1, 0x14, - 0x49, 0xAC, 0x1A, 0x57, 0x20, 0x78, 0x98, 0xBC, - 0x57, 0xD7, 0x6A, 0x1B, 0xCF, 0x35, 0x66, 0x29, - 0x2C, 0x20, 0xC6, 0x83, 0xA5, 0xC4, 0x64, 0x8F - }, - { - 0xDF, 0x0A, 0x9D, 0x0C, 0x21, 0x28, 0x43, 0xA6, - 0xA9, 0x34, 0xE3, 0x90, 0x2B, 0x2D, 0xD3, 0x0D, - 0x17, 0xFB, 0xA5, 0xF9, 0x69, 0xD2, 0x03, 0x0B, - 0x12, 0xA5, 0x46, 0xD8, 0xA6, 0xA4, 0x5E, 0x80, - 0xCF, 0x56, 0x35, 0xF0, 0x71, 0xF0, 0x45, 0x2E, - 0x9C, 0x91, 0x92, 0x75, 0xDA, 0x99, 0xBE, 0xD5, - 0x1E, 0xB1, 0x17, 0x3C, 0x1A, 0xF0, 0x51, 0x87, - 0x26, 0xB7, 0x5B, 0x0E, 0xC3, 0xBA, 0xE2, 0xB5 - }, - { - 0xA3, 0xEB, 0x6E, 0x6C, 0x7B, 0xF2, 0xFB, 0x8B, - 0x28, 0xBF, 0xE8, 0xB1, 0x5E, 0x15, 0xBB, 0x50, - 0x0F, 0x78, 0x1E, 0xCC, 0x86, 0xF7, 0x78, 0xC3, - 0xA4, 0xE6, 0x55, 0xFC, 0x58, 0x69, 0xBF, 0x28, - 0x46, 0xA2, 0x45, 0xD4, 0xE3, 0x3B, 0x7B, 0x14, - 0x43, 0x6A, 0x17, 0xE6, 0x3B, 0xE7, 0x9B, 0x36, - 0x65, 0x5C, 0x22, 0x6A, 0x50, 0xFF, 0xBC, 0x71, - 0x24, 0x20, 0x7B, 0x02, 0x02, 0x34, 0x2D, 0xB5 - }, - { - 0x56, 0xD4, 0xCB, 0xCD, 0x07, 0x05, 0x63, 0x42, - 0x6A, 0x01, 0x70, 0x69, 0x42, 0x5C, 0x2C, 0xD2, - 0xAE, 0x54, 0x06, 0x68, 0x28, 0x7A, 0x5F, 0xB9, - 0xDA, 0xC4, 0x32, 0xEB, 0x8A, 0xB1, 0xA3, 0x53, - 0xA3, 0x0F, 0x2F, 0xE1, 0xF4, 0x0D, 0x83, 0x33, - 0x3A, 0xFE, 0x69, 0x6A, 0x26, 0x77, 0x95, 0x40, - 0x8A, 0x92, 0xFE, 0x7D, 0xA0, 0x7A, 0x0C, 0x18, - 0x14, 0xCF, 0x77, 0xF3, 0x6E, 0x10, 0x5E, 0xE8 - }, - { - 0xE5, 0x9B, 0x99, 0x87, 0xD4, 0x28, 0xB3, 0xED, - 0xA3, 0x7D, 0x80, 0xAB, 0xDB, 0x16, 0xCD, 0x2B, - 0x0A, 0xEF, 0x67, 0x4C, 0x2B, 0x1D, 0xDA, 0x44, - 0x32, 0xEA, 0x91, 0xEE, 0x6C, 0x93, 0x5C, 0x68, - 0x4B, 0x48, 0xB4, 0x42, 0x8A, 0x8C, 0xC7, 0x40, - 0xE5, 0x79, 0xA3, 0x0D, 0xEF, 0xF3, 0x5A, 0x80, - 0x30, 0x13, 0x82, 0x0D, 0xD2, 0x3F, 0x14, 0xAE, - 0x1D, 0x84, 0x13, 0xB5, 0xC8, 0x67, 0x2A, 0xEC - }, - { - 0xCD, 0x9F, 0xCC, 0x99, 0xF9, 0x9D, 0x4C, 0xC1, - 0x6D, 0x03, 0x19, 0x00, 0xB2, 0xA7, 0x36, 0xE1, - 0x50, 0x8D, 0xB4, 0xB5, 0x86, 0x81, 0x4E, 0x63, - 0x45, 0x85, 0x7F, 0x35, 0x4A, 0x70, 0xCC, 0xEC, - 0xB1, 0xDF, 0x3B, 0x50, 0xA1, 0x9A, 0xDA, 0xF4, - 0x3C, 0x27, 0x8E, 0xFA, 0x42, 0x3F, 0xF4, 0xBB, - 0x6C, 0x52, 0x3E, 0xC7, 0xFD, 0x78, 0x59, 0xB9, - 0x7B, 0x16, 0x8A, 0x7E, 0xBF, 0xF8, 0x46, 0x7C - }, - { - 0x06, 0x02, 0x18, 0x5D, 0x8C, 0x3A, 0x78, 0x73, - 0x8B, 0x99, 0x16, 0x4B, 0x8B, 0xC6, 0xFF, 0xB2, - 0x1C, 0x7D, 0xEB, 0xEB, 0xBF, 0x80, 0x63, 0x72, - 0xE0, 0xDA, 0x44, 0xD1, 0x21, 0x54, 0x55, 0x97, - 0xB9, 0xC6, 0x62, 0xA2, 0x55, 0xDC, 0x31, 0x54, - 0x2C, 0xF9, 0x95, 0xEC, 0xBE, 0x6A, 0x50, 0xFB, - 0x5E, 0x6E, 0x0E, 0xE4, 0xEF, 0x24, 0x0F, 0xE5, - 0x57, 0xED, 0xED, 0x11, 0x88, 0x08, 0x7E, 0x86 - }, - { - 0xC0, 0x8A, 0xFA, 0x5B, 0x92, 0x7B, 0xF0, 0x80, - 0x97, 0xAF, 0xC5, 0xFF, 0xF9, 0xCA, 0x4E, 0x78, - 0x00, 0x12, 0x5C, 0x1F, 0x52, 0xF2, 0xAF, 0x35, - 0x53, 0xFA, 0x2B, 0x89, 0xE1, 0xE3, 0x01, 0x5C, - 0x4F, 0x87, 0xD5, 0xE0, 0xA4, 0x89, 0x56, 0xAD, - 0x31, 0x45, 0x0B, 0x08, 0x3D, 0xAD, 0x14, 0x7F, - 0xFB, 0x5E, 0xC0, 0x34, 0x34, 0xA2, 0x68, 0x30, - 0xCF, 0x37, 0xD1, 0x03, 0xAB, 0x50, 0xC5, 0xDA - }, - { - 0x36, 0xF1, 0xE1, 0xC1, 0x1D, 0x6E, 0xF6, 0xBC, - 0x3B, 0x53, 0x6D, 0x50, 0x5D, 0x54, 0x4A, 0x87, - 0x15, 0x22, 0xC5, 0xC2, 0xA2, 0x53, 0x06, 0x7E, - 0xC9, 0x93, 0x3B, 0x6E, 0xC2, 0x54, 0x64, 0xDA, - 0xF9, 0x85, 0x52, 0x5F, 0x5B, 0x95, 0x60, 0xA1, - 0x6D, 0x89, 0x02, 0x59, 0xAC, 0x1B, 0xB5, 0xCC, - 0x67, 0xC0, 0xC4, 0x69, 0xCD, 0xE1, 0x33, 0xDE, - 0xF0, 0x00, 0xEA, 0x1D, 0x68, 0x6F, 0x4F, 0x5D - }, - { - 0xBF, 0x2A, 0xB2, 0xE2, 0x47, 0x0F, 0x54, 0x38, - 0xC3, 0xB6, 0x89, 0xE6, 0x6E, 0x76, 0x86, 0xFF, - 0xFA, 0x0C, 0xB1, 0xE1, 0x79, 0x8A, 0xD3, 0xA8, - 0x6F, 0xF9, 0x90, 0x75, 0xBF, 0x61, 0x38, 0xE3, - 0x3D, 0x9C, 0x0C, 0xE5, 0x9A, 0xFB, 0x24, 0xAC, - 0x67, 0xA0, 0x2A, 0xF3, 0x44, 0x28, 0x19, 0x1A, - 0x9A, 0x0A, 0x60, 0x41, 0xC0, 0x74, 0x71, 0xB7, - 0xC3, 0xB1, 0xA7, 0x52, 0xD6, 0xFC, 0x0B, 0x8B - }, - { - 0xD4, 0x00, 0x60, 0x1F, 0x97, 0x28, 0xCC, 0xC4, - 0xC9, 0x23, 0x42, 0xD9, 0x78, 0x7D, 0x8D, 0x28, - 0xAB, 0x32, 0x3A, 0xF3, 0x75, 0xCA, 0x56, 0x24, - 0xB4, 0xBB, 0x91, 0xD1, 0x72, 0x71, 0xFB, 0xAE, - 0x86, 0x2E, 0x41, 0x3B, 0xE7, 0x3F, 0x1F, 0x68, - 0xE6, 0x15, 0xB8, 0xC5, 0xC3, 0x91, 0xBE, 0x0D, - 0xBD, 0x91, 0x44, 0x74, 0x6E, 0xB3, 0x39, 0xAD, - 0x54, 0x15, 0x47, 0xBA, 0x9C, 0x46, 0x8A, 0x17 - }, - { - 0x79, 0xFE, 0x2F, 0xE1, 0x57, 0xEB, 0x85, 0xA0, - 0x38, 0xAB, 0xB8, 0xEB, 0xBC, 0x64, 0x77, 0x31, - 0xD2, 0xC8, 0x3F, 0x51, 0xB0, 0xAC, 0x6E, 0xE1, - 0x4A, 0xA2, 0x84, 0xCB, 0x6A, 0x35, 0x49, 0xA4, - 0xDC, 0xCE, 0xB3, 0x00, 0x74, 0x0A, 0x82, 0x5F, - 0x52, 0xF5, 0xFB, 0x30, 0xB0, 0x3B, 0x8C, 0x4D, - 0x8B, 0x0F, 0x4A, 0xA6, 0x7A, 0x63, 0xF4, 0xA9, - 0x4E, 0x33, 0x03, 0xC4, 0xED, 0xA4, 0xC0, 0x2B - }, - { - 0x75, 0x35, 0x13, 0x13, 0xB5, 0x2A, 0x85, 0x29, - 0x29, 0x8D, 0x8C, 0x18, 0x6B, 0x17, 0x68, 0x66, - 0x6D, 0xCC, 0xA8, 0x59, 0x53, 0x17, 0xD7, 0xA4, - 0x81, 0x6E, 0xB8, 0x8C, 0x06, 0x20, 0x20, 0xC0, - 0xC8, 0xEF, 0xC5, 0x54, 0xBB, 0x34, 0x1B, 0x64, - 0x68, 0x8D, 0xB5, 0xCC, 0xAF, 0xC3, 0x5F, 0x3C, - 0x3C, 0xD0, 0x9D, 0x65, 0x64, 0xB3, 0x6D, 0x7B, - 0x04, 0xA2, 0x48, 0xE1, 0x46, 0x98, 0x0D, 0x4B - }, - { - 0xE3, 0x12, 0x8B, 0x1D, 0x31, 0x1D, 0x02, 0x17, - 0x9D, 0x7F, 0x25, 0xF9, 0x7A, 0x5A, 0x8B, 0xEE, - 0x2C, 0xC8, 0xC8, 0x63, 0x03, 0x64, 0x4F, 0xCD, - 0x66, 0x4E, 0x15, 0x7D, 0x1F, 0xEF, 0x00, 0xF2, - 0x3E, 0x46, 0xF9, 0xA5, 0xE8, 0xE5, 0xC8, 0x90, - 0xCE, 0x56, 0x5B, 0xB6, 0xAB, 0xD4, 0x30, 0x2C, - 0xE0, 0x64, 0x69, 0xD5, 0x2A, 0x5B, 0xD5, 0x3E, - 0x1C, 0x5A, 0x54, 0xD0, 0x46, 0x49, 0xDC, 0x03 - }, - { - 0xC2, 0x38, 0x2A, 0x72, 0xD2, 0xD3, 0xAC, 0xE9, - 0xD5, 0x93, 0x3D, 0x00, 0xB6, 0x08, 0x27, 0xED, - 0x38, 0x0C, 0xDA, 0x08, 0xD0, 0xBA, 0x5F, 0x6D, - 0xD4, 0x1E, 0x29, 0xEE, 0x6D, 0xBE, 0x8E, 0xCB, - 0x92, 0x35, 0xF0, 0x6B, 0xE9, 0x5D, 0x83, 0xB6, - 0x81, 0x6A, 0x2F, 0xB7, 0xA5, 0xAD, 0x47, 0x03, - 0x5E, 0x8A, 0x4B, 0x69, 0xA4, 0x88, 0x4B, 0x99, - 0xE4, 0xBE, 0xCE, 0x58, 0xCA, 0xB2, 0x5D, 0x44 - }, - { - 0x6B, 0x1C, 0x69, 0x46, 0x0B, 0xBD, 0x50, 0xAC, - 0x2E, 0xD6, 0xF3, 0x2E, 0x6E, 0x88, 0x7C, 0xFE, - 0xD4, 0x07, 0xD4, 0x7D, 0xCF, 0x0A, 0xAA, 0x60, - 0x38, 0x7F, 0xE3, 0x20, 0xD7, 0x80, 0xBD, 0x03, - 0xEA, 0xB6, 0xD7, 0xBA, 0xEB, 0x2A, 0x07, 0xD1, - 0x0C, 0xD5, 0x52, 0xA3, 0x00, 0x34, 0x13, 0x54, - 0xEA, 0x9A, 0x5F, 0x03, 0x18, 0x3A, 0x62, 0x3F, - 0x92, 0xA2, 0xD4, 0xD9, 0xF0, 0x09, 0x26, 0xAF - }, - { - 0x6C, 0xDA, 0x20, 0x6C, 0x80, 0xCD, 0xC9, 0xC4, - 0x4B, 0xA9, 0x90, 0xE0, 0x32, 0x8C, 0x31, 0x4F, - 0x81, 0x9B, 0x14, 0x2D, 0x00, 0x63, 0x04, 0x04, - 0xC4, 0x8C, 0x05, 0xDC, 0x76, 0xD1, 0xB0, 0x0C, - 0xE4, 0xD7, 0x2F, 0xC6, 0xA4, 0x8E, 0x14, 0x69, - 0xDD, 0xEF, 0x60, 0x94, 0x12, 0xC3, 0x64, 0x82, - 0x08, 0x54, 0x21, 0x4B, 0x48, 0x69, 0xAF, 0x09, - 0x0F, 0x00, 0xD3, 0xC1, 0xBA, 0x44, 0x3E, 0x1B - }, - { - 0x7F, 0xFC, 0x8C, 0x26, 0xFB, 0xD6, 0xA0, 0xF7, - 0xA6, 0x09, 0xE6, 0xE1, 0x93, 0x9F, 0x6A, 0x9E, - 0xDF, 0x1B, 0x0B, 0x06, 0x66, 0x41, 0xFB, 0x76, - 0xC4, 0xF9, 0x60, 0x2E, 0xD7, 0x48, 0xD1, 0x16, - 0x02, 0x49, 0x6B, 0x35, 0x35, 0x5B, 0x1A, 0xA2, - 0x55, 0x85, 0x0A, 0x50, 0x9D, 0x2F, 0x8E, 0xE1, - 0x8C, 0x8F, 0x3E, 0x1D, 0x7D, 0xCB, 0xC3, 0x7A, - 0x13, 0x65, 0x98, 0xF5, 0x6A, 0x59, 0xED, 0x17 - }, - { - 0x70, 0xDE, 0x1F, 0x08, 0xDD, 0x4E, 0x09, 0xD5, - 0xFC, 0x15, 0x1F, 0x17, 0xFC, 0x99, 0x1A, 0x23, - 0xAB, 0xFC, 0x05, 0x10, 0x42, 0x90, 0xD5, 0x04, - 0x68, 0x88, 0x2E, 0xFA, 0xF5, 0x82, 0xB6, 0xEC, - 0x2F, 0x14, 0xF5, 0x77, 0xC0, 0xD6, 0x8C, 0x3A, - 0xD0, 0x66, 0x26, 0x91, 0x6E, 0x3C, 0x86, 0xE6, - 0xDA, 0xAB, 0x6C, 0x53, 0xE5, 0x16, 0x3E, 0x82, - 0xB6, 0xBD, 0x0C, 0xE4, 0x9F, 0xC0, 0xD8, 0xDF - }, - { - 0x4F, 0x81, 0x93, 0x57, 0x56, 0xED, 0x35, 0xEE, - 0x20, 0x58, 0xEE, 0x0C, 0x6A, 0x61, 0x10, 0xD6, - 0xFA, 0xC5, 0xCB, 0x6A, 0x4F, 0x46, 0xAA, 0x94, - 0x11, 0x60, 0x3F, 0x99, 0x96, 0x58, 0x23, 0xB6, - 0xDA, 0x48, 0x38, 0x27, 0x6C, 0x5C, 0x06, 0xBC, - 0x78, 0x80, 0xE3, 0x76, 0xD9, 0x27, 0x58, 0x36, - 0x9E, 0xE7, 0x30, 0x5B, 0xCE, 0xC8, 0xD3, 0xCF, - 0xD2, 0x8C, 0xCA, 0xBB, 0x7B, 0x4F, 0x05, 0x79 - }, - { - 0xAB, 0xCB, 0x61, 0xCB, 0x36, 0x83, 0xD1, 0x8F, - 0x27, 0xAD, 0x52, 0x79, 0x08, 0xED, 0x2D, 0x32, - 0xA0, 0x42, 0x6C, 0xB7, 0xBB, 0x4B, 0xF1, 0x80, - 0x61, 0x90, 0x3A, 0x7D, 0xC4, 0x2E, 0x7E, 0x76, - 0xF9, 0x82, 0x38, 0x23, 0x04, 0xD1, 0x8A, 0xF8, - 0xC8, 0x0D, 0x91, 0xDD, 0x58, 0xDD, 0x47, 0xAF, - 0x76, 0xF8, 0xE2, 0xC3, 0x6E, 0x28, 0xAF, 0x24, - 0x76, 0xB4, 0xBC, 0xCF, 0x82, 0xE8, 0x9F, 0xDF - }, - { - 0x02, 0xD2, 0x61, 0xAD, 0x56, 0xA5, 0x26, 0x33, - 0x1B, 0x64, 0x3D, 0xD2, 0x18, 0x6D, 0xE9, 0xA8, - 0x2E, 0x72, 0xA5, 0x82, 0x23, 0xCD, 0x1E, 0x72, - 0x36, 0x86, 0xC5, 0x3D, 0x86, 0x9B, 0x83, 0xB9, - 0x46, 0x32, 0xB7, 0xB6, 0x47, 0xAB, 0x2A, 0xFC, - 0x0D, 0x52, 0x2E, 0x29, 0xDA, 0x3A, 0x56, 0x15, - 0xB7, 0x41, 0xD8, 0x28, 0x52, 0xE0, 0xDF, 0x41, - 0xB6, 0x60, 0x07, 0xDB, 0xCB, 0xA9, 0x05, 0x43 - }, - { - 0xC5, 0x83, 0x27, 0x41, 0xFA, 0x30, 0xC5, 0x43, - 0x68, 0x23, 0x01, 0x53, 0x83, 0xD2, 0x97, 0xFF, - 0x4C, 0x4A, 0x5D, 0x72, 0x76, 0xC3, 0xF9, 0x02, - 0x12, 0x20, 0x66, 0xE0, 0x4B, 0xE5, 0x43, 0x1B, - 0x1A, 0x85, 0xFA, 0xF7, 0x3B, 0x91, 0x84, 0x34, - 0xF9, 0x30, 0x09, 0x63, 0xD1, 0xDE, 0xA9, 0xE8, - 0xAC, 0x39, 0x24, 0xEF, 0x49, 0x02, 0x26, 0xED, - 0xEE, 0xA5, 0xF7, 0x43, 0xE4, 0x10, 0x66, 0x9F - }, - { - 0xCF, 0xAE, 0xAB, 0x26, 0x8C, 0xD0, 0x75, 0xA5, - 0xA6, 0xAE, 0xD5, 0x15, 0x02, 0x3A, 0x03, 0x2D, - 0x54, 0xF2, 0xF2, 0xFF, 0x73, 0x3C, 0xE0, 0xCB, - 0xC7, 0x8D, 0xB5, 0x1D, 0xB4, 0x50, 0x4D, 0x67, - 0x59, 0x23, 0xF8, 0x27, 0x46, 0xD6, 0x59, 0x46, - 0x06, 0xAD, 0x5D, 0x67, 0x73, 0x4B, 0x11, 0xA6, - 0x7C, 0xC6, 0xA4, 0x68, 0xC2, 0x03, 0x2E, 0x43, - 0xCA, 0x1A, 0x94, 0xC6, 0x27, 0x3A, 0x98, 0x5E - }, - { - 0x86, 0x08, 0x50, 0xF9, 0x2E, 0xB2, 0x68, 0x27, - 0x2B, 0x67, 0xD1, 0x33, 0x60, 0x9B, 0xD6, 0x4E, - 0x34, 0xF6, 0x1B, 0xF0, 0x3F, 0x4C, 0x17, 0x38, - 0x64, 0x5C, 0x17, 0xFE, 0xC8, 0x18, 0x46, 0x5D, - 0x7E, 0xCD, 0x2B, 0xE2, 0x90, 0x76, 0x41, 0x13, - 0x00, 0x25, 0xFD, 0xA7, 0x94, 0x70, 0xAB, 0x73, - 0x16, 0x46, 0xE7, 0xF6, 0x94, 0x40, 0xE8, 0x36, - 0x7E, 0xA7, 0x6A, 0xC4, 0xCE, 0xE8, 0xA1, 0xDF - }, - { - 0x84, 0xB1, 0x54, 0xED, 0x29, 0xBB, 0xED, 0xEF, - 0xA6, 0x48, 0x28, 0x68, 0x39, 0x04, 0x6F, 0x4B, - 0x5A, 0xA3, 0x44, 0x30, 0xE2, 0xD6, 0x7F, 0x74, - 0x96, 0xE4, 0xC3, 0x9F, 0x2C, 0x7E, 0xA7, 0x89, - 0x95, 0xF6, 0x9E, 0x12, 0x92, 0x20, 0x00, 0x16, - 0xF1, 0x6A, 0xC3, 0xB3, 0x77, 0x00, 0xE6, 0xC7, - 0xE7, 0x86, 0x1A, 0xFC, 0x39, 0x6B, 0x64, 0xA5, - 0x9A, 0x1D, 0xBF, 0x47, 0xA5, 0x5C, 0x4B, 0xBC - }, - { - 0xAE, 0xEE, 0xC2, 0x60, 0xA5, 0xD8, 0xEF, 0xF5, - 0xCC, 0xAB, 0x8B, 0x95, 0xDA, 0x43, 0x5A, 0x63, - 0xED, 0x7A, 0x21, 0xEA, 0x7F, 0xC7, 0x55, 0x94, - 0x13, 0xFD, 0x61, 0x7E, 0x33, 0x60, 0x9F, 0x8C, - 0x29, 0x0E, 0x64, 0xBB, 0xAC, 0xC5, 0x28, 0xF6, - 0xC0, 0x80, 0x26, 0x22, 0x88, 0xB0, 0xF0, 0xA3, - 0x21, 0x9B, 0xE2, 0x23, 0xC9, 0x91, 0xBE, 0xE9, - 0x2E, 0x72, 0x34, 0x95, 0x93, 0xE6, 0x76, 0x38 - }, - { - 0x8A, 0xD7, 0x8A, 0x9F, 0x26, 0x60, 0x1D, 0x12, - 0x7E, 0x8D, 0x2F, 0x2F, 0x97, 0x6E, 0x63, 0xD1, - 0x9A, 0x05, 0x4A, 0x17, 0xDC, 0xF5, 0x9E, 0x0F, - 0x01, 0x3A, 0xB5, 0x4A, 0x68, 0x87, 0xBB, 0xDF, - 0xFD, 0xE7, 0xAA, 0xAE, 0x11, 0x7E, 0x0F, 0xBF, - 0x32, 0x71, 0x01, 0x65, 0x95, 0xB9, 0xD9, 0xC7, - 0x12, 0xC0, 0x1B, 0x2C, 0x53, 0xE9, 0x65, 0x5A, - 0x38, 0x2B, 0xC4, 0x52, 0x2E, 0x61, 0x66, 0x45 - }, - { - 0x89, 0x34, 0x15, 0x9D, 0xAD, 0xE1, 0xAC, 0x74, - 0x14, 0x7D, 0xFA, 0x28, 0x2C, 0x75, 0x95, 0x4F, - 0xCE, 0xF4, 0x43, 0xEF, 0x25, 0xF8, 0x0D, 0xFE, - 0x9F, 0xB6, 0xEA, 0x63, 0x3B, 0x85, 0x45, 0x11, - 0x1D, 0x08, 0xB3, 0x4E, 0xF4, 0x3F, 0xFF, 0x17, - 0x02, 0x6C, 0x79, 0x64, 0xF5, 0xDE, 0xAC, 0x6D, - 0x2B, 0x3C, 0x29, 0xDA, 0xCF, 0x27, 0x47, 0xF0, - 0x22, 0xDF, 0x59, 0x67, 0xDF, 0xDC, 0x1A, 0x0A - }, - { - 0xCD, 0x36, 0xDD, 0x0B, 0x24, 0x06, 0x14, 0xCF, - 0x2F, 0xA2, 0xB9, 0xE9, 0x59, 0x67, 0x9D, 0xCD, - 0xD7, 0x2E, 0xC0, 0xCD, 0x58, 0xA4, 0x3D, 0xA3, - 0x79, 0x0A, 0x92, 0xF6, 0xCD, 0xEB, 0x9E, 0x1E, - 0x79, 0x5E, 0x47, 0x8A, 0x0A, 0x47, 0xD3, 0x71, - 0x10, 0x0D, 0x34, 0x0C, 0x5C, 0xED, 0xCD, 0xBB, - 0xC9, 0xE6, 0x8B, 0x3F, 0x46, 0x08, 0x18, 0xE5, - 0xBD, 0xFF, 0x7B, 0x4C, 0xDA, 0x4C, 0x27, 0x44 - }, - { - 0x00, 0xDF, 0x4E, 0x09, 0x9B, 0x80, 0x71, 0x37, - 0xA8, 0x59, 0x90, 0xF4, 0x9D, 0x3A, 0x94, 0x31, - 0x5E, 0x5A, 0x5F, 0x7F, 0x7A, 0x60, 0x76, 0xB3, - 0x03, 0xE9, 0x6B, 0x05, 0x6F, 0xB9, 0x38, 0x00, - 0x11, 0x1F, 0x47, 0x96, 0x28, 0xE2, 0xF8, 0xDB, - 0x59, 0xAE, 0xB6, 0xAC, 0x70, 0xC3, 0xB6, 0x1F, - 0x51, 0xF9, 0xB4, 0x6E, 0x80, 0xFF, 0xDE, 0xAE, - 0x25, 0xEB, 0xDD, 0xB4, 0xAF, 0x6C, 0xB4, 0xEE - }, - { - 0x2B, 0x9C, 0x95, 0x5E, 0x6C, 0xAE, 0xD4, 0xB7, - 0xC9, 0xE2, 0x46, 0xB8, 0x6F, 0x9A, 0x17, 0x26, - 0xE8, 0x10, 0xC5, 0x9D, 0x12, 0x6C, 0xEE, 0x66, - 0xED, 0x71, 0xBF, 0x01, 0x5B, 0x83, 0x55, 0x8A, - 0x4B, 0x6D, 0x84, 0xD1, 0x8D, 0xC3, 0xFF, 0x46, - 0x20, 0xC2, 0xFF, 0xB7, 0x22, 0x35, 0x9F, 0xDE, - 0xF8, 0x5B, 0xA0, 0xD4, 0xE2, 0xD2, 0x2E, 0xCB, - 0xE0, 0xED, 0x78, 0x4F, 0x99, 0xAF, 0xE5, 0x87 - }, - { - 0x18, 0x1D, 0xF0, 0xA2, 0x61, 0xA2, 0xF7, 0xD2, - 0x9E, 0xA5, 0xA1, 0x57, 0x72, 0x71, 0x51, 0x05, - 0xD4, 0x50, 0xA4, 0xB6, 0xC2, 0x36, 0xF6, 0x99, - 0xF4, 0x62, 0xD6, 0x0C, 0xA7, 0x64, 0x87, 0xFE, - 0xED, 0xFC, 0x9F, 0x5E, 0xB9, 0x2D, 0xF8, 0x38, - 0xE8, 0xFB, 0x5D, 0xC3, 0x69, 0x4E, 0x84, 0xC5, - 0xE0, 0xF4, 0xA1, 0x0B, 0x76, 0x1F, 0x50, 0x67, - 0x62, 0xBE, 0x05, 0x2C, 0x74, 0x5A, 0x6E, 0xE8 - }, - { - 0x21, 0xFB, 0x20, 0x34, 0x58, 0xBF, 0x3A, 0x7E, - 0x9A, 0x80, 0x43, 0x9F, 0x9A, 0x90, 0x28, 0x99, - 0xCD, 0x5D, 0xE0, 0x13, 0x9D, 0xFD, 0x56, 0xF7, - 0x11, 0x0C, 0x9D, 0xEC, 0x84, 0x37, 0xB2, 0x6B, - 0xDA, 0x63, 0xDE, 0x2F, 0x56, 0x59, 0x26, 0xD8, - 0x5E, 0xDB, 0x1D, 0x6C, 0x68, 0x25, 0x66, 0x97, - 0x43, 0xDD, 0x99, 0x92, 0x65, 0x3D, 0x13, 0x97, - 0x95, 0x44, 0xD5, 0xDC, 0x82, 0x28, 0xBF, 0xAA - }, - { - 0xEF, 0x02, 0x1F, 0x29, 0xC5, 0xFF, 0xB8, 0x30, - 0xE6, 0x4B, 0x9A, 0xA9, 0x05, 0x8D, 0xD6, 0x60, - 0xFD, 0x2F, 0xCB, 0x81, 0xC4, 0x97, 0xA7, 0xE6, - 0x98, 0xBC, 0xFB, 0xF5, 0x9D, 0xE5, 0xAD, 0x4A, - 0x86, 0xFF, 0x93, 0xC1, 0x0A, 0x4B, 0x9D, 0x1A, - 0xE5, 0x77, 0x47, 0x25, 0xF9, 0x07, 0x2D, 0xCD, - 0xE9, 0xE1, 0xF1, 0x99, 0xBA, 0xB9, 0x1F, 0x8B, - 0xFF, 0x92, 0x18, 0x64, 0xAA, 0x50, 0x2E, 0xEE - }, - { - 0xB3, 0xCF, 0xDA, 0x40, 0x52, 0x6B, 0x7F, 0x1D, - 0x37, 0x56, 0x9B, 0xDF, 0xCD, 0xF9, 0x11, 0xE5, - 0xA6, 0xEF, 0xE6, 0xB2, 0xEC, 0x90, 0xA0, 0x45, - 0x4C, 0x47, 0xB2, 0xC0, 0x46, 0xBF, 0x13, 0x0F, - 0xC3, 0xB3, 0x52, 0xB3, 0x4D, 0xF4, 0x81, 0x3D, - 0x48, 0xD3, 0x3A, 0xB8, 0xE2, 0x69, 0xB6, 0x9B, - 0x07, 0x56, 0x76, 0xCB, 0x6D, 0x00, 0xA8, 0xDC, - 0xF9, 0xE1, 0xF9, 0x67, 0xEC, 0x19, 0x1B, 0x2C - }, - { - 0xB4, 0xC6, 0xC3, 0xB2, 0x67, 0x07, 0x1E, 0xEF, - 0xB9, 0xC8, 0xC7, 0x2E, 0x0E, 0x2B, 0x94, 0x12, - 0x93, 0x64, 0x1F, 0x86, 0x73, 0xCB, 0x70, 0xC1, - 0xCC, 0x26, 0xAD, 0x1E, 0x73, 0xCF, 0x14, 0x17, - 0x55, 0x86, 0x0A, 0xD1, 0x9B, 0x34, 0xC2, 0xF3, - 0x4E, 0xD3, 0x5B, 0xB5, 0x2E, 0xC4, 0x50, 0x7C, - 0xC1, 0xFE, 0x59, 0x04, 0x77, 0x43, 0xA5, 0xF0, - 0xC6, 0xFE, 0xBD, 0xE6, 0x25, 0xE2, 0x60, 0x91 - }, - { - 0x57, 0xA3, 0x4F, 0x2B, 0xCC, 0xA6, 0x0D, 0x4B, - 0x85, 0x10, 0x3B, 0x83, 0x0C, 0x9D, 0x79, 0x52, - 0xA4, 0x16, 0xBE, 0x52, 0x63, 0xAE, 0x42, 0x9C, - 0x9E, 0x5E, 0x53, 0xFE, 0x85, 0x90, 0xA8, 0xF7, - 0x8E, 0xC6, 0x5A, 0x51, 0x10, 0x9E, 0xA8, 0x5D, - 0xCD, 0xF7, 0xB6, 0x22, 0x3F, 0x9F, 0x2B, 0x34, - 0x05, 0x39, 0xFA, 0xD8, 0x19, 0x23, 0xDB, 0xF8, - 0xED, 0xAB, 0xF9, 0x51, 0x29, 0xE4, 0xDF, 0xF6 - }, - { - 0x9C, 0xF4, 0x66, 0x62, 0xFC, 0xD6, 0x1A, 0x23, - 0x22, 0x77, 0xB6, 0x85, 0x66, 0x3B, 0x8B, 0x5D, - 0xA8, 0x32, 0xDF, 0xD9, 0xA3, 0xB8, 0xCC, 0xFE, - 0xEC, 0x99, 0x3E, 0xC6, 0xAC, 0x41, 0x5A, 0xD0, - 0x7E, 0x04, 0x8A, 0xDF, 0xE4, 0x14, 0xDF, 0x27, - 0x27, 0x70, 0xDB, 0xA8, 0x67, 0xDA, 0x5C, 0x12, - 0x24, 0xC6, 0xFD, 0x0A, 0xA0, 0xC2, 0x18, 0x7D, - 0x42, 0x6A, 0xC6, 0x47, 0xE9, 0x88, 0x73, 0x61 - }, - { - 0x5C, 0xE1, 0x04, 0x2A, 0xB4, 0xD5, 0x42, 0xC2, - 0xF9, 0xEE, 0x9D, 0x17, 0x26, 0x2A, 0xF8, 0x16, - 0x40, 0x98, 0x93, 0x5B, 0xEF, 0x17, 0x3D, 0x0E, - 0x18, 0x48, 0x9B, 0x04, 0x84, 0x17, 0x46, 0xCD, - 0x2F, 0x2D, 0xF8, 0x66, 0xBD, 0x7D, 0xA6, 0xE5, - 0xEF, 0x90, 0x24, 0xC6, 0x48, 0x02, 0x3E, 0xC7, - 0x23, 0xAB, 0x9C, 0x62, 0xFD, 0x80, 0x28, 0x57, - 0x39, 0xD8, 0x4F, 0x15, 0xD2, 0xAB, 0x51, 0x5A - }, - { - 0x84, 0x88, 0x39, 0x6B, 0xD4, 0xA8, 0x72, 0x9B, - 0x7A, 0x47, 0x31, 0x78, 0xF2, 0x32, 0xDA, 0xDF, - 0x3F, 0x0F, 0x8E, 0x22, 0x67, 0x8B, 0xA5, 0xA4, - 0x3E, 0x04, 0x1E, 0x72, 0xDA, 0x1E, 0x2C, 0xF8, - 0x21, 0x94, 0xC3, 0x07, 0x20, 0x7A, 0x54, 0xCB, - 0x81, 0x56, 0x29, 0x33, 0x39, 0xEA, 0xEC, 0x69, - 0x3F, 0xF6, 0x6B, 0xFC, 0xD5, 0xEF, 0xC6, 0x5E, - 0x95, 0xE4, 0xEC, 0xAF, 0x54, 0x53, 0x0A, 0xBD - }, - { - 0xF5, 0x98, 0xDA, 0x90, 0x1C, 0x38, 0x35, 0xBC, - 0xA5, 0x60, 0x77, 0x90, 0x37, 0xDF, 0xDE, 0x9F, - 0x0C, 0x51, 0xDC, 0x61, 0xC0, 0xB7, 0x60, 0xFC, - 0x15, 0x22, 0xD7, 0xB4, 0x70, 0xEE, 0x63, 0xF5, - 0xBD, 0xC6, 0x49, 0x84, 0x76, 0xE8, 0x60, 0x49, - 0xAD, 0x86, 0xE4, 0xE2, 0x1A, 0xF2, 0x85, 0x4A, - 0x98, 0x4C, 0xC9, 0x05, 0x42, 0x7D, 0x2F, 0x17, - 0xF6, 0x6B, 0x1F, 0x41, 0xC3, 0xDA, 0x6F, 0x61 - }, - { - 0x5F, 0x93, 0x26, 0x97, 0x98, 0xCF, 0x02, 0x13, - 0x21, 0x07, 0x33, 0x76, 0x60, 0xA8, 0xD7, 0xA1, - 0x77, 0x35, 0x4C, 0x02, 0x12, 0xEB, 0x93, 0xE5, - 0x55, 0xE7, 0xC3, 0x7A, 0x08, 0xAE, 0xF3, 0xD8, - 0xDC, 0xE0, 0x12, 0x17, 0x01, 0x1C, 0xD9, 0x65, - 0xC0, 0x4D, 0xD2, 0xC1, 0x05, 0xF2, 0xE2, 0xB6, - 0xCA, 0xE5, 0xE4, 0xE6, 0xBC, 0xAF, 0x09, 0xDF, - 0xBE, 0xE3, 0xE0, 0xA6, 0xA6, 0x35, 0x7C, 0x37 - }, - { - 0x0E, 0xCF, 0x58, 0x1D, 0x47, 0xBA, 0xC9, 0x23, - 0x09, 0x86, 0xFA, 0xAB, 0xD7, 0x0C, 0x2F, 0x5B, - 0x80, 0xE9, 0x10, 0x66, 0xF0, 0xEC, 0x55, 0xA8, - 0x42, 0x93, 0x78, 0x82, 0x28, 0x6D, 0x2C, 0xA0, - 0x07, 0xBB, 0x4E, 0x97, 0x3B, 0x0B, 0x09, 0x1D, - 0x52, 0x16, 0x7F, 0xF7, 0xC4, 0x00, 0x9C, 0x7A, - 0xB4, 0xAD, 0x38, 0xFF, 0xF1, 0xDC, 0xEA, 0xCD, - 0xB7, 0xBE, 0x81, 0xEF, 0x4A, 0x45, 0x29, 0x52 - }, - { - 0x5A, 0xEC, 0xA8, 0xAB, 0xE1, 0x52, 0x85, 0x82, - 0xB2, 0xA3, 0x07, 0xB4, 0x00, 0x95, 0x85, 0x49, - 0x8A, 0x3D, 0x46, 0x7C, 0xA6, 0x10, 0x1C, 0xB0, - 0xC5, 0x12, 0x6F, 0x99, 0x76, 0x05, 0x6E, 0x9F, - 0xFC, 0x12, 0x3C, 0xC2, 0x0C, 0x30, 0x2B, 0x2A, - 0x73, 0x7F, 0x49, 0x2C, 0x75, 0xD2, 0x1F, 0x01, - 0x51, 0x2C, 0x90, 0xCA, 0x05, 0x41, 0xDF, 0xA5, - 0x6E, 0x95, 0x0A, 0x32, 0x1D, 0xCB, 0x28, 0xD8 - }, - { - 0x73, 0x2F, 0xBF, 0x8F, 0x1C, 0xB2, 0xB8, 0x32, - 0x92, 0x63, 0xED, 0xE2, 0x78, 0x58, 0xFE, 0x46, - 0xF8, 0xD3, 0x35, 0x4D, 0x37, 0x6B, 0xCD, 0xA0, - 0x54, 0x8E, 0x7C, 0xE1, 0xFA, 0x9D, 0xD1, 0x1F, - 0x85, 0xEB, 0x66, 0x1F, 0xE9, 0x50, 0xB5, 0x43, - 0xAA, 0x63, 0x5C, 0xA4, 0xD3, 0xF0, 0x4E, 0xDE, - 0x5B, 0x32, 0xD6, 0xB6, 0x56, 0xE5, 0xCE, 0x1C, - 0x44, 0xD3, 0x5C, 0x4A, 0x6C, 0x56, 0xCF, 0xF8 - }, - { - 0xD5, 0xE9, 0x38, 0x73, 0x5D, 0x63, 0x78, 0x8C, - 0x80, 0x10, 0x0A, 0xEF, 0xD1, 0x86, 0x48, 0xD1, - 0x8C, 0xF2, 0x72, 0xF6, 0x9F, 0x20, 0xFF, 0x24, - 0xCF, 0xE2, 0x89, 0x5C, 0x08, 0x8A, 0xD0, 0x8B, - 0x01, 0x04, 0xDA, 0x16, 0x72, 0xA4, 0xEB, 0x26, - 0xFC, 0x52, 0x54, 0x5C, 0xC7, 0xD7, 0xA0, 0x1B, - 0x26, 0x6C, 0xF5, 0x46, 0xC4, 0x03, 0xC4, 0x5B, - 0xD1, 0x29, 0xEB, 0x41, 0xBD, 0xD9, 0x20, 0x0B - }, - { - 0x65, 0xA2, 0x45, 0xB4, 0x93, 0x52, 0xEE, 0x29, - 0x7D, 0x91, 0xAF, 0x8C, 0x8B, 0xE0, 0x05, 0x28, - 0xAC, 0x6E, 0x04, 0x6D, 0xD8, 0x3A, 0xC7, 0xBD, - 0x46, 0x5A, 0x98, 0x81, 0x6D, 0xD6, 0x8F, 0x3E, - 0x00, 0xE1, 0xAE, 0x8F, 0x89, 0x53, 0x27, 0xA7, - 0xE9, 0xA8, 0xC9, 0x32, 0x65, 0x98, 0x37, 0x9A, - 0x29, 0xC9, 0xFC, 0x91, 0xEC, 0x0C, 0x6E, 0xEF, - 0x08, 0xF3, 0xE2, 0xB2, 0x16, 0xC1, 0x10, 0x08 - }, - { - 0xC9, 0x56, 0x54, 0xB6, 0x30, 0x19, 0x13, 0x0A, - 0xB4, 0x5D, 0xD0, 0xFB, 0x49, 0x41, 0xB9, 0x8A, - 0xEB, 0x3A, 0xF2, 0xA1, 0x23, 0x91, 0x3E, 0xCA, - 0x2C, 0xE9, 0x9B, 0x3E, 0x97, 0x41, 0x0A, 0x7B, - 0xF8, 0x66, 0x1C, 0xC7, 0xFB, 0xAA, 0x2B, 0xC1, - 0xCF, 0x2B, 0x13, 0x11, 0x3B, 0x1E, 0xD4, 0x0A, - 0x01, 0x18, 0xB8, 0x8E, 0x5F, 0xFF, 0xC3, 0x54, - 0x27, 0x59, 0xEA, 0x00, 0x7E, 0xD4, 0xC5, 0x8D - }, - { - 0x1E, 0xB2, 0x62, 0xF3, 0x8F, 0xA4, 0x94, 0x43, - 0x1F, 0x01, 0x7D, 0xAD, 0x44, 0xC0, 0xDF, 0xB6, - 0x93, 0x24, 0xAC, 0x03, 0x2F, 0x04, 0xB6, 0x57, - 0xFC, 0x91, 0xA8, 0x86, 0x47, 0xBB, 0x74, 0x76, - 0x0F, 0x24, 0xE7, 0xC9, 0x56, 0x51, 0x4F, 0x0C, - 0xF0, 0x02, 0x99, 0x0B, 0x18, 0x2C, 0x16, 0x42, - 0xB9, 0xB2, 0x42, 0x6E, 0x96, 0xA6, 0x11, 0x87, - 0xE4, 0xE0, 0x12, 0xF0, 0x0E, 0x21, 0x7D, 0x84 - }, - { - 0x3B, 0x95, 0x5A, 0xEE, 0xBF, 0xA5, 0x15, 0x1A, - 0xC1, 0xAB, 0x8E, 0x3F, 0x5C, 0xC1, 0xE3, 0x76, - 0x70, 0x84, 0xC8, 0x42, 0xA5, 0x75, 0xD3, 0x62, - 0x69, 0x83, 0x6E, 0x97, 0x35, 0x3D, 0x41, 0x62, - 0x2B, 0x73, 0x1D, 0xDD, 0xCD, 0x5F, 0x26, 0x95, - 0x50, 0xA3, 0xA5, 0xB8, 0x7B, 0xE1, 0xE9, 0x03, - 0x26, 0x34, 0x0B, 0x6E, 0x0E, 0x62, 0x55, 0x58, - 0x15, 0xD9, 0x60, 0x05, 0x97, 0xAC, 0x6E, 0xF9 - }, - { - 0x68, 0x28, 0x9F, 0x66, 0x05, 0x47, 0x3B, 0xA0, - 0xE4, 0xF2, 0x41, 0xBA, 0xF7, 0x47, 0x7A, 0x98, - 0x85, 0x42, 0x6A, 0x85, 0x8F, 0x19, 0xEF, 0x2A, - 0x18, 0xB0, 0xD4, 0x0E, 0xF8, 0xE4, 0x12, 0x82, - 0xED, 0x55, 0x26, 0xB5, 0x19, 0x79, 0x9E, 0x27, - 0x0F, 0x13, 0x88, 0x13, 0x27, 0x91, 0x82, 0x78, - 0x75, 0x57, 0x11, 0x07, 0x1D, 0x85, 0x11, 0xFE, - 0x96, 0x3E, 0x3B, 0x56, 0x06, 0xAA, 0x37, 0x16 - }, - { - 0x80, 0xA3, 0x37, 0x87, 0x54, 0x26, 0x12, 0xC3, - 0x8F, 0x6B, 0xCD, 0x7C, 0xD8, 0x6C, 0xAB, 0x46, - 0x02, 0x27, 0x50, 0x9B, 0x1C, 0xBA, 0xD5, 0xEC, - 0x40, 0x8A, 0x91, 0x41, 0x3D, 0x51, 0x15, 0x5A, - 0x04, 0x76, 0xDA, 0xDB, 0xF3, 0xA2, 0x51, 0x8E, - 0x4A, 0x6E, 0x77, 0xCC, 0x34, 0x66, 0x22, 0xE3, - 0x47, 0xA4, 0x69, 0xBF, 0x8B, 0xAA, 0x5F, 0x04, - 0xEB, 0x2D, 0x98, 0x70, 0x53, 0x55, 0xD0, 0x63 - }, - { - 0x34, 0x62, 0x9B, 0xC6, 0xD8, 0x31, 0x39, 0x1C, - 0x4C, 0xDF, 0x8A, 0xF1, 0xB4, 0xB7, 0xB6, 0xB8, - 0xE8, 0xEE, 0x17, 0xCF, 0x98, 0xC7, 0x0E, 0x5D, - 0xD5, 0x86, 0xCD, 0x99, 0xF1, 0x4B, 0x11, 0xDF, - 0x94, 0x51, 0x66, 0x23, 0x6A, 0x95, 0x71, 0xE6, - 0xD5, 0x91, 0xBB, 0x83, 0xEE, 0x4D, 0x16, 0x4D, - 0x46, 0xF6, 0xB9, 0xD8, 0xEF, 0x86, 0xFF, 0x86, - 0x5A, 0x81, 0xBF, 0xB9, 0x1B, 0x00, 0x42, 0x4B - }, - { - 0x8B, 0x7C, 0xC3, 0x39, 0x16, 0x38, 0x63, 0xBB, - 0x43, 0x83, 0xE5, 0x42, 0xB0, 0xEF, 0x0E, 0x7C, - 0xF3, 0x6B, 0x84, 0xAD, 0x93, 0x2C, 0xDF, 0x5A, - 0x80, 0x41, 0x9E, 0xC9, 0xAD, 0x69, 0x2E, 0x7A, - 0x7E, 0x78, 0x4D, 0x2C, 0x7C, 0xB3, 0x79, 0x6A, - 0x18, 0xB8, 0xF8, 0x00, 0x03, 0x5F, 0x3A, 0xA0, - 0x6C, 0x82, 0x41, 0x00, 0x61, 0x11, 0x20, 0xA7, - 0xBD, 0xEB, 0x35, 0x61, 0x8C, 0xCB, 0x81, 0xB7 - }, - { - 0x4F, 0x08, 0x4E, 0x49, 0x39, 0xDD, 0x5A, 0x7F, - 0x5A, 0x65, 0x8F, 0xAD, 0x58, 0xA1, 0x8A, 0x15, - 0xC2, 0x5C, 0x32, 0xEC, 0x1C, 0x7F, 0xD5, 0xC5, - 0xC6, 0xC3, 0xE8, 0x92, 0xB3, 0x97, 0x1A, 0xEA, - 0xAC, 0x30, 0x83, 0x04, 0xEF, 0x17, 0xB1, 0xC4, - 0x72, 0x39, 0xEA, 0x4B, 0xB3, 0x98, 0xB3, 0xFD, - 0x6D, 0x45, 0x28, 0xD8, 0xDE, 0x8E, 0x76, 0x8A, - 0xE0, 0xF1, 0xA5, 0xA5, 0xC6, 0xB5, 0xC2, 0x97 - }, - { - 0x48, 0xF4, 0x07, 0xA1, 0xAF, 0x5B, 0x80, 0x09, - 0xB2, 0x05, 0x17, 0x42, 0xE8, 0xCF, 0x5C, 0xD5, - 0x65, 0x66, 0x69, 0xE7, 0xD7, 0x22, 0xEE, 0x8E, - 0x7B, 0xD2, 0x02, 0x06, 0x08, 0x49, 0x44, 0x21, - 0x68, 0xD8, 0xFA, 0xCC, 0x11, 0x7C, 0x01, 0x2B, - 0xFB, 0x7B, 0xF4, 0x49, 0xD9, 0x9B, 0xEF, 0xFF, - 0x6A, 0x34, 0xAE, 0xA2, 0x03, 0xF1, 0xD8, 0xD3, - 0x52, 0x72, 0x2B, 0xE5, 0x01, 0x4E, 0xC8, 0x18 - }, - { - 0xA6, 0xAA, 0x82, 0xCD, 0x1E, 0x42, 0x6F, 0x9A, - 0x73, 0xBF, 0xA3, 0x9A, 0x29, 0x03, 0x78, 0x76, - 0x11, 0x46, 0x55, 0xB8, 0xC2, 0x2D, 0x6D, 0x3F, - 0xF8, 0xB6, 0x38, 0xAE, 0x7D, 0xEA, 0x6B, 0x17, - 0x84, 0x3E, 0x09, 0xE5, 0x2E, 0xB6, 0x6F, 0xA1, - 0xE4, 0x75, 0xE4, 0xA8, 0xA3, 0xDE, 0x42, 0x9B, - 0x7D, 0x0F, 0x4A, 0x77, 0x6F, 0xCB, 0x8B, 0xDC, - 0x9B, 0x9F, 0xED, 0xE7, 0xD5, 0x2E, 0x81, 0x5F - }, - { - 0x58, 0x17, 0x02, 0x7D, 0x6B, 0xDD, 0x00, 0xC5, - 0xDD, 0x10, 0xAC, 0x59, 0x3C, 0xD5, 0x60, 0x37, - 0x22, 0x70, 0x77, 0x5A, 0x18, 0x52, 0x6D, 0x7E, - 0x6F, 0x13, 0x87, 0x2A, 0x2E, 0x20, 0xEA, 0xB6, - 0x64, 0x62, 0x5B, 0xE7, 0x16, 0x8A, 0xC4, 0xBD, - 0x7C, 0x9E, 0x0C, 0xE7, 0xFC, 0x40, 0x99, 0xE0, - 0xF4, 0x84, 0x42, 0xE2, 0xC7, 0x67, 0x19, 0x1C, - 0x6E, 0x12, 0x84, 0xE9, 0xB2, 0xCC, 0xEA, 0x8C - }, - { - 0x08, 0xE4, 0x10, 0x28, 0x34, 0x0A, 0x45, 0xC7, - 0x4E, 0x40, 0x52, 0xB3, 0xA8, 0xD6, 0x38, 0x9E, - 0x22, 0xE0, 0x43, 0xA1, 0xAD, 0xAB, 0x5E, 0x28, - 0xD9, 0x76, 0x19, 0x45, 0x0D, 0x72, 0x34, 0x69, - 0xB6, 0x20, 0xCA, 0xA5, 0x19, 0xB8, 0x1C, 0x14, - 0x52, 0x38, 0x54, 0xF6, 0x19, 0xFD, 0x30, 0x27, - 0xE3, 0x84, 0x7B, 0xD0, 0x32, 0x76, 0xE6, 0x06, - 0x04, 0xA8, 0x0D, 0xDB, 0x4D, 0xE8, 0x76, 0xD6 - }, - { - 0x13, 0x0B, 0x84, 0x20, 0x53, 0x7E, 0xB0, 0x7D, - 0x72, 0xAB, 0xDA, 0x07, 0xC8, 0x5A, 0xCB, 0xD8, - 0xB9, 0xA4, 0x4F, 0x16, 0x32, 0x1D, 0xD0, 0x42, - 0x21, 0x45, 0xF8, 0x09, 0x67, 0x3D, 0x30, 0xF2, - 0xB5, 0x32, 0x13, 0x26, 0xE2, 0xBF, 0xF3, 0x17, - 0xEF, 0x3F, 0xEF, 0x98, 0x3C, 0x51, 0xC4, 0xF8, - 0xAB, 0x24, 0xA3, 0x25, 0xD2, 0x98, 0xE3, 0x4A, - 0xFC, 0xE5, 0x69, 0xA8, 0x25, 0x55, 0x77, 0x4C - }, - { - 0xAC, 0x49, 0xB8, 0x44, 0xAF, 0xAA, 0x01, 0x2E, - 0x31, 0xC4, 0x74, 0xCA, 0x26, 0x36, 0x48, 0x84, - 0x4F, 0xD2, 0xF6, 0x30, 0x79, 0x92, 0xC2, 0xF7, - 0x52, 0xAC, 0xA0, 0x2C, 0x38, 0x28, 0x96, 0x51, - 0x75, 0x79, 0x4D, 0xEE, 0xE2, 0xD2, 0xEE, 0x95, - 0xC6, 0x1C, 0xD2, 0x84, 0xF6, 0xB5, 0xA2, 0xD7, - 0x5E, 0x2E, 0xF2, 0xB2, 0x9E, 0xE8, 0x14, 0x9E, - 0x77, 0xFB, 0x81, 0x44, 0x7B, 0x2F, 0xD0, 0x4B - }, - { - 0xB9, 0xD7, 0xCA, 0x81, 0xCC, 0x60, 0xBB, 0x95, - 0x78, 0xE4, 0x40, 0x24, 0xE5, 0xA0, 0xA0, 0xBE, - 0x80, 0xF2, 0x73, 0x36, 0xA6, 0xA9, 0xF4, 0xE5, - 0x3D, 0xF3, 0x99, 0x9C, 0xB1, 0x91, 0x28, 0x0B, - 0x09, 0x0E, 0x2A, 0xC2, 0xD2, 0x9C, 0x5B, 0xAA, - 0xD9, 0xD7, 0x14, 0x15, 0xBD, 0xC1, 0x29, 0xE6, - 0x9A, 0xA2, 0x66, 0x7A, 0xF6, 0xA7, 0xFD, 0x5E, - 0x18, 0x9F, 0xCC, 0xDC, 0xEE, 0x81, 0x73, 0x40 - }, - { - 0xA7, 0x55, 0xE1, 0x13, 0x38, 0x65, 0x72, 0xC7, - 0x5C, 0xED, 0x61, 0xD7, 0x19, 0x70, 0x60, 0x70, - 0xB9, 0x14, 0x60, 0x48, 0xE4, 0x2A, 0x9F, 0x8C, - 0xD3, 0x56, 0x67, 0xA0, 0x88, 0xB4, 0x2F, 0x08, - 0x80, 0x8A, 0xBD, 0xF7, 0x7E, 0x61, 0x8A, 0xBD, - 0x95, 0x9A, 0xFC, 0x75, 0x73, 0x79, 0xCA, 0x2C, - 0x00, 0xBC, 0xC1, 0xA4, 0x83, 0x90, 0xFA, 0x2B, - 0xFF, 0x61, 0x8B, 0x1E, 0x00, 0x78, 0xA6, 0x13 - }, - { - 0xA7, 0x3C, 0x7D, 0xEB, 0xED, 0x32, 0x6F, 0x1C, - 0x0D, 0xB0, 0x79, 0x5E, 0xE7, 0xD6, 0xE3, 0x94, - 0x68, 0x94, 0xB8, 0x26, 0xB1, 0xF8, 0x10, 0x1C, - 0x56, 0xC8, 0x23, 0xBA, 0x17, 0x16, 0x83, 0x12, - 0xE7, 0xF5, 0x3F, 0xC7, 0xDB, 0xE5, 0x2C, 0x3E, - 0x11, 0xE6, 0x98, 0x52, 0xC4, 0x04, 0x85, 0xE2, - 0xEF, 0x18, 0x24, 0x77, 0x86, 0x2E, 0xA6, 0xA3, - 0x4E, 0xC1, 0x36, 0xE2, 0xDF, 0xEE, 0xA6, 0xF4 - }, - { - 0x6C, 0xB8, 0xF9, 0xD5, 0x2C, 0x56, 0xD8, 0x2C, - 0xAC, 0x28, 0xF3, 0x9E, 0xA1, 0x59, 0x3E, 0x8B, - 0xB2, 0x50, 0x62, 0x93, 0xAC, 0x0D, 0x68, 0x37, - 0x6A, 0x17, 0x09, 0xB6, 0x2A, 0x46, 0xDF, 0x14, - 0xA4, 0xAE, 0x64, 0xB2, 0xD8, 0xFA, 0xB7, 0x67, - 0x33, 0xA1, 0xCE, 0xD2, 0xD5, 0x48, 0xE3, 0xF3, - 0xC6, 0xFC, 0xB4, 0x9D, 0x40, 0xC3, 0xD5, 0x80, - 0x8E, 0x44, 0x9C, 0xD8, 0x3D, 0x1C, 0x2A, 0xA2 - }, - { - 0x68, 0x3F, 0xA2, 0xB2, 0x36, 0x9A, 0x10, 0x16, - 0x2C, 0x1C, 0x1C, 0x7B, 0x24, 0xBC, 0x97, 0x0E, - 0xE6, 0x7D, 0xA2, 0x20, 0x56, 0x4F, 0x32, 0x20, - 0x3F, 0x62, 0x56, 0x96, 0xC0, 0x35, 0x2A, 0x0B, - 0x9A, 0xD9, 0x66, 0x24, 0x36, 0x2D, 0x95, 0x2D, - 0x84, 0x46, 0x3C, 0x11, 0x06, 0xA2, 0xDB, 0xA7, - 0xA0, 0x92, 0x59, 0x98, 0x84, 0xB3, 0x5A, 0x0B, - 0x89, 0xC8, 0xF1, 0xB6, 0xA9, 0xB5, 0xA6, 0x1E - }, - { - 0xAA, 0xD9, 0xAD, 0x44, 0x61, 0x01, 0x18, 0xB7, - 0x7D, 0x50, 0x8A, 0xEB, 0x1B, 0xBC, 0xD1, 0xC1, - 0xB7, 0xD0, 0x17, 0x13, 0x97, 0xFB, 0x51, 0x0A, - 0x40, 0x1B, 0xBC, 0x0E, 0xC3, 0x46, 0x23, 0x67, - 0x0D, 0x86, 0xA2, 0xDC, 0x3C, 0x8F, 0x3A, 0xB5, - 0xA2, 0x04, 0x4D, 0xF7, 0x30, 0x25, 0x67, 0x27, - 0x54, 0x5F, 0x08, 0x60, 0xCE, 0x21, 0xA1, 0xEA, - 0xC7, 0x17, 0xDF, 0xC4, 0x8F, 0x5D, 0x22, 0x8E - }, - { - 0xC4, 0x25, 0x78, 0xDE, 0x23, 0xB4, 0xC9, 0x87, - 0xD5, 0xE1, 0xAC, 0x4D, 0x68, 0x9E, 0xD5, 0xDE, - 0x4B, 0x04, 0x17, 0xF9, 0x70, 0x4B, 0xC6, 0xBC, - 0xE9, 0x69, 0xFA, 0x13, 0x47, 0x15, 0x85, 0xD6, - 0x2C, 0x2C, 0xB1, 0x21, 0x2A, 0x94, 0x4F, 0x39, - 0x7F, 0xC9, 0xCA, 0x2C, 0x37, 0x47, 0xC3, 0xBE, - 0xB6, 0x94, 0xEC, 0x4C, 0x5B, 0xE6, 0x88, 0x28, - 0xDD, 0xA5, 0x3E, 0xF4, 0x3F, 0xAE, 0xC6, 0xC0 - }, - { - 0x47, 0x0F, 0x00, 0x84, 0x1E, 0xE8, 0x24, 0x4E, - 0x63, 0xED, 0x2C, 0x7E, 0xA3, 0x0E, 0x2E, 0x41, - 0x98, 0x97, 0xC1, 0x97, 0x46, 0x2E, 0xCC, 0xCE, - 0xCF, 0x71, 0x3B, 0x42, 0xA5, 0x06, 0x5F, 0xFF, - 0x59, 0x14, 0xBC, 0x9B, 0x79, 0xAF, 0xFE, 0x8F, - 0x6B, 0x65, 0x78, 0x75, 0xE7, 0x89, 0xAE, 0x21, - 0x3B, 0xD9, 0x14, 0xCD, 0x35, 0xBD, 0x17, 0x4D, - 0x46, 0xE9, 0xD1, 0x8B, 0xD8, 0x43, 0x77, 0x3D - }, - { - 0x34, 0xFC, 0x42, 0x13, 0x73, 0x0F, 0x47, 0xA5, - 0xE9, 0xA3, 0x58, 0x0F, 0x64, 0x3E, 0x12, 0x94, - 0x5C, 0xFC, 0xB3, 0x1B, 0xF2, 0x06, 0xF6, 0xAD, - 0x45, 0x0C, 0xE5, 0x28, 0xDA, 0x3F, 0xA4, 0x32, - 0xE0, 0x05, 0xD6, 0xB0, 0xEC, 0xCE, 0x10, 0xDC, - 0xA7, 0xC5, 0x99, 0x5F, 0x6A, 0xAC, 0xC5, 0x15, - 0x0E, 0x1B, 0x00, 0x9E, 0x19, 0x75, 0x1E, 0x83, - 0x09, 0xF8, 0x85, 0x95, 0x31, 0x84, 0x43, 0x74 - }, - { - 0xFB, 0x3C, 0x1F, 0x0F, 0x56, 0xA5, 0x6F, 0x8E, - 0x31, 0x6F, 0xDF, 0x5D, 0x85, 0x3C, 0x8C, 0x87, - 0x2C, 0x39, 0x63, 0x5D, 0x08, 0x36, 0x34, 0xC3, - 0x90, 0x4F, 0xC3, 0xAC, 0x07, 0xD1, 0xB5, 0x78, - 0xE8, 0x5F, 0xF0, 0xE4, 0x80, 0xE9, 0x2D, 0x44, - 0xAD, 0xE3, 0x3B, 0x62, 0xE8, 0x93, 0xEE, 0x32, - 0x34, 0x3E, 0x79, 0xDD, 0xF6, 0xEF, 0x29, 0x2E, - 0x89, 0xB5, 0x82, 0xD3, 0x12, 0x50, 0x23, 0x14 - }, - { - 0xC7, 0xC9, 0x7F, 0xC6, 0x5D, 0xD2, 0xB9, 0xE3, - 0xD3, 0xD6, 0x07, 0xD3, 0x15, 0x98, 0xD3, 0xF8, - 0x42, 0x61, 0xE9, 0x91, 0x92, 0x51, 0xE9, 0xC8, - 0xE5, 0x7B, 0xB5, 0xF8, 0x29, 0x37, 0x7D, 0x5F, - 0x73, 0xEA, 0xBB, 0xED, 0x55, 0xC6, 0xC3, 0x81, - 0x18, 0x0F, 0x29, 0xAD, 0x02, 0xE5, 0xBE, 0x79, - 0x7F, 0xFE, 0xC7, 0xE5, 0x7B, 0xDE, 0xCB, 0xC5, - 0x0A, 0xD3, 0xD0, 0x62, 0xF0, 0x99, 0x3A, 0xB0 - }, - { - 0xA5, 0x7A, 0x49, 0xCD, 0xBE, 0x67, 0xAE, 0x7D, - 0x9F, 0x79, 0x7B, 0xB5, 0xCC, 0x7E, 0xFC, 0x2D, - 0xF0, 0x7F, 0x4E, 0x1B, 0x15, 0x95, 0x5F, 0x85, - 0xDA, 0xE7, 0x4B, 0x76, 0xE2, 0xEC, 0xB8, 0x5A, - 0xFB, 0x6C, 0xD9, 0xEE, 0xED, 0x88, 0x88, 0xD5, - 0xCA, 0x3E, 0xC5, 0xAB, 0x65, 0xD2, 0x7A, 0x7B, - 0x19, 0xE5, 0x78, 0x47, 0x57, 0x60, 0xA0, 0x45, - 0xAC, 0x3C, 0x92, 0xE1, 0x3A, 0x93, 0x8E, 0x77 - }, - { - 0xC7, 0x14, 0x3F, 0xCE, 0x96, 0x14, 0xA1, 0x7F, - 0xD6, 0x53, 0xAE, 0xB1, 0x40, 0x72, 0x6D, 0xC9, - 0xC3, 0xDB, 0xB1, 0xDE, 0x6C, 0xC5, 0x81, 0xB2, - 0x72, 0x68, 0x97, 0xEC, 0x24, 0xB7, 0xA5, 0x03, - 0x59, 0xAD, 0x49, 0x22, 0x43, 0xBE, 0x66, 0xD9, - 0xED, 0xD8, 0xC9, 0x33, 0xB5, 0xB8, 0x0E, 0x0B, - 0x91, 0xBB, 0x61, 0xEA, 0x98, 0x05, 0x60, 0x06, - 0x51, 0x69, 0x76, 0xFA, 0xE8, 0xD9, 0x9A, 0x35 - }, - { - 0x65, 0xBB, 0x58, 0xD0, 0x7F, 0x93, 0x7E, 0x2D, - 0x3C, 0x7E, 0x65, 0x38, 0x5F, 0x9C, 0x54, 0x73, - 0x0B, 0x70, 0x41, 0x05, 0xCC, 0xDB, 0x69, 0x1F, - 0x6E, 0x14, 0x6D, 0x4E, 0xE8, 0xF6, 0xC0, 0x86, - 0xF4, 0x95, 0x11, 0x03, 0x51, 0x10, 0xA9, 0xAD, - 0x60, 0x31, 0xFD, 0xCE, 0xB9, 0x43, 0xE0, 0xF9, - 0x61, 0x3B, 0xCB, 0x27, 0x6D, 0xD4, 0x0F, 0x06, - 0x24, 0xEF, 0x0F, 0x92, 0x4F, 0x80, 0x97, 0x83 - }, - { - 0xE5, 0x40, 0x27, 0x7F, 0x68, 0x3B, 0x11, 0x86, - 0xDD, 0x3B, 0x5B, 0x3F, 0x61, 0x43, 0x33, 0x96, - 0x58, 0x1A, 0x35, 0xFE, 0xB1, 0x20, 0x02, 0xBE, - 0x8C, 0x6A, 0x62, 0x31, 0xFC, 0x40, 0xFF, 0xA7, - 0x0F, 0x08, 0x08, 0x1B, 0xC5, 0x8B, 0x2D, 0x94, - 0xF7, 0x64, 0x95, 0x43, 0x61, 0x4A, 0x43, 0x5F, - 0xAA, 0x2D, 0x62, 0x11, 0x0E, 0x13, 0xDA, 0xBC, - 0x7B, 0x86, 0x62, 0x9B, 0x63, 0xAF, 0x9C, 0x24 - }, - { - 0x41, 0x85, 0x00, 0x87, 0x8C, 0x5F, 0xBC, 0xB5, - 0x84, 0xC4, 0x32, 0xF4, 0x28, 0x5E, 0x05, 0xE4, - 0x9F, 0x2E, 0x3E, 0x07, 0x53, 0x99, 0xA0, 0xDB, - 0xFC, 0xF8, 0x74, 0xEB, 0xF8, 0xC0, 0x3D, 0x02, - 0xBF, 0x16, 0xBC, 0x69, 0x89, 0xD1, 0x61, 0xC7, - 0x7C, 0xA0, 0x78, 0x6B, 0x05, 0x05, 0x3C, 0x6C, - 0x70, 0x94, 0x33, 0x71, 0x23, 0x19, 0x19, 0x21, - 0x28, 0x83, 0x5C, 0xF0, 0xB6, 0x60, 0x59, 0x5B - }, - { - 0x88, 0x90, 0x90, 0xDB, 0xB1, 0x94, 0x4B, 0xDC, - 0x94, 0x33, 0xEE, 0x5E, 0xF1, 0x01, 0x0C, 0x7A, - 0x4A, 0x24, 0xA8, 0xE7, 0x1E, 0xCE, 0xA8, 0xE1, - 0x2A, 0x31, 0x31, 0x8C, 0xE4, 0x9D, 0xCA, 0xB0, - 0xAC, 0xA5, 0xC3, 0x80, 0x23, 0x34, 0xAA, 0xB2, - 0xCC, 0x84, 0xB1, 0x4C, 0x6B, 0x93, 0x21, 0xFE, - 0x58, 0x6B, 0xF3, 0xF8, 0x76, 0xF1, 0x9C, 0xD4, - 0x06, 0xEB, 0x11, 0x27, 0xFB, 0x94, 0x48, 0x01 - }, - { - 0x53, 0xB6, 0xA2, 0x89, 0x10, 0xAA, 0x92, 0xE2, - 0x7E, 0x53, 0x6F, 0xB5, 0x49, 0xCF, 0x9B, 0x99, - 0x18, 0x79, 0x10, 0x60, 0x89, 0x8E, 0x0B, 0x9F, - 0xE1, 0x83, 0x57, 0x7F, 0xF4, 0x3B, 0x5E, 0x9C, - 0x76, 0x89, 0xC7, 0x45, 0xB3, 0x2E, 0x41, 0x22, - 0x69, 0x83, 0x7C, 0x31, 0xB8, 0x9E, 0x6C, 0xC1, - 0x2B, 0xF7, 0x6E, 0x13, 0xCA, 0xD3, 0x66, 0xB7, - 0x4E, 0xCE, 0x48, 0xBB, 0x85, 0xFD, 0x09, 0xE9 - }, - { - 0x7C, 0x09, 0x20, 0x80, 0xC6, 0xA8, 0x0D, 0x67, - 0x24, 0x09, 0xD0, 0x81, 0xD3, 0xD1, 0x77, 0x10, - 0x6B, 0xCD, 0x63, 0x56, 0x77, 0x85, 0x14, 0x07, - 0x19, 0x49, 0x09, 0x50, 0xAE, 0x07, 0xAE, 0x8F, - 0xCA, 0xAB, 0xBA, 0xAA, 0xB3, 0x30, 0xCF, 0xBC, - 0xF7, 0x37, 0x44, 0x82, 0xC2, 0x20, 0xAF, 0x2E, - 0xAD, 0xEE, 0xB7, 0x3D, 0xCB, 0xB3, 0x5E, 0xD8, - 0x23, 0x34, 0x4E, 0x14, 0x4E, 0x7D, 0x48, 0x99 - }, - { - 0x9C, 0xCD, 0xE5, 0x66, 0xD2, 0x40, 0x05, 0x09, - 0x18, 0x11, 0x11, 0xF3, 0x2D, 0xDE, 0x4C, 0xD6, - 0x32, 0x09, 0xFE, 0x59, 0xA3, 0x0C, 0x11, 0x45, - 0x46, 0xAD, 0x27, 0x76, 0xD8, 0x89, 0xA4, 0x1B, - 0xAD, 0x8F, 0xA1, 0xBB, 0x46, 0x8C, 0xB2, 0xF9, - 0xD4, 0x2C, 0xA9, 0x92, 0x8A, 0x77, 0x70, 0xFE, - 0xF8, 0xE8, 0xBA, 0x4D, 0x0C, 0x81, 0x2D, 0x9A, - 0x1E, 0x75, 0xC3, 0xD8, 0xD2, 0xCC, 0xD7, 0x5A - }, - { - 0x6E, 0x29, 0x3B, 0xF5, 0xD0, 0x3F, 0xE4, 0x39, - 0x77, 0xCF, 0xE3, 0xF5, 0x7C, 0xCD, 0xB3, 0xAE, - 0x28, 0x2A, 0x85, 0x45, 0x5D, 0xCA, 0x33, 0xF3, - 0x7F, 0x4B, 0x74, 0xF8, 0x39, 0x8C, 0xC6, 0x12, - 0x43, 0x3D, 0x75, 0x5C, 0xBE, 0xC4, 0x12, 0xF8, - 0xF8, 0x2A, 0x3B, 0xD3, 0xBC, 0x4A, 0x27, 0x8F, - 0x7E, 0xCD, 0x0D, 0xFA, 0x9B, 0xBD, 0xC4, 0x0B, - 0xE7, 0xA7, 0x87, 0xC8, 0xF1, 0x59, 0xB2, 0xDF - }, - { - 0xC5, 0x65, 0x46, 0xFB, 0x21, 0x78, 0x45, 0x6F, - 0x33, 0x61, 0x64, 0xC1, 0x8B, 0x90, 0xDE, 0xFF, - 0xC8, 0x3A, 0xE2, 0xB5, 0xA3, 0xAC, 0xA7, 0x7B, - 0x68, 0x84, 0xD3, 0x6D, 0x2C, 0x1D, 0xB3, 0x95, - 0x01, 0xB3, 0xE6, 0x5E, 0x36, 0xC7, 0x58, 0xC6, - 0x6E, 0x31, 0x88, 0x45, 0x1F, 0xDB, 0x35, 0x15, - 0xEE, 0x16, 0x2C, 0x00, 0x1F, 0x06, 0xC3, 0xE8, - 0xCB, 0x57, 0x3A, 0xDF, 0x30, 0xF7, 0xA1, 0x01 - }, - { - 0x6F, 0x82, 0xF8, 0x9F, 0x29, 0x9E, 0xBC, 0xA2, - 0xFE, 0x01, 0x4B, 0x59, 0xBF, 0xFE, 0x1A, 0xA8, - 0x4E, 0x88, 0xB1, 0x91, 0x5F, 0xE2, 0x56, 0xAF, - 0xB6, 0x46, 0xFD, 0x84, 0x48, 0xAF, 0x2B, 0x88, - 0x91, 0xA7, 0xFA, 0xB3, 0x7A, 0x4E, 0xA6, 0xF9, - 0xA5, 0x0E, 0x6C, 0x31, 0x70, 0x39, 0xD8, 0xCF, - 0x87, 0x8F, 0x4C, 0x8E, 0x1A, 0x0D, 0xD4, 0x64, - 0xF0, 0xB4, 0xD6, 0xFF, 0x1C, 0x7E, 0xA8, 0x53 - }, - { - 0x2B, 0x85, 0x99, 0xFF, 0x9C, 0x3D, 0x61, 0x98, - 0x63, 0x7A, 0xD5, 0x1E, 0x57, 0xD1, 0x99, 0x8B, - 0x0D, 0x75, 0x31, 0x3F, 0xE2, 0xDD, 0x61, 0xA5, - 0x33, 0xC9, 0x64, 0xA6, 0xDD, 0x96, 0x07, 0xC6, - 0xF7, 0x23, 0xE9, 0x45, 0x2C, 0xE4, 0x6E, 0x01, - 0x4B, 0x1C, 0x1D, 0x6D, 0xE7, 0x7B, 0xA5, 0xB8, - 0x8C, 0x91, 0x4D, 0x1C, 0x59, 0x7B, 0xF1, 0xEA, - 0xE1, 0x34, 0x74, 0xB4, 0x29, 0x0E, 0x89, 0xB2 - }, - { - 0x08, 0xBF, 0x34, 0x6D, 0x38, 0xE1, 0xDF, 0x06, - 0xC8, 0x26, 0x0E, 0xDB, 0x1D, 0xA7, 0x55, 0x79, - 0x27, 0x59, 0x48, 0xD5, 0xC0, 0xA0, 0xAA, 0x9E, - 0xD2, 0x88, 0x6F, 0x88, 0x56, 0xDE, 0x54, 0x17, - 0xA1, 0x56, 0x99, 0x87, 0x58, 0xF5, 0xB1, 0x7E, - 0x52, 0xF1, 0x01, 0xCA, 0x95, 0x7A, 0x71, 0x13, - 0x74, 0x73, 0xDF, 0xD1, 0x8D, 0x7D, 0x20, 0x9C, - 0x4C, 0x10, 0xD9, 0x23, 0x3C, 0x93, 0x69, 0x1D - }, - { - 0x6D, 0xF2, 0x15, 0x6D, 0x77, 0x31, 0x14, 0xD3, - 0x10, 0xB6, 0x3D, 0xB9, 0xEE, 0x53, 0x50, 0xD7, - 0x7E, 0x6B, 0xCF, 0x25, 0xB0, 0x5F, 0xCD, 0x91, - 0x0F, 0x9B, 0x31, 0xBC, 0x42, 0xBB, 0x13, 0xFE, - 0x82, 0x25, 0xEB, 0xCB, 0x2A, 0x23, 0xA6, 0x22, - 0x80, 0x77, 0x7B, 0x6B, 0xF7, 0x4E, 0x2C, 0xD0, - 0x91, 0x7C, 0x76, 0x40, 0xB4, 0x3D, 0xEF, 0xE4, - 0x68, 0xCD, 0x1E, 0x18, 0xC9, 0x43, 0xC6, 0x6A - }, - { - 0x7C, 0x70, 0x38, 0xBC, 0x13, 0xA9, 0x11, 0x51, - 0x82, 0x8A, 0x5B, 0xA8, 0x2B, 0x4A, 0x96, 0x04, - 0x0F, 0x25, 0x8A, 0x4D, 0xFB, 0x1B, 0x13, 0x73, - 0xF0, 0xD3, 0x59, 0x16, 0x8A, 0xFB, 0x05, 0x17, - 0xA2, 0x0B, 0x28, 0xA1, 0x2D, 0x36, 0x44, 0x04, - 0x6B, 0xE6, 0x6B, 0x8D, 0x08, 0xD8, 0xAE, 0x7F, - 0x6A, 0x92, 0x3E, 0xA1, 0xC0, 0x01, 0x87, 0xC6, - 0xD1, 0x1D, 0xC5, 0x02, 0xBA, 0xC7, 0x13, 0x05 - }, - { - 0xBC, 0xD1, 0xB3, 0x0D, 0x80, 0x8F, 0xB7, 0x39, - 0xB9, 0x87, 0xCB, 0xF1, 0x54, 0xBE, 0xA0, 0x0D, - 0xA9, 0xD4, 0x03, 0x80, 0xB8, 0x61, 0xD4, 0xC1, - 0xD6, 0x37, 0x71, 0x22, 0xDA, 0xDD, 0x61, 0xC0, - 0xE5, 0x90, 0x18, 0xB7, 0x19, 0x41, 0xCF, 0xB6, - 0x2E, 0x00, 0xDC, 0xD7, 0x0A, 0xEB, 0x9A, 0xBF, - 0x04, 0x73, 0xE8, 0x0F, 0x0A, 0x7E, 0xCA, 0x6B, - 0x6D, 0xEA, 0x24, 0x6A, 0xB2, 0x29, 0xDD, 0x2B - }, - { - 0x7E, 0xD4, 0x46, 0x8D, 0x96, 0x85, 0x30, 0xFE, - 0x7A, 0xB2, 0xC3, 0x35, 0x40, 0xB2, 0x6D, 0x8C, - 0x3B, 0xD3, 0xED, 0x44, 0xB3, 0x4F, 0xBE, 0x8C, - 0x2A, 0x9D, 0x7F, 0x80, 0x5B, 0x5A, 0xDA, 0x0E, - 0xA2, 0x52, 0xEE, 0xAD, 0xE4, 0xFC, 0xE9, 0x7F, - 0x89, 0x72, 0x8A, 0xD8, 0x5B, 0xC8, 0xBB, 0x24, - 0x30, 0xB1, 0xBE, 0xF2, 0xCD, 0xDD, 0x32, 0xC8, - 0x44, 0x6E, 0x59, 0xB8, 0xE8, 0xBA, 0x3C, 0x67 - }, - { - 0x6D, 0x30, 0xB7, 0xC6, 0xCE, 0x8A, 0x32, 0x36, - 0xC0, 0xCA, 0x2F, 0x8D, 0x72, 0x8B, 0x10, 0x88, - 0xCA, 0x06, 0x98, 0x3A, 0x80, 0x43, 0xE6, 0x21, - 0xD5, 0xDC, 0xF0, 0xC5, 0x37, 0xD1, 0x3B, 0x08, - 0x79, 0x1E, 0xDE, 0xB0, 0x1A, 0x3C, 0xF0, 0x94, - 0x3E, 0xC1, 0xC8, 0x90, 0xAB, 0x6E, 0x29, 0xB1, - 0x46, 0xA2, 0x36, 0xCD, 0x46, 0xBC, 0xB9, 0xD9, - 0x3B, 0xF5, 0x16, 0xFB, 0x67, 0xC6, 0x3F, 0xE5 - }, - { - 0x97, 0xFE, 0x03, 0xCE, 0xF3, 0x14, 0x38, 0x50, - 0x89, 0x11, 0xBD, 0xED, 0x97, 0x59, 0x80, 0xA6, - 0x60, 0x29, 0x30, 0x5D, 0xC5, 0xE3, 0xFA, 0x8A, - 0xD1, 0xB4, 0xFB, 0x22, 0xFC, 0xDF, 0x5A, 0x19, - 0xA7, 0x33, 0x32, 0x03, 0x27, 0xD8, 0xF7, 0x1C, - 0xCF, 0x49, 0x6C, 0xB3, 0xA4, 0x4A, 0x77, 0xAF, - 0x56, 0xE3, 0xDD, 0xE7, 0x3D, 0x3A, 0x5F, 0x17, - 0x68, 0x96, 0xCC, 0x57, 0xC9, 0xA5, 0xAD, 0x99 - }, - { - 0x78, 0x5A, 0x9D, 0x0F, 0xBD, 0x21, 0x13, 0x6D, - 0xBC, 0xE8, 0xFA, 0x7E, 0xAF, 0xD6, 0x3C, 0x9D, - 0xAD, 0x22, 0x00, 0x52, 0x97, 0x84, 0x16, 0xB3, - 0x1D, 0x97, 0x53, 0xEA, 0xA1, 0x49, 0x09, 0x78, - 0x47, 0xED, 0x9B, 0x30, 0xA6, 0x5C, 0x70, 0x50, - 0x7E, 0xFF, 0x01, 0x87, 0x91, 0x49, 0xED, 0x5C, - 0xF0, 0x47, 0x1D, 0x37, 0x79, 0x8E, 0xDC, 0x05, - 0xAB, 0xD5, 0x6A, 0xD4, 0xA2, 0xCC, 0xCB, 0x1D - }, - { - 0xAD, 0x40, 0x8D, 0x2A, 0xBD, 0xDF, 0xD3, 0x7B, - 0x3B, 0xF3, 0x47, 0x94, 0xC1, 0xA3, 0x37, 0x1D, - 0x92, 0x8E, 0xD7, 0xFC, 0x8D, 0x96, 0x62, 0x25, - 0x33, 0x35, 0x84, 0xC5, 0x66, 0x58, 0x17, 0x83, - 0x2A, 0x37, 0xC0, 0x7F, 0x0D, 0xC7, 0xCB, 0x5A, - 0xA8, 0x74, 0xCD, 0x7D, 0x20, 0xFE, 0x8F, 0xAB, - 0x8E, 0xAB, 0xCB, 0x9B, 0x33, 0xD2, 0xE0, 0x84, - 0x1F, 0x6E, 0x20, 0x09, 0x60, 0x89, 0x9D, 0x95 - }, - { - 0x97, 0x66, 0x8F, 0x74, 0x5B, 0x60, 0x32, 0xFC, - 0x81, 0x5D, 0x95, 0x79, 0x32, 0x27, 0x69, 0xDC, - 0xCD, 0x95, 0x01, 0xA5, 0x08, 0x00, 0x29, 0xB8, - 0xAE, 0x82, 0x6B, 0xEF, 0xB6, 0x74, 0x23, 0x31, - 0xBD, 0x9F, 0x76, 0xEF, 0xEB, 0x3E, 0x2B, 0x8E, - 0x81, 0xA9, 0x78, 0x6B, 0x28, 0x2F, 0x50, 0x68, - 0xA3, 0xA2, 0x42, 0x46, 0x97, 0xA7, 0x7C, 0x41, - 0x87, 0x6B, 0x7E, 0x75, 0x3F, 0x4C, 0x77, 0x67 - }, - { - 0x26, 0xBB, 0x98, 0x5F, 0x47, 0xE7, 0xFE, 0xE0, - 0xCF, 0xD2, 0x52, 0xD4, 0xEF, 0x96, 0xBE, 0xD4, - 0x2B, 0x9C, 0x37, 0x0C, 0x1C, 0x6A, 0x3E, 0x8C, - 0x9E, 0xB0, 0x4E, 0xF7, 0xF7, 0x81, 0x8B, 0x83, - 0x3A, 0x0D, 0x1F, 0x04, 0x3E, 0xBA, 0xFB, 0x91, - 0x1D, 0xC7, 0x79, 0xE0, 0x27, 0x40, 0xA0, 0x2A, - 0x44, 0xD3, 0xA1, 0xEA, 0x45, 0xED, 0x4A, 0xD5, - 0x5E, 0x68, 0x6C, 0x92, 0x7C, 0xAF, 0xE9, 0x7E - }, - { - 0x5B, 0xFE, 0x2B, 0x1D, 0xCF, 0x7F, 0xE9, 0xB9, - 0x50, 0x88, 0xAC, 0xED, 0xB5, 0x75, 0xC1, 0x90, - 0x16, 0xC7, 0x43, 0xB2, 0xE7, 0x63, 0xBF, 0x58, - 0x51, 0xAC, 0x40, 0x7C, 0x9E, 0xDA, 0x43, 0x71, - 0x5E, 0xDF, 0xA4, 0x8B, 0x48, 0x25, 0x49, 0x2C, - 0x51, 0x79, 0x59, 0x3F, 0xFF, 0x21, 0x35, 0x1B, - 0x76, 0xE8, 0xB7, 0xE0, 0x34, 0xE4, 0xC5, 0x3C, - 0x79, 0xF6, 0x1F, 0x29, 0xC4, 0x79, 0xBD, 0x08 - }, - { - 0xC7, 0x65, 0x09, 0xEF, 0x72, 0xF4, 0xA6, 0xF9, - 0xC9, 0xC4, 0x06, 0x18, 0xED, 0x52, 0xB2, 0x08, - 0x4F, 0x83, 0x50, 0x22, 0x32, 0xE0, 0xAC, 0x8B, - 0xDA, 0xF3, 0x26, 0x43, 0x68, 0xE4, 0xD0, 0x18, - 0x0F, 0x68, 0x54, 0xC4, 0xAB, 0xF4, 0xF6, 0x50, - 0x9C, 0x79, 0xCA, 0xAF, 0xC4, 0x4C, 0xF3, 0x19, - 0x4A, 0xFC, 0x57, 0xBD, 0x07, 0x7B, 0xD7, 0xB3, - 0xC9, 0xBD, 0xA3, 0xD4, 0xB8, 0x77, 0x58, 0x16 - }, - { - 0xD6, 0x6F, 0x2B, 0xEA, 0xB9, 0x90, 0xE3, 0x54, - 0xCC, 0xB9, 0x10, 0xE4, 0xE9, 0xC7, 0xAC, 0x61, - 0x8C, 0x7B, 0x63, 0xEF, 0x29, 0x2A, 0x96, 0xB5, - 0x52, 0x34, 0x1D, 0xE7, 0x8D, 0xC4, 0x6D, 0x3E, - 0xC8, 0xCF, 0xAB, 0xC6, 0x99, 0xB5, 0x0A, 0xF4, - 0x1F, 0xDA, 0x39, 0xCF, 0x1B, 0x01, 0x73, 0x66, - 0x09, 0x23, 0x51, 0x0A, 0xD6, 0x7F, 0xAE, 0xDE, - 0xF5, 0x20, 0x7C, 0xFF, 0xE8, 0x64, 0x1D, 0x20 - }, - { - 0x7D, 0x8F, 0x06, 0x72, 0x99, 0x2B, 0x79, 0xBE, - 0x3A, 0x36, 0x4D, 0x8E, 0x59, 0x04, 0xF4, 0xAB, - 0x71, 0x3B, 0xBC, 0x8A, 0xB0, 0x1B, 0x4F, 0x30, - 0x9A, 0xD8, 0xCC, 0xF2, 0x23, 0xCE, 0x10, 0x34, - 0xA8, 0x60, 0xDC, 0xB0, 0xB0, 0x05, 0x50, 0x61, - 0x2C, 0xC2, 0xFA, 0x17, 0xF2, 0x96, 0x9E, 0x18, - 0xF2, 0x2E, 0x14, 0x27, 0xD2, 0x54, 0xB4, 0xA8, - 0x2B, 0x3A, 0x03, 0xA3, 0xEB, 0x39, 0x4A, 0xDF - }, - { - 0xA5, 0x6D, 0x67, 0x25, 0xBF, 0xB3, 0xDE, 0x47, - 0xC1, 0x41, 0x4A, 0xDF, 0x25, 0xFC, 0x8F, 0x0F, - 0xC9, 0x84, 0x6F, 0x69, 0x87, 0x72, 0x2B, 0xC0, - 0x63, 0x66, 0xD5, 0xCA, 0x4E, 0x89, 0x72, 0x29, - 0x25, 0xEB, 0xBC, 0x88, 0x14, 0x18, 0x84, 0x40, - 0x75, 0x39, 0x7A, 0x0C, 0xA8, 0x98, 0x42, 0xC7, - 0xB9, 0xE9, 0xE0, 0x7E, 0x1D, 0x9D, 0x18, 0x3E, - 0xBE, 0xB3, 0x9E, 0x12, 0x0B, 0x48, 0x3B, 0xF7 - }, - { - 0xAF, 0x5E, 0x03, 0xD7, 0xFE, 0x60, 0xC6, 0x7E, - 0x10, 0x31, 0x33, 0x44, 0x43, 0x4E, 0x79, 0x48, - 0x5A, 0x03, 0xA7, 0x58, 0xD6, 0xDC, 0xE9, 0x85, - 0x57, 0x47, 0x45, 0x76, 0x3C, 0x1C, 0x5C, 0x77, - 0xD4, 0xFB, 0x3E, 0x6F, 0xB1, 0x22, 0x30, 0x36, - 0x83, 0x70, 0x99, 0x3B, 0xF9, 0x0F, 0xEE, 0xD0, - 0xC5, 0xD1, 0x60, 0x75, 0x24, 0x56, 0x2D, 0x7C, - 0x09, 0xC0, 0xC2, 0x10, 0xED, 0x39, 0x3D, 0x7C - }, - { - 0x7A, 0x20, 0x54, 0x0C, 0xC0, 0x7B, 0xF7, 0x2B, - 0x58, 0x24, 0x21, 0xFC, 0x34, 0x2E, 0x82, 0xF5, - 0x21, 0x34, 0xB6, 0x98, 0x41, 0xEC, 0x28, 0xED, - 0x18, 0x9E, 0x2E, 0xA6, 0xA2, 0x9D, 0xD2, 0xF8, - 0x2A, 0x64, 0x03, 0x52, 0xD2, 0x22, 0xB5, 0x2F, - 0x29, 0x11, 0xDC, 0x72, 0xA7, 0xDA, 0xB3, 0x1C, - 0xAA, 0xDD, 0x80, 0xC6, 0x11, 0x8F, 0x13, 0xC5, - 0x6B, 0x2A, 0x1E, 0x43, 0x73, 0xBE, 0x0E, 0xA3 - }, - { - 0x48, 0x6F, 0x02, 0xC6, 0x3E, 0x54, 0x67, 0xEA, - 0x1F, 0xDD, 0xE7, 0xE8, 0x2B, 0xFA, 0xCC, 0x2C, - 0x1B, 0xA5, 0xD6, 0x36, 0xD9, 0xF3, 0xD0, 0x8B, - 0x21, 0x0D, 0xA3, 0xF3, 0x72, 0xF7, 0x06, 0xEC, - 0x21, 0x8C, 0xC1, 0x7F, 0xF6, 0x0A, 0xEF, 0x70, - 0x3B, 0xBE, 0x0C, 0x15, 0xC3, 0x8A, 0xE5, 0x5D, - 0x28, 0x6A, 0x68, 0x4F, 0x86, 0x4C, 0x78, 0x21, - 0x1C, 0xCA, 0xB4, 0x17, 0x8C, 0x92, 0xAD, 0xBA - }, - { - 0x1C, 0x7A, 0x5C, 0x1D, 0xED, 0xCD, 0x04, 0xA9, - 0x21, 0x78, 0x8F, 0x7E, 0xB2, 0x33, 0x61, 0xCA, - 0x19, 0x53, 0xB0, 0x4B, 0x9C, 0x7A, 0xEC, 0x35, - 0xD6, 0x5E, 0xA3, 0xE4, 0x99, 0x6D, 0xB2, 0x6F, - 0x28, 0x12, 0x78, 0xEA, 0x4A, 0xE6, 0x66, 0xAD, - 0x81, 0x02, 0x7D, 0x98, 0xAF, 0x57, 0x26, 0x2C, - 0xDB, 0xFA, 0x4C, 0x08, 0x5F, 0x42, 0x10, 0x56, - 0x8C, 0x7E, 0x15, 0xEE, 0xC7, 0x80, 0x51, 0x14 - }, - { - 0x9C, 0xE3, 0xFA, 0x9A, 0x86, 0x0B, 0xDB, 0xD5, - 0x37, 0x8F, 0xD6, 0xD7, 0xB8, 0xB6, 0x71, 0xC6, - 0xCB, 0x76, 0x92, 0x91, 0x0C, 0xE8, 0xF9, 0xB6, - 0xCB, 0x41, 0x22, 0xCB, 0xCB, 0xE6, 0xAC, 0x06, - 0xCA, 0x04, 0x22, 0xCE, 0xF1, 0x22, 0x59, 0x35, - 0x05, 0x3B, 0x7D, 0x19, 0x3A, 0x81, 0xB9, 0xE9, - 0x72, 0xEB, 0x85, 0xA1, 0xD3, 0x07, 0x4F, 0x14, - 0xCB, 0xB5, 0xEC, 0x9F, 0x05, 0x73, 0x89, 0x2D - }, - { - 0xA9, 0x11, 0x87, 0xBE, 0x5C, 0x37, 0x1C, 0x42, - 0x65, 0xC1, 0x74, 0xFD, 0x46, 0x53, 0xB8, 0xAB, - 0x70, 0x85, 0x51, 0xF8, 0x3D, 0x1F, 0xEE, 0x1C, - 0xC1, 0x47, 0x95, 0x81, 0xBC, 0x00, 0x6D, 0x6F, - 0xB7, 0x8F, 0xCC, 0x9A, 0x5D, 0xEE, 0x1D, 0xB3, - 0x66, 0x6F, 0x50, 0x8F, 0x97, 0x80, 0xA3, 0x75, - 0x93, 0xEB, 0xCC, 0xCF, 0x5F, 0xBE, 0xD3, 0x96, - 0x67, 0xDC, 0x63, 0x61, 0xE9, 0x21, 0xF7, 0x79 - }, - { - 0x46, 0x25, 0x76, 0x7D, 0x7B, 0x1D, 0x3D, 0x3E, - 0xD2, 0xFB, 0xC6, 0x74, 0xAF, 0x14, 0xE0, 0x24, - 0x41, 0x52, 0xF2, 0xA4, 0x02, 0x1F, 0xCF, 0x33, - 0x11, 0x50, 0x5D, 0x89, 0xBD, 0x81, 0xE2, 0xF9, - 0xF9, 0xA5, 0x00, 0xC3, 0xB1, 0x99, 0x91, 0x4D, - 0xB4, 0x95, 0x00, 0xB3, 0xC9, 0x8D, 0x03, 0xEA, - 0x93, 0x28, 0x67, 0x51, 0xA6, 0x86, 0xA3, 0xB8, - 0x75, 0xDA, 0xAB, 0x0C, 0xCD, 0x63, 0xB4, 0x4F - }, - { - 0x43, 0xDF, 0xDF, 0xE1, 0xB0, 0x14, 0xFE, 0xD3, - 0xA2, 0xAC, 0xAB, 0xB7, 0xF3, 0xE9, 0xA1, 0x82, - 0xF2, 0xAA, 0x18, 0x01, 0x9D, 0x27, 0xE3, 0xE6, - 0xCD, 0xCF, 0x31, 0xA1, 0x5B, 0x42, 0x8E, 0x91, - 0xE7, 0xB0, 0x8C, 0xF5, 0xE5, 0xC3, 0x76, 0xFC, - 0xE2, 0xD8, 0xA2, 0x8F, 0xF8, 0x5A, 0xB0, 0xA0, - 0xA1, 0x65, 0x6E, 0xDB, 0x4A, 0x0A, 0x91, 0x53, - 0x26, 0x20, 0x09, 0x6D, 0x9A, 0x5A, 0x65, 0x2D - }, - { - 0x27, 0x9E, 0x32, 0x02, 0xBE, 0x39, 0x89, 0xBA, - 0x31, 0x12, 0x77, 0x25, 0x85, 0x17, 0x74, 0x87, - 0xE4, 0xFE, 0x3E, 0xE3, 0xEA, 0xB4, 0x9C, 0x2F, - 0x7F, 0xA7, 0xFE, 0x87, 0xCF, 0xE7, 0xB8, 0x0D, - 0x3E, 0x03, 0x55, 0xED, 0xFF, 0x6D, 0x03, 0x1E, - 0x6C, 0x96, 0xC7, 0x95, 0xDB, 0x1C, 0x6F, 0x04, - 0x18, 0x80, 0xEC, 0x38, 0x24, 0xDE, 0xFA, 0xCF, - 0x92, 0x63, 0x82, 0x0A, 0x8E, 0x73, 0x27, 0xDE - }, - { - 0xEA, 0x2D, 0x06, 0x6A, 0xC2, 0x29, 0xD4, 0xD4, - 0xB6, 0x16, 0xA8, 0xBE, 0xDE, 0xC7, 0x34, 0x32, - 0x52, 0x24, 0xE4, 0xB4, 0xE5, 0x8F, 0x1A, 0xE6, - 0xDA, 0xD7, 0xE4, 0x0C, 0x2D, 0xA2, 0x91, 0x96, - 0xC3, 0xB1, 0xEA, 0x95, 0x71, 0xDA, 0xCC, 0x81, - 0xE8, 0x73, 0x28, 0xCA, 0xA0, 0x21, 0x1E, 0x09, - 0x02, 0x7B, 0x05, 0x24, 0xAA, 0x3F, 0x4A, 0x84, - 0x99, 0x17, 0xB3, 0x58, 0x67, 0x47, 0xEB, 0xBB - }, - { - 0x49, 0xF0, 0x14, 0xF5, 0xC6, 0x18, 0x22, 0xC8, - 0x99, 0xAB, 0x5C, 0xAE, 0x51, 0xBE, 0x40, 0x44, - 0xA4, 0x49, 0x5E, 0x77, 0x7D, 0xEB, 0x7D, 0xA9, - 0xB6, 0xD8, 0x49, 0x0E, 0xFB, 0xB8, 0x75, 0x30, - 0xAD, 0xF2, 0x93, 0xDA, 0xF0, 0x79, 0xF9, 0x4C, - 0x33, 0xB7, 0x04, 0x4E, 0xF6, 0x2E, 0x2E, 0x5B, - 0xB3, 0xEB, 0x11, 0xE1, 0x73, 0x04, 0xF8, 0x45, - 0x3E, 0xE6, 0xCE, 0x24, 0xF0, 0x33, 0xDD, 0xB0 - }, - { - 0x92, 0x33, 0x49, 0x03, 0x44, 0xE5, 0xB0, 0xDC, - 0x59, 0x12, 0x67, 0x1B, 0x7A, 0xE5, 0x4C, 0xEE, - 0x77, 0x30, 0xDB, 0xE1, 0xF4, 0xC7, 0xD9, 0x2A, - 0x4D, 0x3E, 0x3A, 0xAB, 0x50, 0x57, 0x17, 0x08, - 0xDB, 0x51, 0xDC, 0xF9, 0xC2, 0x94, 0x45, 0x91, - 0xDB, 0x65, 0x1D, 0xB3, 0x2D, 0x22, 0x93, 0x5B, - 0x86, 0x94, 0x49, 0x69, 0xBE, 0x77, 0xD5, 0xB5, - 0xFE, 0xAE, 0x6C, 0x38, 0x40, 0xA8, 0xDB, 0x26 - }, - { - 0xB6, 0xE7, 0x5E, 0x6F, 0x4C, 0x7F, 0x45, 0x3B, - 0x74, 0x65, 0xD2, 0x5B, 0x5A, 0xC8, 0xC7, 0x19, - 0x69, 0x02, 0xEA, 0xA9, 0x53, 0x87, 0x52, 0x28, - 0xC8, 0x63, 0x4E, 0x16, 0xE2, 0xAE, 0x1F, 0x38, - 0xBC, 0x32, 0x75, 0x30, 0x43, 0x35, 0xF5, 0x98, - 0x9E, 0xCC, 0xC1, 0xE3, 0x41, 0x67, 0xD4, 0xE6, - 0x8D, 0x77, 0x19, 0x96, 0x8F, 0xBA, 0x8E, 0x2F, - 0xE6, 0x79, 0x47, 0xC3, 0x5C, 0x48, 0xE8, 0x06 - }, - { - 0xCC, 0x14, 0xCA, 0x66, 0x5A, 0xF1, 0x48, 0x3E, - 0xFB, 0xC3, 0xAF, 0x80, 0x08, 0x0E, 0x65, 0x0D, - 0x50, 0x46, 0xA3, 0x93, 0x2F, 0x4F, 0x51, 0xF3, - 0xFE, 0x90, 0xA0, 0x70, 0x5E, 0xC2, 0x51, 0x04, - 0xAD, 0xF0, 0x78, 0x39, 0x26, 0x5D, 0xC5, 0x1D, - 0x43, 0x40, 0x14, 0x11, 0x24, 0x6E, 0x47, 0x4F, - 0x0D, 0x5E, 0x56, 0x37, 0xAF, 0x94, 0x76, 0x72, - 0x83, 0xD5, 0x3E, 0x06, 0x17, 0xE9, 0x81, 0xF4 - }, - { - 0x23, 0x0A, 0x1C, 0x85, 0x7C, 0xB2, 0xE7, 0x85, - 0x2E, 0x41, 0xB6, 0x47, 0xE9, 0x0E, 0x45, 0x85, - 0xD2, 0xD8, 0x81, 0xE1, 0x73, 0x4D, 0xC3, 0x89, - 0x55, 0x35, 0x6E, 0x8D, 0xD7, 0xBF, 0xF3, 0x90, - 0x53, 0x09, 0x2C, 0x6B, 0x38, 0xE2, 0x36, 0xE1, - 0x89, 0x95, 0x25, 0x64, 0x70, 0x73, 0xDD, 0xDF, - 0x68, 0x95, 0xD6, 0x42, 0x06, 0x32, 0x5E, 0x76, - 0x47, 0xF2, 0x75, 0x56, 0x7B, 0x25, 0x59, 0x09 - }, - { - 0xCB, 0xB6, 0x53, 0x21, 0xAC, 0x43, 0x6E, 0x2F, - 0xFD, 0xAB, 0x29, 0x36, 0x35, 0x9C, 0xE4, 0x90, - 0x23, 0xF7, 0xDE, 0xE7, 0x61, 0x4E, 0xF2, 0x8D, - 0x17, 0x3C, 0x3D, 0x27, 0xC5, 0xD1, 0xBF, 0xFA, - 0x51, 0x55, 0x3D, 0x43, 0x3F, 0x8E, 0xE3, 0xC9, - 0xE4, 0x9C, 0x05, 0xA2, 0xB8, 0x83, 0xCC, 0xE9, - 0x54, 0xC9, 0xA8, 0x09, 0x3B, 0x80, 0x61, 0x2A, - 0x0C, 0xDD, 0x47, 0x32, 0xE0, 0x41, 0xF9, 0x95 - }, - { - 0x3E, 0x7E, 0x57, 0x00, 0x74, 0x33, 0x72, 0x75, - 0xEF, 0xB5, 0x13, 0x15, 0x58, 0x80, 0x34, 0xC3, - 0xCF, 0x0D, 0xDD, 0xCA, 0x20, 0xB4, 0x61, 0x2E, - 0x0B, 0xD5, 0xB8, 0x81, 0xE7, 0xE5, 0x47, 0x6D, - 0x31, 0x9C, 0xE4, 0xFE, 0x9F, 0x19, 0x18, 0x6E, - 0x4C, 0x08, 0x26, 0xF4, 0x4F, 0x13, 0x1E, 0xB0, - 0x48, 0xE6, 0x5B, 0xE2, 0x42, 0xB1, 0x17, 0x2C, - 0x63, 0xBA, 0xDB, 0x12, 0x3A, 0xB0, 0xCB, 0xE8 - }, - { - 0xD3, 0x2E, 0x9E, 0xC0, 0x2D, 0x38, 0xD4, 0xE1, - 0xB8, 0x24, 0x9D, 0xF8, 0xDC, 0xB0, 0x0C, 0x5B, - 0x9C, 0x68, 0xEB, 0x89, 0x22, 0x67, 0x2E, 0x35, - 0x05, 0x39, 0x3B, 0x6A, 0x21, 0x0B, 0xA5, 0x6F, - 0x94, 0x96, 0xE5, 0xEE, 0x04, 0x90, 0xEF, 0x38, - 0x7C, 0x3C, 0xDE, 0xC0, 0x61, 0xF0, 0x6B, 0xC0, - 0x38, 0x2D, 0x93, 0x04, 0xCA, 0xFB, 0xB8, 0xE0, - 0xCD, 0x33, 0xD5, 0x70, 0x29, 0xE6, 0x2D, 0xF2 - }, - { - 0x8C, 0x15, 0x12, 0x46, 0x60, 0x89, 0xF0, 0x5B, - 0x37, 0x75, 0xC2, 0x62, 0xB6, 0x2D, 0x22, 0xB8, - 0x38, 0x54, 0xA8, 0x32, 0x18, 0x13, 0x0B, 0x4E, - 0xC9, 0x1B, 0x3C, 0xCB, 0xD2, 0x93, 0xD2, 0xA5, - 0x43, 0x02, 0xCE, 0xCA, 0xAB, 0x9B, 0x10, 0x0C, - 0x68, 0xD1, 0xE6, 0xDD, 0xC8, 0xF0, 0x7C, 0xDD, - 0xBD, 0xFE, 0x6F, 0xDA, 0xAA, 0xF0, 0x99, 0xCC, - 0x09, 0xD6, 0xB7, 0x25, 0x87, 0x9C, 0x63, 0x69 - }, - { - 0x91, 0xA7, 0xF6, 0x1C, 0x97, 0xC2, 0x91, 0x1E, - 0x4C, 0x81, 0x2E, 0xF7, 0x1D, 0x78, 0x0A, 0xD8, - 0xFA, 0x78, 0x87, 0x94, 0x56, 0x1D, 0x08, 0x30, - 0x3F, 0xD1, 0xC1, 0xCB, 0x60, 0x8A, 0x46, 0xA1, - 0x25, 0x63, 0x08, 0x6E, 0xC5, 0xB3, 0x9D, 0x47, - 0x1A, 0xED, 0x94, 0xFB, 0x0F, 0x6C, 0x67, 0x8A, - 0x43, 0xB8, 0x79, 0x29, 0x32, 0xF9, 0x02, 0x8D, - 0x77, 0x2A, 0x22, 0x76, 0x8E, 0xA2, 0x3A, 0x9B - }, - { - 0x4F, 0x6B, 0xB2, 0x22, 0xA3, 0x95, 0xE8, 0xB1, - 0x8F, 0x6B, 0xA1, 0x55, 0x47, 0x7A, 0xED, 0x3F, - 0x07, 0x29, 0xAC, 0x9E, 0x83, 0xE1, 0x6D, 0x31, - 0xA2, 0xA8, 0xBC, 0x65, 0x54, 0x22, 0xB8, 0x37, - 0xC8, 0x91, 0xC6, 0x19, 0x9E, 0x6F, 0x0D, 0x75, - 0x79, 0x9E, 0x3B, 0x69, 0x15, 0x25, 0xC5, 0x81, - 0x95, 0x35, 0x17, 0xF2, 0x52, 0xC4, 0xB9, 0xE3, - 0xA2, 0x7A, 0x28, 0xFB, 0xAF, 0x49, 0x64, 0x4C - }, - { - 0x5D, 0x06, 0xC0, 0x7E, 0x7A, 0x64, 0x6C, 0x41, - 0x3A, 0x50, 0x1C, 0x3F, 0x4B, 0xB2, 0xFC, 0x38, - 0x12, 0x7D, 0xE7, 0x50, 0x9B, 0x70, 0x77, 0xC4, - 0xD9, 0xB5, 0x61, 0x32, 0x01, 0xC1, 0xAA, 0x02, - 0xFD, 0x5F, 0x79, 0xD2, 0x74, 0x59, 0x15, 0xDD, - 0x57, 0xFB, 0xCB, 0x4C, 0xE0, 0x86, 0x95, 0xF6, - 0xEF, 0xC0, 0xCB, 0x3D, 0x2D, 0x33, 0x0E, 0x19, - 0xB4, 0xB0, 0xE6, 0x00, 0x4E, 0xA6, 0x47, 0x1E - }, - { - 0xB9, 0x67, 0x56, 0xE5, 0x79, 0x09, 0x96, 0x8F, - 0x14, 0xB7, 0x96, 0xA5, 0xD3, 0x0F, 0x4C, 0x9D, - 0x67, 0x14, 0x72, 0xCF, 0x82, 0xC8, 0xCF, 0xB2, - 0xCA, 0xCA, 0x7A, 0xC7, 0xA4, 0x4C, 0xA0, 0xA1, - 0x4C, 0x98, 0x42, 0xD0, 0x0C, 0x82, 0xE3, 0x37, - 0x50, 0x2C, 0x94, 0xD5, 0x96, 0x0A, 0xCA, 0x4C, - 0x49, 0x2E, 0xA7, 0xB0, 0xDF, 0x91, 0x9D, 0xDF, - 0x1A, 0xAD, 0xA2, 0xA2, 0x75, 0xBB, 0x10, 0xD4 - }, - { - 0xFF, 0x0A, 0x01, 0x5E, 0x98, 0xDB, 0x9C, 0x99, - 0xF0, 0x39, 0x77, 0x71, 0x0A, 0xAC, 0x3E, 0x65, - 0x8C, 0x0D, 0x89, 0x6F, 0x6D, 0x71, 0xD6, 0x18, - 0xBA, 0x79, 0xDC, 0x6C, 0xF7, 0x2A, 0xC7, 0x5B, - 0x7C, 0x03, 0x8E, 0xB6, 0x86, 0x2D, 0xED, 0xE4, - 0x54, 0x3E, 0x14, 0x54, 0x13, 0xA6, 0x36, 0x8D, - 0x69, 0xF5, 0x72, 0x2C, 0x82, 0x7B, 0xA3, 0xEF, - 0x25, 0xB6, 0xAE, 0x64, 0x40, 0xD3, 0x92, 0x76 - }, - { - 0x5B, 0x21, 0xC5, 0xFD, 0x88, 0x68, 0x36, 0x76, - 0x12, 0x47, 0x4F, 0xA2, 0xE7, 0x0E, 0x9C, 0xFA, - 0x22, 0x01, 0xFF, 0xEE, 0xE8, 0xFA, 0xFA, 0xB5, - 0x79, 0x7A, 0xD5, 0x8F, 0xEF, 0xA1, 0x7C, 0x9B, - 0x5B, 0x10, 0x7D, 0xA4, 0xA3, 0xDB, 0x63, 0x20, - 0xBA, 0xAF, 0x2C, 0x86, 0x17, 0xD5, 0xA5, 0x1D, - 0xF9, 0x14, 0xAE, 0x88, 0xDA, 0x38, 0x67, 0xC2, - 0xD4, 0x1F, 0x0C, 0xC1, 0x4F, 0xA6, 0x79, 0x28 - }, -}; - - - - -static const uint8_t blake2b_keyed_kat[KAT_LENGTH][BLAKE2B_OUTBYTES] = -{ - { - 0x10, 0xEB, 0xB6, 0x77, 0x00, 0xB1, 0x86, 0x8E, - 0xFB, 0x44, 0x17, 0x98, 0x7A, 0xCF, 0x46, 0x90, - 0xAE, 0x9D, 0x97, 0x2F, 0xB7, 0xA5, 0x90, 0xC2, - 0xF0, 0x28, 0x71, 0x79, 0x9A, 0xAA, 0x47, 0x86, - 0xB5, 0xE9, 0x96, 0xE8, 0xF0, 0xF4, 0xEB, 0x98, - 0x1F, 0xC2, 0x14, 0xB0, 0x05, 0xF4, 0x2D, 0x2F, - 0xF4, 0x23, 0x34, 0x99, 0x39, 0x16, 0x53, 0xDF, - 0x7A, 0xEF, 0xCB, 0xC1, 0x3F, 0xC5, 0x15, 0x68 - }, - { - 0x96, 0x1F, 0x6D, 0xD1, 0xE4, 0xDD, 0x30, 0xF6, - 0x39, 0x01, 0x69, 0x0C, 0x51, 0x2E, 0x78, 0xE4, - 0xB4, 0x5E, 0x47, 0x42, 0xED, 0x19, 0x7C, 0x3C, - 0x5E, 0x45, 0xC5, 0x49, 0xFD, 0x25, 0xF2, 0xE4, - 0x18, 0x7B, 0x0B, 0xC9, 0xFE, 0x30, 0x49, 0x2B, - 0x16, 0xB0, 0xD0, 0xBC, 0x4E, 0xF9, 0xB0, 0xF3, - 0x4C, 0x70, 0x03, 0xFA, 0xC0, 0x9A, 0x5E, 0xF1, - 0x53, 0x2E, 0x69, 0x43, 0x02, 0x34, 0xCE, 0xBD - }, - { - 0xDA, 0x2C, 0xFB, 0xE2, 0xD8, 0x40, 0x9A, 0x0F, - 0x38, 0x02, 0x61, 0x13, 0x88, 0x4F, 0x84, 0xB5, - 0x01, 0x56, 0x37, 0x1A, 0xE3, 0x04, 0xC4, 0x43, - 0x01, 0x73, 0xD0, 0x8A, 0x99, 0xD9, 0xFB, 0x1B, - 0x98, 0x31, 0x64, 0xA3, 0x77, 0x07, 0x06, 0xD5, - 0x37, 0xF4, 0x9E, 0x0C, 0x91, 0x6D, 0x9F, 0x32, - 0xB9, 0x5C, 0xC3, 0x7A, 0x95, 0xB9, 0x9D, 0x85, - 0x74, 0x36, 0xF0, 0x23, 0x2C, 0x88, 0xA9, 0x65 - }, - { - 0x33, 0xD0, 0x82, 0x5D, 0xDD, 0xF7, 0xAD, 0xA9, - 0x9B, 0x0E, 0x7E, 0x30, 0x71, 0x04, 0xAD, 0x07, - 0xCA, 0x9C, 0xFD, 0x96, 0x92, 0x21, 0x4F, 0x15, - 0x61, 0x35, 0x63, 0x15, 0xE7, 0x84, 0xF3, 0xE5, - 0xA1, 0x7E, 0x36, 0x4A, 0xE9, 0xDB, 0xB1, 0x4C, - 0xB2, 0x03, 0x6D, 0xF9, 0x32, 0xB7, 0x7F, 0x4B, - 0x29, 0x27, 0x61, 0x36, 0x5F, 0xB3, 0x28, 0xDE, - 0x7A, 0xFD, 0xC6, 0xD8, 0x99, 0x8F, 0x5F, 0xC1 - }, - { - 0xBE, 0xAA, 0x5A, 0x3D, 0x08, 0xF3, 0x80, 0x71, - 0x43, 0xCF, 0x62, 0x1D, 0x95, 0xCD, 0x69, 0x05, - 0x14, 0xD0, 0xB4, 0x9E, 0xFF, 0xF9, 0xC9, 0x1D, - 0x24, 0xB5, 0x92, 0x41, 0xEC, 0x0E, 0xEF, 0xA5, - 0xF6, 0x01, 0x96, 0xD4, 0x07, 0x04, 0x8B, 0xBA, - 0x8D, 0x21, 0x46, 0x82, 0x8E, 0xBC, 0xB0, 0x48, - 0x8D, 0x88, 0x42, 0xFD, 0x56, 0xBB, 0x4F, 0x6D, - 0xF8, 0xE1, 0x9C, 0x4B, 0x4D, 0xAA, 0xB8, 0xAC - }, - { - 0x09, 0x80, 0x84, 0xB5, 0x1F, 0xD1, 0x3D, 0xEA, - 0xE5, 0xF4, 0x32, 0x0D, 0xE9, 0x4A, 0x68, 0x8E, - 0xE0, 0x7B, 0xAE, 0xA2, 0x80, 0x04, 0x86, 0x68, - 0x9A, 0x86, 0x36, 0x11, 0x7B, 0x46, 0xC1, 0xF4, - 0xC1, 0xF6, 0xAF, 0x7F, 0x74, 0xAE, 0x7C, 0x85, - 0x76, 0x00, 0x45, 0x6A, 0x58, 0xA3, 0xAF, 0x25, - 0x1D, 0xC4, 0x72, 0x3A, 0x64, 0xCC, 0x7C, 0x0A, - 0x5A, 0xB6, 0xD9, 0xCA, 0xC9, 0x1C, 0x20, 0xBB - }, - { - 0x60, 0x44, 0x54, 0x0D, 0x56, 0x08, 0x53, 0xEB, - 0x1C, 0x57, 0xDF, 0x00, 0x77, 0xDD, 0x38, 0x10, - 0x94, 0x78, 0x1C, 0xDB, 0x90, 0x73, 0xE5, 0xB1, - 0xB3, 0xD3, 0xF6, 0xC7, 0x82, 0x9E, 0x12, 0x06, - 0x6B, 0xBA, 0xCA, 0x96, 0xD9, 0x89, 0xA6, 0x90, - 0xDE, 0x72, 0xCA, 0x31, 0x33, 0xA8, 0x36, 0x52, - 0xBA, 0x28, 0x4A, 0x6D, 0x62, 0x94, 0x2B, 0x27, - 0x1F, 0xFA, 0x26, 0x20, 0xC9, 0xE7, 0x5B, 0x1F - }, - { - 0x7A, 0x8C, 0xFE, 0x9B, 0x90, 0xF7, 0x5F, 0x7E, - 0xCB, 0x3A, 0xCC, 0x05, 0x3A, 0xAE, 0xD6, 0x19, - 0x31, 0x12, 0xB6, 0xF6, 0xA4, 0xAE, 0xEB, 0x3F, - 0x65, 0xD3, 0xDE, 0x54, 0x19, 0x42, 0xDE, 0xB9, - 0xE2, 0x22, 0x81, 0x52, 0xA3, 0xC4, 0xBB, 0xBE, - 0x72, 0xFC, 0x3B, 0x12, 0x62, 0x95, 0x28, 0xCF, - 0xBB, 0x09, 0xFE, 0x63, 0x0F, 0x04, 0x74, 0x33, - 0x9F, 0x54, 0xAB, 0xF4, 0x53, 0xE2, 0xED, 0x52 - }, - { - 0x38, 0x0B, 0xEA, 0xF6, 0xEA, 0x7C, 0xC9, 0x36, - 0x5E, 0x27, 0x0E, 0xF0, 0xE6, 0xF3, 0xA6, 0x4F, - 0xB9, 0x02, 0xAC, 0xAE, 0x51, 0xDD, 0x55, 0x12, - 0xF8, 0x42, 0x59, 0xAD, 0x2C, 0x91, 0xF4, 0xBC, - 0x41, 0x08, 0xDB, 0x73, 0x19, 0x2A, 0x5B, 0xBF, - 0xB0, 0xCB, 0xCF, 0x71, 0xE4, 0x6C, 0x3E, 0x21, - 0xAE, 0xE1, 0xC5, 0xE8, 0x60, 0xDC, 0x96, 0xE8, - 0xEB, 0x0B, 0x7B, 0x84, 0x26, 0xE6, 0xAB, 0xE9 - }, - { - 0x60, 0xFE, 0x3C, 0x45, 0x35, 0xE1, 0xB5, 0x9D, - 0x9A, 0x61, 0xEA, 0x85, 0x00, 0xBF, 0xAC, 0x41, - 0xA6, 0x9D, 0xFF, 0xB1, 0xCE, 0xAD, 0xD9, 0xAC, - 0xA3, 0x23, 0xE9, 0xA6, 0x25, 0xB6, 0x4D, 0xA5, - 0x76, 0x3B, 0xAD, 0x72, 0x26, 0xDA, 0x02, 0xB9, - 0xC8, 0xC4, 0xF1, 0xA5, 0xDE, 0x14, 0x0A, 0xC5, - 0xA6, 0xC1, 0x12, 0x4E, 0x4F, 0x71, 0x8C, 0xE0, - 0xB2, 0x8E, 0xA4, 0x73, 0x93, 0xAA, 0x66, 0x37 - }, - { - 0x4F, 0xE1, 0x81, 0xF5, 0x4A, 0xD6, 0x3A, 0x29, - 0x83, 0xFE, 0xAA, 0xF7, 0x7D, 0x1E, 0x72, 0x35, - 0xC2, 0xBE, 0xB1, 0x7F, 0xA3, 0x28, 0xB6, 0xD9, - 0x50, 0x5B, 0xDA, 0x32, 0x7D, 0xF1, 0x9F, 0xC3, - 0x7F, 0x02, 0xC4, 0xB6, 0xF0, 0x36, 0x8C, 0xE2, - 0x31, 0x47, 0x31, 0x3A, 0x8E, 0x57, 0x38, 0xB5, - 0xFA, 0x2A, 0x95, 0xB2, 0x9D, 0xE1, 0xC7, 0xF8, - 0x26, 0x4E, 0xB7, 0x7B, 0x69, 0xF5, 0x85, 0xCD - }, - { - 0xF2, 0x28, 0x77, 0x3C, 0xE3, 0xF3, 0xA4, 0x2B, - 0x5F, 0x14, 0x4D, 0x63, 0x23, 0x7A, 0x72, 0xD9, - 0x96, 0x93, 0xAD, 0xB8, 0x83, 0x7D, 0x0E, 0x11, - 0x2A, 0x8A, 0x0F, 0x8F, 0xFF, 0xF2, 0xC3, 0x62, - 0x85, 0x7A, 0xC4, 0x9C, 0x11, 0xEC, 0x74, 0x0D, - 0x15, 0x00, 0x74, 0x9D, 0xAC, 0x9B, 0x1F, 0x45, - 0x48, 0x10, 0x8B, 0xF3, 0x15, 0x57, 0x94, 0xDC, - 0xC9, 0xE4, 0x08, 0x28, 0x49, 0xE2, 0xB8, 0x5B - }, - { - 0x96, 0x24, 0x52, 0xA8, 0x45, 0x5C, 0xC5, 0x6C, - 0x85, 0x11, 0x31, 0x7E, 0x3B, 0x1F, 0x3B, 0x2C, - 0x37, 0xDF, 0x75, 0xF5, 0x88, 0xE9, 0x43, 0x25, - 0xFD, 0xD7, 0x70, 0x70, 0x35, 0x9C, 0xF6, 0x3A, - 0x9A, 0xE6, 0xE9, 0x30, 0x93, 0x6F, 0xDF, 0x8E, - 0x1E, 0x08, 0xFF, 0xCA, 0x44, 0x0C, 0xFB, 0x72, - 0xC2, 0x8F, 0x06, 0xD8, 0x9A, 0x21, 0x51, 0xD1, - 0xC4, 0x6C, 0xD5, 0xB2, 0x68, 0xEF, 0x85, 0x63 - }, - { - 0x43, 0xD4, 0x4B, 0xFA, 0x18, 0x76, 0x8C, 0x59, - 0x89, 0x6B, 0xF7, 0xED, 0x17, 0x65, 0xCB, 0x2D, - 0x14, 0xAF, 0x8C, 0x26, 0x02, 0x66, 0x03, 0x90, - 0x99, 0xB2, 0x5A, 0x60, 0x3E, 0x4D, 0xDC, 0x50, - 0x39, 0xD6, 0xEF, 0x3A, 0x91, 0x84, 0x7D, 0x10, - 0x88, 0xD4, 0x01, 0xC0, 0xC7, 0xE8, 0x47, 0x78, - 0x1A, 0x8A, 0x59, 0x0D, 0x33, 0xA3, 0xC6, 0xCB, - 0x4D, 0xF0, 0xFA, 0xB1, 0xC2, 0xF2, 0x23, 0x55 - }, - { - 0xDC, 0xFF, 0xA9, 0xD5, 0x8C, 0x2A, 0x4C, 0xA2, - 0xCD, 0xBB, 0x0C, 0x7A, 0xA4, 0xC4, 0xC1, 0xD4, - 0x51, 0x65, 0x19, 0x00, 0x89, 0xF4, 0xE9, 0x83, - 0xBB, 0x1C, 0x2C, 0xAB, 0x4A, 0xAE, 0xFF, 0x1F, - 0xA2, 0xB5, 0xEE, 0x51, 0x6F, 0xEC, 0xD7, 0x80, - 0x54, 0x02, 0x40, 0xBF, 0x37, 0xE5, 0x6C, 0x8B, - 0xCC, 0xA7, 0xFA, 0xB9, 0x80, 0xE1, 0xE6, 0x1C, - 0x94, 0x00, 0xD8, 0xA9, 0xA5, 0xB1, 0x4A, 0xC6 - }, - { - 0x6F, 0xBF, 0x31, 0xB4, 0x5A, 0xB0, 0xC0, 0xB8, - 0xDA, 0xD1, 0xC0, 0xF5, 0xF4, 0x06, 0x13, 0x79, - 0x91, 0x2D, 0xDE, 0x5A, 0xA9, 0x22, 0x09, 0x9A, - 0x03, 0x0B, 0x72, 0x5C, 0x73, 0x34, 0x6C, 0x52, - 0x42, 0x91, 0xAD, 0xEF, 0x89, 0xD2, 0xF6, 0xFD, - 0x8D, 0xFC, 0xDA, 0x6D, 0x07, 0xDA, 0xD8, 0x11, - 0xA9, 0x31, 0x45, 0x36, 0xC2, 0x91, 0x5E, 0xD4, - 0x5D, 0xA3, 0x49, 0x47, 0xE8, 0x3D, 0xE3, 0x4E - }, - { - 0xA0, 0xC6, 0x5B, 0xDD, 0xDE, 0x8A, 0xDE, 0xF5, - 0x72, 0x82, 0xB0, 0x4B, 0x11, 0xE7, 0xBC, 0x8A, - 0xAB, 0x10, 0x5B, 0x99, 0x23, 0x1B, 0x75, 0x0C, - 0x02, 0x1F, 0x4A, 0x73, 0x5C, 0xB1, 0xBC, 0xFA, - 0xB8, 0x75, 0x53, 0xBB, 0xA3, 0xAB, 0xB0, 0xC3, - 0xE6, 0x4A, 0x0B, 0x69, 0x55, 0x28, 0x51, 0x85, - 0xA0, 0xBD, 0x35, 0xFB, 0x8C, 0xFD, 0xE5, 0x57, - 0x32, 0x9B, 0xEB, 0xB1, 0xF6, 0x29, 0xEE, 0x93 - }, - { - 0xF9, 0x9D, 0x81, 0x55, 0x50, 0x55, 0x8E, 0x81, - 0xEC, 0xA2, 0xF9, 0x67, 0x18, 0xAE, 0xD1, 0x0D, - 0x86, 0xF3, 0xF1, 0xCF, 0xB6, 0x75, 0xCC, 0xE0, - 0x6B, 0x0E, 0xFF, 0x02, 0xF6, 0x17, 0xC5, 0xA4, - 0x2C, 0x5A, 0xA7, 0x60, 0x27, 0x0F, 0x26, 0x79, - 0xDA, 0x26, 0x77, 0xC5, 0xAE, 0xB9, 0x4F, 0x11, - 0x42, 0x27, 0x7F, 0x21, 0xC7, 0xF7, 0x9F, 0x3C, - 0x4F, 0x0C, 0xCE, 0x4E, 0xD8, 0xEE, 0x62, 0xB1 - }, - { - 0x95, 0x39, 0x1D, 0xA8, 0xFC, 0x7B, 0x91, 0x7A, - 0x20, 0x44, 0xB3, 0xD6, 0xF5, 0x37, 0x4E, 0x1C, - 0xA0, 0x72, 0xB4, 0x14, 0x54, 0xD5, 0x72, 0xC7, - 0x35, 0x6C, 0x05, 0xFD, 0x4B, 0xC1, 0xE0, 0xF4, - 0x0B, 0x8B, 0xB8, 0xB4, 0xA9, 0xF6, 0xBC, 0xE9, - 0xBE, 0x2C, 0x46, 0x23, 0xC3, 0x99, 0xB0, 0xDC, - 0xA0, 0xDA, 0xB0, 0x5C, 0xB7, 0x28, 0x1B, 0x71, - 0xA2, 0x1B, 0x0E, 0xBC, 0xD9, 0xE5, 0x56, 0x70 - }, - { - 0x04, 0xB9, 0xCD, 0x3D, 0x20, 0xD2, 0x21, 0xC0, - 0x9A, 0xC8, 0x69, 0x13, 0xD3, 0xDC, 0x63, 0x04, - 0x19, 0x89, 0xA9, 0xA1, 0xE6, 0x94, 0xF1, 0xE6, - 0x39, 0xA3, 0xBA, 0x7E, 0x45, 0x18, 0x40, 0xF7, - 0x50, 0xC2, 0xFC, 0x19, 0x1D, 0x56, 0xAD, 0x61, - 0xF2, 0xE7, 0x93, 0x6B, 0xC0, 0xAC, 0x8E, 0x09, - 0x4B, 0x60, 0xCA, 0xEE, 0xD8, 0x78, 0xC1, 0x87, - 0x99, 0x04, 0x54, 0x02, 0xD6, 0x1C, 0xEA, 0xF9 - }, - { - 0xEC, 0x0E, 0x0E, 0xF7, 0x07, 0xE4, 0xED, 0x6C, - 0x0C, 0x66, 0xF9, 0xE0, 0x89, 0xE4, 0x95, 0x4B, - 0x05, 0x80, 0x30, 0xD2, 0xDD, 0x86, 0x39, 0x8F, - 0xE8, 0x40, 0x59, 0x63, 0x1F, 0x9E, 0xE5, 0x91, - 0xD9, 0xD7, 0x73, 0x75, 0x35, 0x51, 0x49, 0x17, - 0x8C, 0x0C, 0xF8, 0xF8, 0xE7, 0xC4, 0x9E, 0xD2, - 0xA5, 0xE4, 0xF9, 0x54, 0x88, 0xA2, 0x24, 0x70, - 0x67, 0xC2, 0x08, 0x51, 0x0F, 0xAD, 0xC4, 0x4C - }, - { - 0x9A, 0x37, 0xCC, 0xE2, 0x73, 0xB7, 0x9C, 0x09, - 0x91, 0x36, 0x77, 0x51, 0x0E, 0xAF, 0x76, 0x88, - 0xE8, 0x9B, 0x33, 0x14, 0xD3, 0x53, 0x2F, 0xD2, - 0x76, 0x4C, 0x39, 0xDE, 0x02, 0x2A, 0x29, 0x45, - 0xB5, 0x71, 0x0D, 0x13, 0x51, 0x7A, 0xF8, 0xDD, - 0xC0, 0x31, 0x66, 0x24, 0xE7, 0x3B, 0xEC, 0x1C, - 0xE6, 0x7D, 0xF1, 0x52, 0x28, 0x30, 0x20, 0x36, - 0xF3, 0x30, 0xAB, 0x0C, 0xB4, 0xD2, 0x18, 0xDD - }, - { - 0x4C, 0xF9, 0xBB, 0x8F, 0xB3, 0xD4, 0xDE, 0x8B, - 0x38, 0xB2, 0xF2, 0x62, 0xD3, 0xC4, 0x0F, 0x46, - 0xDF, 0xE7, 0x47, 0xE8, 0xFC, 0x0A, 0x41, 0x4C, - 0x19, 0x3D, 0x9F, 0xCF, 0x75, 0x31, 0x06, 0xCE, - 0x47, 0xA1, 0x8F, 0x17, 0x2F, 0x12, 0xE8, 0xA2, - 0xF1, 0xC2, 0x67, 0x26, 0x54, 0x53, 0x58, 0xE5, - 0xEE, 0x28, 0xC9, 0xE2, 0x21, 0x3A, 0x87, 0x87, - 0xAA, 0xFB, 0xC5, 0x16, 0xD2, 0x34, 0x31, 0x52 - }, - { - 0x64, 0xE0, 0xC6, 0x3A, 0xF9, 0xC8, 0x08, 0xFD, - 0x89, 0x31, 0x37, 0x12, 0x98, 0x67, 0xFD, 0x91, - 0x93, 0x9D, 0x53, 0xF2, 0xAF, 0x04, 0xBE, 0x4F, - 0xA2, 0x68, 0x00, 0x61, 0x00, 0x06, 0x9B, 0x2D, - 0x69, 0xDA, 0xA5, 0xC5, 0xD8, 0xED, 0x7F, 0xDD, - 0xCB, 0x2A, 0x70, 0xEE, 0xEC, 0xDF, 0x2B, 0x10, - 0x5D, 0xD4, 0x6A, 0x1E, 0x3B, 0x73, 0x11, 0x72, - 0x8F, 0x63, 0x9A, 0xB4, 0x89, 0x32, 0x6B, 0xC9 - }, - { - 0x5E, 0x9C, 0x93, 0x15, 0x8D, 0x65, 0x9B, 0x2D, - 0xEF, 0x06, 0xB0, 0xC3, 0xC7, 0x56, 0x50, 0x45, - 0x54, 0x26, 0x62, 0xD6, 0xEE, 0xE8, 0xA9, 0x6A, - 0x89, 0xB7, 0x8A, 0xDE, 0x09, 0xFE, 0x8B, 0x3D, - 0xCC, 0x09, 0x6D, 0x4F, 0xE4, 0x88, 0x15, 0xD8, - 0x8D, 0x8F, 0x82, 0x62, 0x01, 0x56, 0x60, 0x2A, - 0xF5, 0x41, 0x95, 0x5E, 0x1F, 0x6C, 0xA3, 0x0D, - 0xCE, 0x14, 0xE2, 0x54, 0xC3, 0x26, 0xB8, 0x8F - }, - { - 0x77, 0x75, 0xDF, 0xF8, 0x89, 0x45, 0x8D, 0xD1, - 0x1A, 0xEF, 0x41, 0x72, 0x76, 0x85, 0x3E, 0x21, - 0x33, 0x5E, 0xB8, 0x8E, 0x4D, 0xEC, 0x9C, 0xFB, - 0x4E, 0x9E, 0xDB, 0x49, 0x82, 0x00, 0x88, 0x55, - 0x1A, 0x2C, 0xA6, 0x03, 0x39, 0xF1, 0x20, 0x66, - 0x10, 0x11, 0x69, 0xF0, 0xDF, 0xE8, 0x4B, 0x09, - 0x8F, 0xDD, 0xB1, 0x48, 0xD9, 0xDA, 0x6B, 0x3D, - 0x61, 0x3D, 0xF2, 0x63, 0x88, 0x9A, 0xD6, 0x4B - }, - { - 0xF0, 0xD2, 0x80, 0x5A, 0xFB, 0xB9, 0x1F, 0x74, - 0x39, 0x51, 0x35, 0x1A, 0x6D, 0x02, 0x4F, 0x93, - 0x53, 0xA2, 0x3C, 0x7C, 0xE1, 0xFC, 0x2B, 0x05, - 0x1B, 0x3A, 0x8B, 0x96, 0x8C, 0x23, 0x3F, 0x46, - 0xF5, 0x0F, 0x80, 0x6E, 0xCB, 0x15, 0x68, 0xFF, - 0xAA, 0x0B, 0x60, 0x66, 0x1E, 0x33, 0x4B, 0x21, - 0xDD, 0xE0, 0x4F, 0x8F, 0xA1, 0x55, 0xAC, 0x74, - 0x0E, 0xEB, 0x42, 0xE2, 0x0B, 0x60, 0xD7, 0x64 - }, - { - 0x86, 0xA2, 0xAF, 0x31, 0x6E, 0x7D, 0x77, 0x54, - 0x20, 0x1B, 0x94, 0x2E, 0x27, 0x53, 0x64, 0xAC, - 0x12, 0xEA, 0x89, 0x62, 0xAB, 0x5B, 0xD8, 0xD7, - 0xFB, 0x27, 0x6D, 0xC5, 0xFB, 0xFF, 0xC8, 0xF9, - 0xA2, 0x8C, 0xAE, 0x4E, 0x48, 0x67, 0xDF, 0x67, - 0x80, 0xD9, 0xB7, 0x25, 0x24, 0x16, 0x09, 0x27, - 0xC8, 0x55, 0xDA, 0x5B, 0x60, 0x78, 0xE0, 0xB5, - 0x54, 0xAA, 0x91, 0xE3, 0x1C, 0xB9, 0xCA, 0x1D - }, - { - 0x10, 0xBD, 0xF0, 0xCA, 0xA0, 0x80, 0x27, 0x05, - 0xE7, 0x06, 0x36, 0x9B, 0xAF, 0x8A, 0x3F, 0x79, - 0xD7, 0x2C, 0x0A, 0x03, 0xA8, 0x06, 0x75, 0xA7, - 0xBB, 0xB0, 0x0B, 0xE3, 0xA4, 0x5E, 0x51, 0x64, - 0x24, 0xD1, 0xEE, 0x88, 0xEF, 0xB5, 0x6F, 0x6D, - 0x57, 0x77, 0x54, 0x5A, 0xE6, 0xE2, 0x77, 0x65, - 0xC3, 0xA8, 0xF5, 0xE4, 0x93, 0xFC, 0x30, 0x89, - 0x15, 0x63, 0x89, 0x33, 0xA1, 0xDF, 0xEE, 0x55 - }, - { - 0xB0, 0x17, 0x81, 0x09, 0x2B, 0x17, 0x48, 0x45, - 0x9E, 0x2E, 0x4E, 0xC1, 0x78, 0x69, 0x66, 0x27, - 0xBF, 0x4E, 0xBA, 0xFE, 0xBB, 0xA7, 0x74, 0xEC, - 0xF0, 0x18, 0xB7, 0x9A, 0x68, 0xAE, 0xB8, 0x49, - 0x17, 0xBF, 0x0B, 0x84, 0xBB, 0x79, 0xD1, 0x7B, - 0x74, 0x31, 0x51, 0x14, 0x4C, 0xD6, 0x6B, 0x7B, - 0x33, 0xA4, 0xB9, 0xE5, 0x2C, 0x76, 0xC4, 0xE1, - 0x12, 0x05, 0x0F, 0xF5, 0x38, 0x5B, 0x7F, 0x0B - }, - { - 0xC6, 0xDB, 0xC6, 0x1D, 0xEC, 0x6E, 0xAE, 0xAC, - 0x81, 0xE3, 0xD5, 0xF7, 0x55, 0x20, 0x3C, 0x8E, - 0x22, 0x05, 0x51, 0x53, 0x4A, 0x0B, 0x2F, 0xD1, - 0x05, 0xA9, 0x18, 0x89, 0x94, 0x5A, 0x63, 0x85, - 0x50, 0x20, 0x4F, 0x44, 0x09, 0x3D, 0xD9, 0x98, - 0xC0, 0x76, 0x20, 0x5D, 0xFF, 0xAD, 0x70, 0x3A, - 0x0E, 0x5C, 0xD3, 0xC7, 0xF4, 0x38, 0xA7, 0xE6, - 0x34, 0xCD, 0x59, 0xFE, 0xDE, 0xDB, 0x53, 0x9E - }, - { - 0xEB, 0xA5, 0x1A, 0xCF, 0xFB, 0x4C, 0xEA, 0x31, - 0xDB, 0x4B, 0x8D, 0x87, 0xE9, 0xBF, 0x7D, 0xD4, - 0x8F, 0xE9, 0x7B, 0x02, 0x53, 0xAE, 0x67, 0xAA, - 0x58, 0x0F, 0x9A, 0xC4, 0xA9, 0xD9, 0x41, 0xF2, - 0xBE, 0xA5, 0x18, 0xEE, 0x28, 0x68, 0x18, 0xCC, - 0x9F, 0x63, 0x3F, 0x2A, 0x3B, 0x9F, 0xB6, 0x8E, - 0x59, 0x4B, 0x48, 0xCD, 0xD6, 0xD5, 0x15, 0xBF, - 0x1D, 0x52, 0xBA, 0x6C, 0x85, 0xA2, 0x03, 0xA7 - }, - { - 0x86, 0x22, 0x1F, 0x3A, 0xDA, 0x52, 0x03, 0x7B, - 0x72, 0x22, 0x4F, 0x10, 0x5D, 0x79, 0x99, 0x23, - 0x1C, 0x5E, 0x55, 0x34, 0xD0, 0x3D, 0xA9, 0xD9, - 0xC0, 0xA1, 0x2A, 0xCB, 0x68, 0x46, 0x0C, 0xD3, - 0x75, 0xDA, 0xF8, 0xE2, 0x43, 0x86, 0x28, 0x6F, - 0x96, 0x68, 0xF7, 0x23, 0x26, 0xDB, 0xF9, 0x9B, - 0xA0, 0x94, 0x39, 0x24, 0x37, 0xD3, 0x98, 0xE9, - 0x5B, 0xB8, 0x16, 0x1D, 0x71, 0x7F, 0x89, 0x91 - }, - { - 0x55, 0x95, 0xE0, 0x5C, 0x13, 0xA7, 0xEC, 0x4D, - 0xC8, 0xF4, 0x1F, 0xB7, 0x0C, 0xB5, 0x0A, 0x71, - 0xBC, 0xE1, 0x7C, 0x02, 0x4F, 0xF6, 0xDE, 0x7A, - 0xF6, 0x18, 0xD0, 0xCC, 0x4E, 0x9C, 0x32, 0xD9, - 0x57, 0x0D, 0x6D, 0x3E, 0xA4, 0x5B, 0x86, 0x52, - 0x54, 0x91, 0x03, 0x0C, 0x0D, 0x8F, 0x2B, 0x18, - 0x36, 0xD5, 0x77, 0x8C, 0x1C, 0xE7, 0x35, 0xC1, - 0x77, 0x07, 0xDF, 0x36, 0x4D, 0x05, 0x43, 0x47 - }, - { - 0xCE, 0x0F, 0x4F, 0x6A, 0xCA, 0x89, 0x59, 0x0A, - 0x37, 0xFE, 0x03, 0x4D, 0xD7, 0x4D, 0xD5, 0xFA, - 0x65, 0xEB, 0x1C, 0xBD, 0x0A, 0x41, 0x50, 0x8A, - 0xAD, 0xDC, 0x09, 0x35, 0x1A, 0x3C, 0xEA, 0x6D, - 0x18, 0xCB, 0x21, 0x89, 0xC5, 0x4B, 0x70, 0x0C, - 0x00, 0x9F, 0x4C, 0xBF, 0x05, 0x21, 0xC7, 0xEA, - 0x01, 0xBE, 0x61, 0xC5, 0xAE, 0x09, 0xCB, 0x54, - 0xF2, 0x7B, 0xC1, 0xB4, 0x4D, 0x65, 0x8C, 0x82 - }, - { - 0x7E, 0xE8, 0x0B, 0x06, 0xA2, 0x15, 0xA3, 0xBC, - 0xA9, 0x70, 0xC7, 0x7C, 0xDA, 0x87, 0x61, 0x82, - 0x2B, 0xC1, 0x03, 0xD4, 0x4F, 0xA4, 0xB3, 0x3F, - 0x4D, 0x07, 0xDC, 0xB9, 0x97, 0xE3, 0x6D, 0x55, - 0x29, 0x8B, 0xCE, 0xAE, 0x12, 0x24, 0x1B, 0x3F, - 0xA0, 0x7F, 0xA6, 0x3B, 0xE5, 0x57, 0x60, 0x68, - 0xDA, 0x38, 0x7B, 0x8D, 0x58, 0x59, 0xAE, 0xAB, - 0x70, 0x13, 0x69, 0x84, 0x8B, 0x17, 0x6D, 0x42 - }, - { - 0x94, 0x0A, 0x84, 0xB6, 0xA8, 0x4D, 0x10, 0x9A, - 0xAB, 0x20, 0x8C, 0x02, 0x4C, 0x6C, 0xE9, 0x64, - 0x76, 0x76, 0xBA, 0x0A, 0xAA, 0x11, 0xF8, 0x6D, - 0xBB, 0x70, 0x18, 0xF9, 0xFD, 0x22, 0x20, 0xA6, - 0xD9, 0x01, 0xA9, 0x02, 0x7F, 0x9A, 0xBC, 0xF9, - 0x35, 0x37, 0x27, 0x27, 0xCB, 0xF0, 0x9E, 0xBD, - 0x61, 0xA2, 0xA2, 0xEE, 0xB8, 0x76, 0x53, 0xE8, - 0xEC, 0xAD, 0x1B, 0xAB, 0x85, 0xDC, 0x83, 0x27 - }, - { - 0x20, 0x20, 0xB7, 0x82, 0x64, 0xA8, 0x2D, 0x9F, - 0x41, 0x51, 0x14, 0x1A, 0xDB, 0xA8, 0xD4, 0x4B, - 0xF2, 0x0C, 0x5E, 0xC0, 0x62, 0xEE, 0xE9, 0xB5, - 0x95, 0xA1, 0x1F, 0x9E, 0x84, 0x90, 0x1B, 0xF1, - 0x48, 0xF2, 0x98, 0xE0, 0xC9, 0xF8, 0x77, 0x7D, - 0xCD, 0xBC, 0x7C, 0xC4, 0x67, 0x0A, 0xAC, 0x35, - 0x6C, 0xC2, 0xAD, 0x8C, 0xCB, 0x16, 0x29, 0xF1, - 0x6F, 0x6A, 0x76, 0xBC, 0xEF, 0xBE, 0xE7, 0x60 - }, - { - 0xD1, 0xB8, 0x97, 0xB0, 0xE0, 0x75, 0xBA, 0x68, - 0xAB, 0x57, 0x2A, 0xDF, 0x9D, 0x9C, 0x43, 0x66, - 0x63, 0xE4, 0x3E, 0xB3, 0xD8, 0xE6, 0x2D, 0x92, - 0xFC, 0x49, 0xC9, 0xBE, 0x21, 0x4E, 0x6F, 0x27, - 0x87, 0x3F, 0xE2, 0x15, 0xA6, 0x51, 0x70, 0xE6, - 0xBE, 0xA9, 0x02, 0x40, 0x8A, 0x25, 0xB4, 0x95, - 0x06, 0xF4, 0x7B, 0xAB, 0xD0, 0x7C, 0xEC, 0xF7, - 0x11, 0x3E, 0xC1, 0x0C, 0x5D, 0xD3, 0x12, 0x52 - }, - { - 0xB1, 0x4D, 0x0C, 0x62, 0xAB, 0xFA, 0x46, 0x9A, - 0x35, 0x71, 0x77, 0xE5, 0x94, 0xC1, 0x0C, 0x19, - 0x42, 0x43, 0xED, 0x20, 0x25, 0xAB, 0x8A, 0xA5, - 0xAD, 0x2F, 0xA4, 0x1A, 0xD3, 0x18, 0xE0, 0xFF, - 0x48, 0xCD, 0x5E, 0x60, 0xBE, 0xC0, 0x7B, 0x13, - 0x63, 0x4A, 0x71, 0x1D, 0x23, 0x26, 0xE4, 0x88, - 0xA9, 0x85, 0xF3, 0x1E, 0x31, 0x15, 0x33, 0x99, - 0xE7, 0x30, 0x88, 0xEF, 0xC8, 0x6A, 0x5C, 0x55 - }, - { - 0x41, 0x69, 0xC5, 0xCC, 0x80, 0x8D, 0x26, 0x97, - 0xDC, 0x2A, 0x82, 0x43, 0x0D, 0xC2, 0x3E, 0x3C, - 0xD3, 0x56, 0xDC, 0x70, 0xA9, 0x45, 0x66, 0x81, - 0x05, 0x02, 0xB8, 0xD6, 0x55, 0xB3, 0x9A, 0xBF, - 0x9E, 0x7F, 0x90, 0x2F, 0xE7, 0x17, 0xE0, 0x38, - 0x92, 0x19, 0x85, 0x9E, 0x19, 0x45, 0xDF, 0x1A, - 0xF6, 0xAD, 0xA4, 0x2E, 0x4C, 0xCD, 0xA5, 0x5A, - 0x19, 0x7B, 0x71, 0x00, 0xA3, 0x0C, 0x30, 0xA1 - }, - { - 0x25, 0x8A, 0x4E, 0xDB, 0x11, 0x3D, 0x66, 0xC8, - 0x39, 0xC8, 0xB1, 0xC9, 0x1F, 0x15, 0xF3, 0x5A, - 0xDE, 0x60, 0x9F, 0x11, 0xCD, 0x7F, 0x86, 0x81, - 0xA4, 0x04, 0x5B, 0x9F, 0xEF, 0x7B, 0x0B, 0x24, - 0xC8, 0x2C, 0xDA, 0x06, 0xA5, 0xF2, 0x06, 0x7B, - 0x36, 0x88, 0x25, 0xE3, 0x91, 0x4E, 0x53, 0xD6, - 0x94, 0x8E, 0xDE, 0x92, 0xEF, 0xD6, 0xE8, 0x38, - 0x7F, 0xA2, 0xE5, 0x37, 0x23, 0x9B, 0x5B, 0xEE - }, - { - 0x79, 0xD2, 0xD8, 0x69, 0x6D, 0x30, 0xF3, 0x0F, - 0xB3, 0x46, 0x57, 0x76, 0x11, 0x71, 0xA1, 0x1E, - 0x6C, 0x3F, 0x1E, 0x64, 0xCB, 0xE7, 0xBE, 0xBE, - 0xE1, 0x59, 0xCB, 0x95, 0xBF, 0xAF, 0x81, 0x2B, - 0x4F, 0x41, 0x1E, 0x2F, 0x26, 0xD9, 0xC4, 0x21, - 0xDC, 0x2C, 0x28, 0x4A, 0x33, 0x42, 0xD8, 0x23, - 0xEC, 0x29, 0x38, 0x49, 0xE4, 0x2D, 0x1E, 0x46, - 0xB0, 0xA4, 0xAC, 0x1E, 0x3C, 0x86, 0xAB, 0xAA - }, - { - 0x8B, 0x94, 0x36, 0x01, 0x0D, 0xC5, 0xDE, 0xE9, - 0x92, 0xAE, 0x38, 0xAE, 0xA9, 0x7F, 0x2C, 0xD6, - 0x3B, 0x94, 0x6D, 0x94, 0xFE, 0xDD, 0x2E, 0xC9, - 0x67, 0x1D, 0xCD, 0xE3, 0xBD, 0x4C, 0xE9, 0x56, - 0x4D, 0x55, 0x5C, 0x66, 0xC1, 0x5B, 0xB2, 0xB9, - 0x00, 0xDF, 0x72, 0xED, 0xB6, 0xB8, 0x91, 0xEB, - 0xCA, 0xDF, 0xEF, 0xF6, 0x3C, 0x9E, 0xA4, 0x03, - 0x6A, 0x99, 0x8B, 0xE7, 0x97, 0x39, 0x81, 0xE7 - }, - { - 0xC8, 0xF6, 0x8E, 0x69, 0x6E, 0xD2, 0x82, 0x42, - 0xBF, 0x99, 0x7F, 0x5B, 0x3B, 0x34, 0x95, 0x95, - 0x08, 0xE4, 0x2D, 0x61, 0x38, 0x10, 0xF1, 0xE2, - 0xA4, 0x35, 0xC9, 0x6E, 0xD2, 0xFF, 0x56, 0x0C, - 0x70, 0x22, 0xF3, 0x61, 0xA9, 0x23, 0x4B, 0x98, - 0x37, 0xFE, 0xEE, 0x90, 0xBF, 0x47, 0x92, 0x2E, - 0xE0, 0xFD, 0x5F, 0x8D, 0xDF, 0x82, 0x37, 0x18, - 0xD8, 0x6D, 0x1E, 0x16, 0xC6, 0x09, 0x00, 0x71 - }, - { - 0xB0, 0x2D, 0x3E, 0xEE, 0x48, 0x60, 0xD5, 0x86, - 0x8B, 0x2C, 0x39, 0xCE, 0x39, 0xBF, 0xE8, 0x10, - 0x11, 0x29, 0x05, 0x64, 0xDD, 0x67, 0x8C, 0x85, - 0xE8, 0x78, 0x3F, 0x29, 0x30, 0x2D, 0xFC, 0x13, - 0x99, 0xBA, 0x95, 0xB6, 0xB5, 0x3C, 0xD9, 0xEB, - 0xBF, 0x40, 0x0C, 0xCA, 0x1D, 0xB0, 0xAB, 0x67, - 0xE1, 0x9A, 0x32, 0x5F, 0x2D, 0x11, 0x58, 0x12, - 0xD2, 0x5D, 0x00, 0x97, 0x8A, 0xD1, 0xBC, 0xA4 - }, - { - 0x76, 0x93, 0xEA, 0x73, 0xAF, 0x3A, 0xC4, 0xDA, - 0xD2, 0x1C, 0xA0, 0xD8, 0xDA, 0x85, 0xB3, 0x11, - 0x8A, 0x7D, 0x1C, 0x60, 0x24, 0xCF, 0xAF, 0x55, - 0x76, 0x99, 0x86, 0x82, 0x17, 0xBC, 0x0C, 0x2F, - 0x44, 0xA1, 0x99, 0xBC, 0x6C, 0x0E, 0xDD, 0x51, - 0x97, 0x98, 0xBA, 0x05, 0xBD, 0x5B, 0x1B, 0x44, - 0x84, 0x34, 0x6A, 0x47, 0xC2, 0xCA, 0xDF, 0x6B, - 0xF3, 0x0B, 0x78, 0x5C, 0xC8, 0x8B, 0x2B, 0xAF - }, - { - 0xA0, 0xE5, 0xC1, 0xC0, 0x03, 0x1C, 0x02, 0xE4, - 0x8B, 0x7F, 0x09, 0xA5, 0xE8, 0x96, 0xEE, 0x9A, - 0xEF, 0x2F, 0x17, 0xFC, 0x9E, 0x18, 0xE9, 0x97, - 0xD7, 0xF6, 0xCA, 0xC7, 0xAE, 0x31, 0x64, 0x22, - 0xC2, 0xB1, 0xE7, 0x79, 0x84, 0xE5, 0xF3, 0xA7, - 0x3C, 0xB4, 0x5D, 0xEE, 0xD5, 0xD3, 0xF8, 0x46, - 0x00, 0x10, 0x5E, 0x6E, 0xE3, 0x8F, 0x2D, 0x09, - 0x0C, 0x7D, 0x04, 0x42, 0xEA, 0x34, 0xC4, 0x6D - }, - { - 0x41, 0xDA, 0xA6, 0xAD, 0xCF, 0xDB, 0x69, 0xF1, - 0x44, 0x0C, 0x37, 0xB5, 0x96, 0x44, 0x01, 0x65, - 0xC1, 0x5A, 0xDA, 0x59, 0x68, 0x13, 0xE2, 0xE2, - 0x2F, 0x06, 0x0F, 0xCD, 0x55, 0x1F, 0x24, 0xDE, - 0xE8, 0xE0, 0x4B, 0xA6, 0x89, 0x03, 0x87, 0x88, - 0x6C, 0xEE, 0xC4, 0xA7, 0xA0, 0xD7, 0xFC, 0x6B, - 0x44, 0x50, 0x63, 0x92, 0xEC, 0x38, 0x22, 0xC0, - 0xD8, 0xC1, 0xAC, 0xFC, 0x7D, 0x5A, 0xEB, 0xE8 - }, - { - 0x14, 0xD4, 0xD4, 0x0D, 0x59, 0x84, 0xD8, 0x4C, - 0x5C, 0xF7, 0x52, 0x3B, 0x77, 0x98, 0xB2, 0x54, - 0xE2, 0x75, 0xA3, 0xA8, 0xCC, 0x0A, 0x1B, 0xD0, - 0x6E, 0xBC, 0x0B, 0xEE, 0x72, 0x68, 0x56, 0xAC, - 0xC3, 0xCB, 0xF5, 0x16, 0xFF, 0x66, 0x7C, 0xDA, - 0x20, 0x58, 0xAD, 0x5C, 0x34, 0x12, 0x25, 0x44, - 0x60, 0xA8, 0x2C, 0x92, 0x18, 0x70, 0x41, 0x36, - 0x3C, 0xC7, 0x7A, 0x4D, 0xC2, 0x15, 0xE4, 0x87 - }, - { - 0xD0, 0xE7, 0xA1, 0xE2, 0xB9, 0xA4, 0x47, 0xFE, - 0xE8, 0x3E, 0x22, 0x77, 0xE9, 0xFF, 0x80, 0x10, - 0xC2, 0xF3, 0x75, 0xAE, 0x12, 0xFA, 0x7A, 0xAA, - 0x8C, 0xA5, 0xA6, 0x31, 0x78, 0x68, 0xA2, 0x6A, - 0x36, 0x7A, 0x0B, 0x69, 0xFB, 0xC1, 0xCF, 0x32, - 0xA5, 0x5D, 0x34, 0xEB, 0x37, 0x06, 0x63, 0x01, - 0x6F, 0x3D, 0x21, 0x10, 0x23, 0x0E, 0xBA, 0x75, - 0x40, 0x28, 0xA5, 0x6F, 0x54, 0xAC, 0xF5, 0x7C - }, - { - 0xE7, 0x71, 0xAA, 0x8D, 0xB5, 0xA3, 0xE0, 0x43, - 0xE8, 0x17, 0x8F, 0x39, 0xA0, 0x85, 0x7B, 0xA0, - 0x4A, 0x3F, 0x18, 0xE4, 0xAA, 0x05, 0x74, 0x3C, - 0xF8, 0xD2, 0x22, 0xB0, 0xB0, 0x95, 0x82, 0x53, - 0x50, 0xBA, 0x42, 0x2F, 0x63, 0x38, 0x2A, 0x23, - 0xD9, 0x2E, 0x41, 0x49, 0x07, 0x4E, 0x81, 0x6A, - 0x36, 0xC1, 0xCD, 0x28, 0x28, 0x4D, 0x14, 0x62, - 0x67, 0x94, 0x0B, 0x31, 0xF8, 0x81, 0x8E, 0xA2 - }, - { - 0xFE, 0xB4, 0xFD, 0x6F, 0x9E, 0x87, 0xA5, 0x6B, - 0xEF, 0x39, 0x8B, 0x32, 0x84, 0xD2, 0xBD, 0xA5, - 0xB5, 0xB0, 0xE1, 0x66, 0x58, 0x3A, 0x66, 0xB6, - 0x1E, 0x53, 0x84, 0x57, 0xFF, 0x05, 0x84, 0x87, - 0x2C, 0x21, 0xA3, 0x29, 0x62, 0xB9, 0x92, 0x8F, - 0xFA, 0xB5, 0x8D, 0xE4, 0xAF, 0x2E, 0xDD, 0x4E, - 0x15, 0xD8, 0xB3, 0x55, 0x70, 0x52, 0x32, 0x07, - 0xFF, 0x4E, 0x2A, 0x5A, 0xA7, 0x75, 0x4C, 0xAA - }, - { - 0x46, 0x2F, 0x17, 0xBF, 0x00, 0x5F, 0xB1, 0xC1, - 0xB9, 0xE6, 0x71, 0x77, 0x9F, 0x66, 0x52, 0x09, - 0xEC, 0x28, 0x73, 0xE3, 0xE4, 0x11, 0xF9, 0x8D, - 0xAB, 0xF2, 0x40, 0xA1, 0xD5, 0xEC, 0x3F, 0x95, - 0xCE, 0x67, 0x96, 0xB6, 0xFC, 0x23, 0xFE, 0x17, - 0x19, 0x03, 0xB5, 0x02, 0x02, 0x34, 0x67, 0xDE, - 0xC7, 0x27, 0x3F, 0xF7, 0x48, 0x79, 0xB9, 0x29, - 0x67, 0xA2, 0xA4, 0x3A, 0x5A, 0x18, 0x3D, 0x33 - }, - { - 0xD3, 0x33, 0x81, 0x93, 0xB6, 0x45, 0x53, 0xDB, - 0xD3, 0x8D, 0x14, 0x4B, 0xEA, 0x71, 0xC5, 0x91, - 0x5B, 0xB1, 0x10, 0xE2, 0xD8, 0x81, 0x80, 0xDB, - 0xC5, 0xDB, 0x36, 0x4F, 0xD6, 0x17, 0x1D, 0xF3, - 0x17, 0xFC, 0x72, 0x68, 0x83, 0x1B, 0x5A, 0xEF, - 0x75, 0xE4, 0x34, 0x2B, 0x2F, 0xAD, 0x87, 0x97, - 0xBA, 0x39, 0xED, 0xDC, 0xEF, 0x80, 0xE6, 0xEC, - 0x08, 0x15, 0x93, 0x50, 0xB1, 0xAD, 0x69, 0x6D - }, - { - 0xE1, 0x59, 0x0D, 0x58, 0x5A, 0x3D, 0x39, 0xF7, - 0xCB, 0x59, 0x9A, 0xBD, 0x47, 0x90, 0x70, 0x96, - 0x64, 0x09, 0xA6, 0x84, 0x6D, 0x43, 0x77, 0xAC, - 0xF4, 0x47, 0x1D, 0x06, 0x5D, 0x5D, 0xB9, 0x41, - 0x29, 0xCC, 0x9B, 0xE9, 0x25, 0x73, 0xB0, 0x5E, - 0xD2, 0x26, 0xBE, 0x1E, 0x9B, 0x7C, 0xB0, 0xCA, - 0xBE, 0x87, 0x91, 0x85, 0x89, 0xF8, 0x0D, 0xAD, - 0xD4, 0xEF, 0x5E, 0xF2, 0x5A, 0x93, 0xD2, 0x8E - }, - { - 0xF8, 0xF3, 0x72, 0x6A, 0xC5, 0xA2, 0x6C, 0xC8, - 0x01, 0x32, 0x49, 0x3A, 0x6F, 0xED, 0xCB, 0x0E, - 0x60, 0x76, 0x0C, 0x09, 0xCF, 0xC8, 0x4C, 0xAD, - 0x17, 0x81, 0x75, 0x98, 0x68, 0x19, 0x66, 0x5E, - 0x76, 0x84, 0x2D, 0x7B, 0x9F, 0xED, 0xF7, 0x6D, - 0xDD, 0xEB, 0xF5, 0xD3, 0xF5, 0x6F, 0xAA, 0xAD, - 0x44, 0x77, 0x58, 0x7A, 0xF2, 0x16, 0x06, 0xD3, - 0x96, 0xAE, 0x57, 0x0D, 0x8E, 0x71, 0x9A, 0xF2 - }, - { - 0x30, 0x18, 0x60, 0x55, 0xC0, 0x79, 0x49, 0x94, - 0x81, 0x83, 0xC8, 0x50, 0xE9, 0xA7, 0x56, 0xCC, - 0x09, 0x93, 0x7E, 0x24, 0x7D, 0x9D, 0x92, 0x8E, - 0x86, 0x9E, 0x20, 0xBA, 0xFC, 0x3C, 0xD9, 0x72, - 0x17, 0x19, 0xD3, 0x4E, 0x04, 0xA0, 0x89, 0x9B, - 0x92, 0xC7, 0x36, 0x08, 0x45, 0x50, 0x18, 0x68, - 0x86, 0xEF, 0xBA, 0x2E, 0x79, 0x0D, 0x8B, 0xE6, - 0xEB, 0xF0, 0x40, 0xB2, 0x09, 0xC4, 0x39, 0xA4 - }, - { - 0xF3, 0xC4, 0x27, 0x6C, 0xB8, 0x63, 0x63, 0x77, - 0x12, 0xC2, 0x41, 0xC4, 0x44, 0xC5, 0xCC, 0x1E, - 0x35, 0x54, 0xE0, 0xFD, 0xDB, 0x17, 0x4D, 0x03, - 0x58, 0x19, 0xDD, 0x83, 0xEB, 0x70, 0x0B, 0x4C, - 0xE8, 0x8D, 0xF3, 0xAB, 0x38, 0x41, 0xBA, 0x02, - 0x08, 0x5E, 0x1A, 0x99, 0xB4, 0xE1, 0x73, 0x10, - 0xC5, 0x34, 0x10, 0x75, 0xC0, 0x45, 0x8B, 0xA3, - 0x76, 0xC9, 0x5A, 0x68, 0x18, 0xFB, 0xB3, 0xE2 - }, - { - 0x0A, 0xA0, 0x07, 0xC4, 0xDD, 0x9D, 0x58, 0x32, - 0x39, 0x30, 0x40, 0xA1, 0x58, 0x3C, 0x93, 0x0B, - 0xCA, 0x7D, 0xC5, 0xE7, 0x7E, 0xA5, 0x3A, 0xDD, - 0x7E, 0x2B, 0x3F, 0x7C, 0x8E, 0x23, 0x13, 0x68, - 0x04, 0x35, 0x20, 0xD4, 0xA3, 0xEF, 0x53, 0xC9, - 0x69, 0xB6, 0xBB, 0xFD, 0x02, 0x59, 0x46, 0xF6, - 0x32, 0xBD, 0x7F, 0x76, 0x5D, 0x53, 0xC2, 0x10, - 0x03, 0xB8, 0xF9, 0x83, 0xF7, 0x5E, 0x2A, 0x6A - }, - { - 0x08, 0xE9, 0x46, 0x47, 0x20, 0x53, 0x3B, 0x23, - 0xA0, 0x4E, 0xC2, 0x4F, 0x7A, 0xE8, 0xC1, 0x03, - 0x14, 0x5F, 0x76, 0x53, 0x87, 0xD7, 0x38, 0x77, - 0x7D, 0x3D, 0x34, 0x34, 0x77, 0xFD, 0x1C, 0x58, - 0xDB, 0x05, 0x21, 0x42, 0xCA, 0xB7, 0x54, 0xEA, - 0x67, 0x43, 0x78, 0xE1, 0x87, 0x66, 0xC5, 0x35, - 0x42, 0xF7, 0x19, 0x70, 0x17, 0x1C, 0xC4, 0xF8, - 0x16, 0x94, 0x24, 0x6B, 0x71, 0x7D, 0x75, 0x64 - }, - { - 0xD3, 0x7F, 0xF7, 0xAD, 0x29, 0x79, 0x93, 0xE7, - 0xEC, 0x21, 0xE0, 0xF1, 0xB4, 0xB5, 0xAE, 0x71, - 0x9C, 0xDC, 0x83, 0xC5, 0xDB, 0x68, 0x75, 0x27, - 0xF2, 0x75, 0x16, 0xCB, 0xFF, 0xA8, 0x22, 0x88, - 0x8A, 0x68, 0x10, 0xEE, 0x5C, 0x1C, 0xA7, 0xBF, - 0xE3, 0x32, 0x11, 0x19, 0xBE, 0x1A, 0xB7, 0xBF, - 0xA0, 0xA5, 0x02, 0x67, 0x1C, 0x83, 0x29, 0x49, - 0x4D, 0xF7, 0xAD, 0x6F, 0x52, 0x2D, 0x44, 0x0F - }, - { - 0xDD, 0x90, 0x42, 0xF6, 0xE4, 0x64, 0xDC, 0xF8, - 0x6B, 0x12, 0x62, 0xF6, 0xAC, 0xCF, 0xAF, 0xBD, - 0x8C, 0xFD, 0x90, 0x2E, 0xD3, 0xED, 0x89, 0xAB, - 0xF7, 0x8F, 0xFA, 0x48, 0x2D, 0xBD, 0xEE, 0xB6, - 0x96, 0x98, 0x42, 0x39, 0x4C, 0x9A, 0x11, 0x68, - 0xAE, 0x3D, 0x48, 0x1A, 0x01, 0x78, 0x42, 0xF6, - 0x60, 0x00, 0x2D, 0x42, 0x44, 0x7C, 0x6B, 0x22, - 0xF7, 0xB7, 0x2F, 0x21, 0xAA, 0xE0, 0x21, 0xC9 - }, - { - 0xBD, 0x96, 0x5B, 0xF3, 0x1E, 0x87, 0xD7, 0x03, - 0x27, 0x53, 0x6F, 0x2A, 0x34, 0x1C, 0xEB, 0xC4, - 0x76, 0x8E, 0xCA, 0x27, 0x5F, 0xA0, 0x5E, 0xF9, - 0x8F, 0x7F, 0x1B, 0x71, 0xA0, 0x35, 0x12, 0x98, - 0xDE, 0x00, 0x6F, 0xBA, 0x73, 0xFE, 0x67, 0x33, - 0xED, 0x01, 0xD7, 0x58, 0x01, 0xB4, 0xA9, 0x28, - 0xE5, 0x42, 0x31, 0xB3, 0x8E, 0x38, 0xC5, 0x62, - 0xB2, 0xE3, 0x3E, 0xA1, 0x28, 0x49, 0x92, 0xFA - }, - { - 0x65, 0x67, 0x6D, 0x80, 0x06, 0x17, 0x97, 0x2F, - 0xBD, 0x87, 0xE4, 0xB9, 0x51, 0x4E, 0x1C, 0x67, - 0x40, 0x2B, 0x7A, 0x33, 0x10, 0x96, 0xD3, 0xBF, - 0xAC, 0x22, 0xF1, 0xAB, 0xB9, 0x53, 0x74, 0xAB, - 0xC9, 0x42, 0xF1, 0x6E, 0x9A, 0xB0, 0xEA, 0xD3, - 0x3B, 0x87, 0xC9, 0x19, 0x68, 0xA6, 0xE5, 0x09, - 0xE1, 0x19, 0xFF, 0x07, 0x78, 0x7B, 0x3E, 0xF4, - 0x83, 0xE1, 0xDC, 0xDC, 0xCF, 0x6E, 0x30, 0x22 - }, - { - 0x93, 0x9F, 0xA1, 0x89, 0x69, 0x9C, 0x5D, 0x2C, - 0x81, 0xDD, 0xD1, 0xFF, 0xC1, 0xFA, 0x20, 0x7C, - 0x97, 0x0B, 0x6A, 0x36, 0x85, 0xBB, 0x29, 0xCE, - 0x1D, 0x3E, 0x99, 0xD4, 0x2F, 0x2F, 0x74, 0x42, - 0xDA, 0x53, 0xE9, 0x5A, 0x72, 0x90, 0x73, 0x14, - 0xF4, 0x58, 0x83, 0x99, 0xA3, 0xFF, 0x5B, 0x0A, - 0x92, 0xBE, 0xB3, 0xF6, 0xBE, 0x26, 0x94, 0xF9, - 0xF8, 0x6E, 0xCF, 0x29, 0x52, 0xD5, 0xB4, 0x1C - }, - { - 0xC5, 0x16, 0x54, 0x17, 0x01, 0x86, 0x3F, 0x91, - 0x00, 0x5F, 0x31, 0x41, 0x08, 0xCE, 0xEC, 0xE3, - 0xC6, 0x43, 0xE0, 0x4F, 0xC8, 0xC4, 0x2F, 0xD2, - 0xFF, 0x55, 0x62, 0x20, 0xE6, 0x16, 0xAA, 0xA6, - 0xA4, 0x8A, 0xEB, 0x97, 0xA8, 0x4B, 0xAD, 0x74, - 0x78, 0x2E, 0x8D, 0xFF, 0x96, 0xA1, 0xA2, 0xFA, - 0x94, 0x93, 0x39, 0xD7, 0x22, 0xED, 0xCA, 0xA3, - 0x2B, 0x57, 0x06, 0x70, 0x41, 0xDF, 0x88, 0xCC - }, - { - 0x98, 0x7F, 0xD6, 0xE0, 0xD6, 0x85, 0x7C, 0x55, - 0x3E, 0xAE, 0xBB, 0x3D, 0x34, 0x97, 0x0A, 0x2C, - 0x2F, 0x6E, 0x89, 0xA3, 0x54, 0x8F, 0x49, 0x25, - 0x21, 0x72, 0x2B, 0x80, 0xA1, 0xC2, 0x1A, 0x15, - 0x38, 0x92, 0x34, 0x6D, 0x2C, 0xBA, 0x64, 0x44, - 0x21, 0x2D, 0x56, 0xDA, 0x9A, 0x26, 0xE3, 0x24, - 0xDC, 0xCB, 0xC0, 0xDC, 0xDE, 0x85, 0xD4, 0xD2, - 0xEE, 0x43, 0x99, 0xEE, 0xC5, 0xA6, 0x4E, 0x8F - }, - { - 0xAE, 0x56, 0xDE, 0xB1, 0xC2, 0x32, 0x8D, 0x9C, - 0x40, 0x17, 0x70, 0x6B, 0xCE, 0x6E, 0x99, 0xD4, - 0x13, 0x49, 0x05, 0x3B, 0xA9, 0xD3, 0x36, 0xD6, - 0x77, 0xC4, 0xC2, 0x7D, 0x9F, 0xD5, 0x0A, 0xE6, - 0xAE, 0xE1, 0x7E, 0x85, 0x31, 0x54, 0xE1, 0xF4, - 0xFE, 0x76, 0x72, 0x34, 0x6D, 0xA2, 0xEA, 0xA3, - 0x1E, 0xEA, 0x53, 0xFC, 0xF2, 0x4A, 0x22, 0x80, - 0x4F, 0x11, 0xD0, 0x3D, 0xA6, 0xAB, 0xFC, 0x2B - }, - { - 0x49, 0xD6, 0xA6, 0x08, 0xC9, 0xBD, 0xE4, 0x49, - 0x18, 0x70, 0x49, 0x85, 0x72, 0xAC, 0x31, 0xAA, - 0xC3, 0xFA, 0x40, 0x93, 0x8B, 0x38, 0xA7, 0x81, - 0x8F, 0x72, 0x38, 0x3E, 0xB0, 0x40, 0xAD, 0x39, - 0x53, 0x2B, 0xC0, 0x65, 0x71, 0xE1, 0x3D, 0x76, - 0x7E, 0x69, 0x45, 0xAB, 0x77, 0xC0, 0xBD, 0xC3, - 0xB0, 0x28, 0x42, 0x53, 0x34, 0x3F, 0x9F, 0x6C, - 0x12, 0x44, 0xEB, 0xF2, 0xFF, 0x0D, 0xF8, 0x66 - }, - { - 0xDA, 0x58, 0x2A, 0xD8, 0xC5, 0x37, 0x0B, 0x44, - 0x69, 0xAF, 0x86, 0x2A, 0xA6, 0x46, 0x7A, 0x22, - 0x93, 0xB2, 0xB2, 0x8B, 0xD8, 0x0A, 0xE0, 0xE9, - 0x1F, 0x42, 0x5A, 0xD3, 0xD4, 0x72, 0x49, 0xFD, - 0xF9, 0x88, 0x25, 0xCC, 0x86, 0xF1, 0x40, 0x28, - 0xC3, 0x30, 0x8C, 0x98, 0x04, 0xC7, 0x8B, 0xFE, - 0xEE, 0xEE, 0x46, 0x14, 0x44, 0xCE, 0x24, 0x36, - 0x87, 0xE1, 0xA5, 0x05, 0x22, 0x45, 0x6A, 0x1D - }, - { - 0xD5, 0x26, 0x6A, 0xA3, 0x33, 0x11, 0x94, 0xAE, - 0xF8, 0x52, 0xEE, 0xD8, 0x6D, 0x7B, 0x5B, 0x26, - 0x33, 0xA0, 0xAF, 0x1C, 0x73, 0x59, 0x06, 0xF2, - 0xE1, 0x32, 0x79, 0xF1, 0x49, 0x31, 0xA9, 0xFC, - 0x3B, 0x0E, 0xAC, 0x5C, 0xE9, 0x24, 0x52, 0x73, - 0xBD, 0x1A, 0xA9, 0x29, 0x05, 0xAB, 0xE1, 0x62, - 0x78, 0xEF, 0x7E, 0xFD, 0x47, 0x69, 0x47, 0x89, - 0xA7, 0x28, 0x3B, 0x77, 0xDA, 0x3C, 0x70, 0xF8 - }, - { - 0x29, 0x62, 0x73, 0x4C, 0x28, 0x25, 0x21, 0x86, - 0xA9, 0xA1, 0x11, 0x1C, 0x73, 0x2A, 0xD4, 0xDE, - 0x45, 0x06, 0xD4, 0xB4, 0x48, 0x09, 0x16, 0x30, - 0x3E, 0xB7, 0x99, 0x1D, 0x65, 0x9C, 0xCD, 0xA0, - 0x7A, 0x99, 0x11, 0x91, 0x4B, 0xC7, 0x5C, 0x41, - 0x8A, 0xB7, 0xA4, 0x54, 0x17, 0x57, 0xAD, 0x05, - 0x47, 0x96, 0xE2, 0x67, 0x97, 0xFE, 0xAF, 0x36, - 0xE9, 0xF6, 0xAD, 0x43, 0xF1, 0x4B, 0x35, 0xA4 - }, - { - 0xE8, 0xB7, 0x9E, 0xC5, 0xD0, 0x6E, 0x11, 0x1B, - 0xDF, 0xAF, 0xD7, 0x1E, 0x9F, 0x57, 0x60, 0xF0, - 0x0A, 0xC8, 0xAC, 0x5D, 0x8B, 0xF7, 0x68, 0xF9, - 0xFF, 0x6F, 0x08, 0xB8, 0xF0, 0x26, 0x09, 0x6B, - 0x1C, 0xC3, 0xA4, 0xC9, 0x73, 0x33, 0x30, 0x19, - 0xF1, 0xE3, 0x55, 0x3E, 0x77, 0xDA, 0x3F, 0x98, - 0xCB, 0x9F, 0x54, 0x2E, 0x0A, 0x90, 0xE5, 0xF8, - 0xA9, 0x40, 0xCC, 0x58, 0xE5, 0x98, 0x44, 0xB3 - }, - { - 0xDF, 0xB3, 0x20, 0xC4, 0x4F, 0x9D, 0x41, 0xD1, - 0xEF, 0xDC, 0xC0, 0x15, 0xF0, 0x8D, 0xD5, 0x53, - 0x9E, 0x52, 0x6E, 0x39, 0xC8, 0x7D, 0x50, 0x9A, - 0xE6, 0x81, 0x2A, 0x96, 0x9E, 0x54, 0x31, 0xBF, - 0x4F, 0xA7, 0xD9, 0x1F, 0xFD, 0x03, 0xB9, 0x81, - 0xE0, 0xD5, 0x44, 0xCF, 0x72, 0xD7, 0xB1, 0xC0, - 0x37, 0x4F, 0x88, 0x01, 0x48, 0x2E, 0x6D, 0xEA, - 0x2E, 0xF9, 0x03, 0x87, 0x7E, 0xBA, 0x67, 0x5E - }, - { - 0xD8, 0x86, 0x75, 0x11, 0x8F, 0xDB, 0x55, 0xA5, - 0xFB, 0x36, 0x5A, 0xC2, 0xAF, 0x1D, 0x21, 0x7B, - 0xF5, 0x26, 0xCE, 0x1E, 0xE9, 0xC9, 0x4B, 0x2F, - 0x00, 0x90, 0xB2, 0xC5, 0x8A, 0x06, 0xCA, 0x58, - 0x18, 0x7D, 0x7F, 0xE5, 0x7C, 0x7B, 0xED, 0x9D, - 0x26, 0xFC, 0xA0, 0x67, 0xB4, 0x11, 0x0E, 0xEF, - 0xCD, 0x9A, 0x0A, 0x34, 0x5D, 0xE8, 0x72, 0xAB, - 0xE2, 0x0D, 0xE3, 0x68, 0x00, 0x1B, 0x07, 0x45 - }, - { - 0xB8, 0x93, 0xF2, 0xFC, 0x41, 0xF7, 0xB0, 0xDD, - 0x6E, 0x2F, 0x6A, 0xA2, 0xE0, 0x37, 0x0C, 0x0C, - 0xFF, 0x7D, 0xF0, 0x9E, 0x3A, 0xCF, 0xCC, 0x0E, - 0x92, 0x0B, 0x6E, 0x6F, 0xAD, 0x0E, 0xF7, 0x47, - 0xC4, 0x06, 0x68, 0x41, 0x7D, 0x34, 0x2B, 0x80, - 0xD2, 0x35, 0x1E, 0x8C, 0x17, 0x5F, 0x20, 0x89, - 0x7A, 0x06, 0x2E, 0x97, 0x65, 0xE6, 0xC6, 0x7B, - 0x53, 0x9B, 0x6B, 0xA8, 0xB9, 0x17, 0x05, 0x45 - }, - { - 0x6C, 0x67, 0xEC, 0x56, 0x97, 0xAC, 0xCD, 0x23, - 0x5C, 0x59, 0xB4, 0x86, 0xD7, 0xB7, 0x0B, 0xAE, - 0xED, 0xCB, 0xD4, 0xAA, 0x64, 0xEB, 0xD4, 0xEE, - 0xF3, 0xC7, 0xEA, 0xC1, 0x89, 0x56, 0x1A, 0x72, - 0x62, 0x50, 0xAE, 0xC4, 0xD4, 0x8C, 0xAD, 0xCA, - 0xFB, 0xBE, 0x2C, 0xE3, 0xC1, 0x6C, 0xE2, 0xD6, - 0x91, 0xA8, 0xCC, 0xE0, 0x6E, 0x88, 0x79, 0x55, - 0x6D, 0x44, 0x83, 0xED, 0x71, 0x65, 0xC0, 0x63 - }, - { - 0xF1, 0xAA, 0x2B, 0x04, 0x4F, 0x8F, 0x0C, 0x63, - 0x8A, 0x3F, 0x36, 0x2E, 0x67, 0x7B, 0x5D, 0x89, - 0x1D, 0x6F, 0xD2, 0xAB, 0x07, 0x65, 0xF6, 0xEE, - 0x1E, 0x49, 0x87, 0xDE, 0x05, 0x7E, 0xAD, 0x35, - 0x78, 0x83, 0xD9, 0xB4, 0x05, 0xB9, 0xD6, 0x09, - 0xEE, 0xA1, 0xB8, 0x69, 0xD9, 0x7F, 0xB1, 0x6D, - 0x9B, 0x51, 0x01, 0x7C, 0x55, 0x3F, 0x3B, 0x93, - 0xC0, 0xA1, 0xE0, 0xF1, 0x29, 0x6F, 0xED, 0xCD - }, - { - 0xCB, 0xAA, 0x25, 0x95, 0x72, 0xD4, 0xAE, 0xBF, - 0xC1, 0x91, 0x7A, 0xCD, 0xDC, 0x58, 0x2B, 0x9F, - 0x8D, 0xFA, 0xA9, 0x28, 0xA1, 0x98, 0xCA, 0x7A, - 0xCD, 0x0F, 0x2A, 0xA7, 0x6A, 0x13, 0x4A, 0x90, - 0x25, 0x2E, 0x62, 0x98, 0xA6, 0x5B, 0x08, 0x18, - 0x6A, 0x35, 0x0D, 0x5B, 0x76, 0x26, 0x69, 0x9F, - 0x8C, 0xB7, 0x21, 0xA3, 0xEA, 0x59, 0x21, 0xB7, - 0x53, 0xAE, 0x3A, 0x2D, 0xCE, 0x24, 0xBA, 0x3A - }, - { - 0xFA, 0x15, 0x49, 0xC9, 0x79, 0x6C, 0xD4, 0xD3, - 0x03, 0xDC, 0xF4, 0x52, 0xC1, 0xFB, 0xD5, 0x74, - 0x4F, 0xD9, 0xB9, 0xB4, 0x70, 0x03, 0xD9, 0x20, - 0xB9, 0x2D, 0xE3, 0x48, 0x39, 0xD0, 0x7E, 0xF2, - 0xA2, 0x9D, 0xED, 0x68, 0xF6, 0xFC, 0x9E, 0x6C, - 0x45, 0xE0, 0x71, 0xA2, 0xE4, 0x8B, 0xD5, 0x0C, - 0x50, 0x84, 0xE9, 0x6B, 0x65, 0x7D, 0xD0, 0x40, - 0x40, 0x45, 0xA1, 0xDD, 0xEF, 0xE2, 0x82, 0xED - }, - { - 0x5C, 0xF2, 0xAC, 0x89, 0x7A, 0xB4, 0x44, 0xDC, - 0xB5, 0xC8, 0xD8, 0x7C, 0x49, 0x5D, 0xBD, 0xB3, - 0x4E, 0x18, 0x38, 0xB6, 0xB6, 0x29, 0x42, 0x7C, - 0xAA, 0x51, 0x70, 0x2A, 0xD0, 0xF9, 0x68, 0x85, - 0x25, 0xF1, 0x3B, 0xEC, 0x50, 0x3A, 0x3C, 0x3A, - 0x2C, 0x80, 0xA6, 0x5E, 0x0B, 0x57, 0x15, 0xE8, - 0xAF, 0xAB, 0x00, 0xFF, 0xA5, 0x6E, 0xC4, 0x55, - 0xA4, 0x9A, 0x1A, 0xD3, 0x0A, 0xA2, 0x4F, 0xCD - }, - { - 0x9A, 0xAF, 0x80, 0x20, 0x7B, 0xAC, 0xE1, 0x7B, - 0xB7, 0xAB, 0x14, 0x57, 0x57, 0xD5, 0x69, 0x6B, - 0xDE, 0x32, 0x40, 0x6E, 0xF2, 0x2B, 0x44, 0x29, - 0x2E, 0xF6, 0x5D, 0x45, 0x19, 0xC3, 0xBB, 0x2A, - 0xD4, 0x1A, 0x59, 0xB6, 0x2C, 0xC3, 0xE9, 0x4B, - 0x6F, 0xA9, 0x6D, 0x32, 0xA7, 0xFA, 0xAD, 0xAE, - 0x28, 0xAF, 0x7D, 0x35, 0x09, 0x72, 0x19, 0xAA, - 0x3F, 0xD8, 0xCD, 0xA3, 0x1E, 0x40, 0xC2, 0x75 - }, - { - 0xAF, 0x88, 0xB1, 0x63, 0x40, 0x2C, 0x86, 0x74, - 0x5C, 0xB6, 0x50, 0xC2, 0x98, 0x8F, 0xB9, 0x52, - 0x11, 0xB9, 0x4B, 0x03, 0xEF, 0x29, 0x0E, 0xED, - 0x96, 0x62, 0x03, 0x42, 0x41, 0xFD, 0x51, 0xCF, - 0x39, 0x8F, 0x80, 0x73, 0xE3, 0x69, 0x35, 0x4C, - 0x43, 0xEA, 0xE1, 0x05, 0x2F, 0x9B, 0x63, 0xB0, - 0x81, 0x91, 0xCA, 0xA1, 0x38, 0xAA, 0x54, 0xFE, - 0xA8, 0x89, 0xCC, 0x70, 0x24, 0x23, 0x68, 0x97 - }, - { - 0x48, 0xFA, 0x7D, 0x64, 0xE1, 0xCE, 0xEE, 0x27, - 0xB9, 0x86, 0x4D, 0xB5, 0xAD, 0xA4, 0xB5, 0x3D, - 0x00, 0xC9, 0xBC, 0x76, 0x26, 0x55, 0x58, 0x13, - 0xD3, 0xCD, 0x67, 0x30, 0xAB, 0x3C, 0xC0, 0x6F, - 0xF3, 0x42, 0xD7, 0x27, 0x90, 0x5E, 0x33, 0x17, - 0x1B, 0xDE, 0x6E, 0x84, 0x76, 0xE7, 0x7F, 0xB1, - 0x72, 0x08, 0x61, 0xE9, 0x4B, 0x73, 0xA2, 0xC5, - 0x38, 0xD2, 0x54, 0x74, 0x62, 0x85, 0xF4, 0x30 - }, - { - 0x0E, 0x6F, 0xD9, 0x7A, 0x85, 0xE9, 0x04, 0xF8, - 0x7B, 0xFE, 0x85, 0xBB, 0xEB, 0x34, 0xF6, 0x9E, - 0x1F, 0x18, 0x10, 0x5C, 0xF4, 0xED, 0x4F, 0x87, - 0xAE, 0xC3, 0x6C, 0x6E, 0x8B, 0x5F, 0x68, 0xBD, - 0x2A, 0x6F, 0x3D, 0xC8, 0xA9, 0xEC, 0xB2, 0xB6, - 0x1D, 0xB4, 0xEE, 0xDB, 0x6B, 0x2E, 0xA1, 0x0B, - 0xF9, 0xCB, 0x02, 0x51, 0xFB, 0x0F, 0x8B, 0x34, - 0x4A, 0xBF, 0x7F, 0x36, 0x6B, 0x6D, 0xE5, 0xAB - }, - { - 0x06, 0x62, 0x2D, 0xA5, 0x78, 0x71, 0x76, 0x28, - 0x7F, 0xDC, 0x8F, 0xED, 0x44, 0x0B, 0xAD, 0x18, - 0x7D, 0x83, 0x00, 0x99, 0xC9, 0x4E, 0x6D, 0x04, - 0xC8, 0xE9, 0xC9, 0x54, 0xCD, 0xA7, 0x0C, 0x8B, - 0xB9, 0xE1, 0xFC, 0x4A, 0x6D, 0x0B, 0xAA, 0x83, - 0x1B, 0x9B, 0x78, 0xEF, 0x66, 0x48, 0x68, 0x1A, - 0x48, 0x67, 0xA1, 0x1D, 0xA9, 0x3E, 0xE3, 0x6E, - 0x5E, 0x6A, 0x37, 0xD8, 0x7F, 0xC6, 0x3F, 0x6F - }, - { - 0x1D, 0xA6, 0x77, 0x2B, 0x58, 0xFA, 0xBF, 0x9C, - 0x61, 0xF6, 0x8D, 0x41, 0x2C, 0x82, 0xF1, 0x82, - 0xC0, 0x23, 0x6D, 0x7D, 0x57, 0x5E, 0xF0, 0xB5, - 0x8D, 0xD2, 0x24, 0x58, 0xD6, 0x43, 0xCD, 0x1D, - 0xFC, 0x93, 0xB0, 0x38, 0x71, 0xC3, 0x16, 0xD8, - 0x43, 0x0D, 0x31, 0x29, 0x95, 0xD4, 0x19, 0x7F, - 0x08, 0x74, 0xC9, 0x91, 0x72, 0xBA, 0x00, 0x4A, - 0x01, 0xEE, 0x29, 0x5A, 0xBA, 0xC2, 0x4E, 0x46 - }, - { - 0x3C, 0xD2, 0xD9, 0x32, 0x0B, 0x7B, 0x1D, 0x5F, - 0xB9, 0xAA, 0xB9, 0x51, 0xA7, 0x60, 0x23, 0xFA, - 0x66, 0x7B, 0xE1, 0x4A, 0x91, 0x24, 0xE3, 0x94, - 0x51, 0x39, 0x18, 0xA3, 0xF4, 0x40, 0x96, 0xAE, - 0x49, 0x04, 0xBA, 0x0F, 0xFC, 0x15, 0x0B, 0x63, - 0xBC, 0x7A, 0xB1, 0xEE, 0xB9, 0xA6, 0xE2, 0x57, - 0xE5, 0xC8, 0xF0, 0x00, 0xA7, 0x03, 0x94, 0xA5, - 0xAF, 0xD8, 0x42, 0x71, 0x5D, 0xE1, 0x5F, 0x29 - }, - { - 0x04, 0xCD, 0xC1, 0x4F, 0x74, 0x34, 0xE0, 0xB4, - 0xBE, 0x70, 0xCB, 0x41, 0xDB, 0x4C, 0x77, 0x9A, - 0x88, 0xEA, 0xEF, 0x6A, 0xCC, 0xEB, 0xCB, 0x41, - 0xF2, 0xD4, 0x2F, 0xFF, 0xE7, 0xF3, 0x2A, 0x8E, - 0x28, 0x1B, 0x5C, 0x10, 0x3A, 0x27, 0x02, 0x1D, - 0x0D, 0x08, 0x36, 0x22, 0x50, 0x75, 0x3C, 0xDF, - 0x70, 0x29, 0x21, 0x95, 0xA5, 0x3A, 0x48, 0x72, - 0x8C, 0xEB, 0x58, 0x44, 0xC2, 0xD9, 0x8B, 0xAB - }, - { - 0x90, 0x71, 0xB7, 0xA8, 0xA0, 0x75, 0xD0, 0x09, - 0x5B, 0x8F, 0xB3, 0xAE, 0x51, 0x13, 0x78, 0x57, - 0x35, 0xAB, 0x98, 0xE2, 0xB5, 0x2F, 0xAF, 0x91, - 0xD5, 0xB8, 0x9E, 0x44, 0xAA, 0xC5, 0xB5, 0xD4, - 0xEB, 0xBF, 0x91, 0x22, 0x3B, 0x0F, 0xF4, 0xC7, - 0x19, 0x05, 0xDA, 0x55, 0x34, 0x2E, 0x64, 0x65, - 0x5D, 0x6E, 0xF8, 0xC8, 0x9A, 0x47, 0x68, 0xC3, - 0xF9, 0x3A, 0x6D, 0xC0, 0x36, 0x6B, 0x5B, 0xC8 - }, - { - 0xEB, 0xB3, 0x02, 0x40, 0xDD, 0x96, 0xC7, 0xBC, - 0x8D, 0x0A, 0xBE, 0x49, 0xAA, 0x4E, 0xDC, 0xBB, - 0x4A, 0xFD, 0xC5, 0x1F, 0xF9, 0xAA, 0xF7, 0x20, - 0xD3, 0xF9, 0xE7, 0xFB, 0xB0, 0xF9, 0xC6, 0xD6, - 0x57, 0x13, 0x50, 0x50, 0x17, 0x69, 0xFC, 0x4E, - 0xBD, 0x0B, 0x21, 0x41, 0x24, 0x7F, 0xF4, 0x00, - 0xD4, 0xFD, 0x4B, 0xE4, 0x14, 0xED, 0xF3, 0x77, - 0x57, 0xBB, 0x90, 0xA3, 0x2A, 0xC5, 0xC6, 0x5A - }, - { - 0x85, 0x32, 0xC5, 0x8B, 0xF3, 0xC8, 0x01, 0x5D, - 0x9D, 0x1C, 0xBE, 0x00, 0xEE, 0xF1, 0xF5, 0x08, - 0x2F, 0x8F, 0x36, 0x32, 0xFB, 0xE9, 0xF1, 0xED, - 0x4F, 0x9D, 0xFB, 0x1F, 0xA7, 0x9E, 0x82, 0x83, - 0x06, 0x6D, 0x77, 0xC4, 0x4C, 0x4A, 0xF9, 0x43, - 0xD7, 0x6B, 0x30, 0x03, 0x64, 0xAE, 0xCB, 0xD0, - 0x64, 0x8C, 0x8A, 0x89, 0x39, 0xBD, 0x20, 0x41, - 0x23, 0xF4, 0xB5, 0x62, 0x60, 0x42, 0x2D, 0xEC - }, - { - 0xFE, 0x98, 0x46, 0xD6, 0x4F, 0x7C, 0x77, 0x08, - 0x69, 0x6F, 0x84, 0x0E, 0x2D, 0x76, 0xCB, 0x44, - 0x08, 0xB6, 0x59, 0x5C, 0x2F, 0x81, 0xEC, 0x6A, - 0x28, 0xA7, 0xF2, 0xF2, 0x0C, 0xB8, 0x8C, 0xFE, - 0x6A, 0xC0, 0xB9, 0xE9, 0xB8, 0x24, 0x4F, 0x08, - 0xBD, 0x70, 0x95, 0xC3, 0x50, 0xC1, 0xD0, 0x84, - 0x2F, 0x64, 0xFB, 0x01, 0xBB, 0x7F, 0x53, 0x2D, - 0xFC, 0xD4, 0x73, 0x71, 0xB0, 0xAE, 0xEB, 0x79 - }, - { - 0x28, 0xF1, 0x7E, 0xA6, 0xFB, 0x6C, 0x42, 0x09, - 0x2D, 0xC2, 0x64, 0x25, 0x7E, 0x29, 0x74, 0x63, - 0x21, 0xFB, 0x5B, 0xDA, 0xEA, 0x98, 0x73, 0xC2, - 0xA7, 0xFA, 0x9D, 0x8F, 0x53, 0x81, 0x8E, 0x89, - 0x9E, 0x16, 0x1B, 0xC7, 0x7D, 0xFE, 0x80, 0x90, - 0xAF, 0xD8, 0x2B, 0xF2, 0x26, 0x6C, 0x5C, 0x1B, - 0xC9, 0x30, 0xA8, 0xD1, 0x54, 0x76, 0x24, 0x43, - 0x9E, 0x66, 0x2E, 0xF6, 0x95, 0xF2, 0x6F, 0x24 - }, - { - 0xEC, 0x6B, 0x7D, 0x7F, 0x03, 0x0D, 0x48, 0x50, - 0xAC, 0xAE, 0x3C, 0xB6, 0x15, 0xC2, 0x1D, 0xD2, - 0x52, 0x06, 0xD6, 0x3E, 0x84, 0xD1, 0xDB, 0x8D, - 0x95, 0x73, 0x70, 0x73, 0x7B, 0xA0, 0xE9, 0x84, - 0x67, 0xEA, 0x0C, 0xE2, 0x74, 0xC6, 0x61, 0x99, - 0x90, 0x1E, 0xAE, 0xC1, 0x8A, 0x08, 0x52, 0x57, - 0x15, 0xF5, 0x3B, 0xFD, 0xB0, 0xAA, 0xCB, 0x61, - 0x3D, 0x34, 0x2E, 0xBD, 0xCE, 0xED, 0xDC, 0x3B - }, - { - 0xB4, 0x03, 0xD3, 0x69, 0x1C, 0x03, 0xB0, 0xD3, - 0x41, 0x8D, 0xF3, 0x27, 0xD5, 0x86, 0x0D, 0x34, - 0xBB, 0xFC, 0xC4, 0x51, 0x9B, 0xFB, 0xCE, 0x36, - 0xBF, 0x33, 0xB2, 0x08, 0x38, 0x5F, 0xAD, 0xB9, - 0x18, 0x6B, 0xC7, 0x8A, 0x76, 0xC4, 0x89, 0xD8, - 0x9F, 0xD5, 0x7E, 0x7D, 0xC7, 0x54, 0x12, 0xD2, - 0x3B, 0xCD, 0x1D, 0xAE, 0x84, 0x70, 0xCE, 0x92, - 0x74, 0x75, 0x4B, 0xB8, 0x58, 0x5B, 0x13, 0xC5 - }, - { - 0x31, 0xFC, 0x79, 0x73, 0x8B, 0x87, 0x72, 0xB3, - 0xF5, 0x5C, 0xD8, 0x17, 0x88, 0x13, 0xB3, 0xB5, - 0x2D, 0x0D, 0xB5, 0xA4, 0x19, 0xD3, 0x0B, 0xA9, - 0x49, 0x5C, 0x4B, 0x9D, 0xA0, 0x21, 0x9F, 0xAC, - 0x6D, 0xF8, 0xE7, 0xC2, 0x3A, 0x81, 0x15, 0x51, - 0xA6, 0x2B, 0x82, 0x7F, 0x25, 0x6E, 0xCD, 0xB8, - 0x12, 0x4A, 0xC8, 0xA6, 0x79, 0x2C, 0xCF, 0xEC, - 0xC3, 0xB3, 0x01, 0x27, 0x22, 0xE9, 0x44, 0x63 - }, - { - 0xBB, 0x20, 0x39, 0xEC, 0x28, 0x70, 0x91, 0xBC, - 0xC9, 0x64, 0x2F, 0xC9, 0x00, 0x49, 0xE7, 0x37, - 0x32, 0xE0, 0x2E, 0x57, 0x7E, 0x28, 0x62, 0xB3, - 0x22, 0x16, 0xAE, 0x9B, 0xED, 0xCD, 0x73, 0x0C, - 0x4C, 0x28, 0x4E, 0xF3, 0x96, 0x8C, 0x36, 0x8B, - 0x7D, 0x37, 0x58, 0x4F, 0x97, 0xBD, 0x4B, 0x4D, - 0xC6, 0xEF, 0x61, 0x27, 0xAC, 0xFE, 0x2E, 0x6A, - 0xE2, 0x50, 0x91, 0x24, 0xE6, 0x6C, 0x8A, 0xF4 - }, - { - 0xF5, 0x3D, 0x68, 0xD1, 0x3F, 0x45, 0xED, 0xFC, - 0xB9, 0xBD, 0x41, 0x5E, 0x28, 0x31, 0xE9, 0x38, - 0x35, 0x0D, 0x53, 0x80, 0xD3, 0x43, 0x22, 0x78, - 0xFC, 0x1C, 0x0C, 0x38, 0x1F, 0xCB, 0x7C, 0x65, - 0xC8, 0x2D, 0xAF, 0xE0, 0x51, 0xD8, 0xC8, 0xB0, - 0xD4, 0x4E, 0x09, 0x74, 0xA0, 0xE5, 0x9E, 0xC7, - 0xBF, 0x7E, 0xD0, 0x45, 0x9F, 0x86, 0xE9, 0x6F, - 0x32, 0x9F, 0xC7, 0x97, 0x52, 0x51, 0x0F, 0xD3 - }, - { - 0x8D, 0x56, 0x8C, 0x79, 0x84, 0xF0, 0xEC, 0xDF, - 0x76, 0x40, 0xFB, 0xC4, 0x83, 0xB5, 0xD8, 0xC9, - 0xF8, 0x66, 0x34, 0xF6, 0xF4, 0x32, 0x91, 0x84, - 0x1B, 0x30, 0x9A, 0x35, 0x0A, 0xB9, 0xC1, 0x13, - 0x7D, 0x24, 0x06, 0x6B, 0x09, 0xDA, 0x99, 0x44, - 0xBA, 0xC5, 0x4D, 0x5B, 0xB6, 0x58, 0x0D, 0x83, - 0x60, 0x47, 0xAA, 0xC7, 0x4A, 0xB7, 0x24, 0xB8, - 0x87, 0xEB, 0xF9, 0x3D, 0x4B, 0x32, 0xEC, 0xA9 - }, - { - 0xC0, 0xB6, 0x5C, 0xE5, 0xA9, 0x6F, 0xF7, 0x74, - 0xC4, 0x56, 0xCA, 0xC3, 0xB5, 0xF2, 0xC4, 0xCD, - 0x35, 0x9B, 0x4F, 0xF5, 0x3E, 0xF9, 0x3A, 0x3D, - 0xA0, 0x77, 0x8B, 0xE4, 0x90, 0x0D, 0x1E, 0x8D, - 0xA1, 0x60, 0x1E, 0x76, 0x9E, 0x8F, 0x1B, 0x02, - 0xD2, 0xA2, 0xF8, 0xC5, 0xB9, 0xFA, 0x10, 0xB4, - 0x4F, 0x1C, 0x18, 0x69, 0x85, 0x46, 0x8F, 0xEE, - 0xB0, 0x08, 0x73, 0x02, 0x83, 0xA6, 0x65, 0x7D - }, - { - 0x49, 0x00, 0xBB, 0xA6, 0xF5, 0xFB, 0x10, 0x3E, - 0xCE, 0x8E, 0xC9, 0x6A, 0xDA, 0x13, 0xA5, 0xC3, - 0xC8, 0x54, 0x88, 0xE0, 0x55, 0x51, 0xDA, 0x6B, - 0x6B, 0x33, 0xD9, 0x88, 0xE6, 0x11, 0xEC, 0x0F, - 0xE2, 0xE3, 0xC2, 0xAA, 0x48, 0xEA, 0x6A, 0xE8, - 0x98, 0x6A, 0x3A, 0x23, 0x1B, 0x22, 0x3C, 0x5D, - 0x27, 0xCE, 0xC2, 0xEA, 0xDD, 0xE9, 0x1C, 0xE0, - 0x79, 0x81, 0xEE, 0x65, 0x28, 0x62, 0xD1, 0xE4 - }, - { - 0xC7, 0xF5, 0xC3, 0x7C, 0x72, 0x85, 0xF9, 0x27, - 0xF7, 0x64, 0x43, 0x41, 0x4D, 0x43, 0x57, 0xFF, - 0x78, 0x96, 0x47, 0xD7, 0xA0, 0x05, 0xA5, 0xA7, - 0x87, 0xE0, 0x3C, 0x34, 0x6B, 0x57, 0xF4, 0x9F, - 0x21, 0xB6, 0x4F, 0xA9, 0xCF, 0x4B, 0x7E, 0x45, - 0x57, 0x3E, 0x23, 0x04, 0x90, 0x17, 0x56, 0x71, - 0x21, 0xA9, 0xC3, 0xD4, 0xB2, 0xB7, 0x3E, 0xC5, - 0xE9, 0x41, 0x35, 0x77, 0x52, 0x5D, 0xB4, 0x5A - }, - { - 0xEC, 0x70, 0x96, 0x33, 0x07, 0x36, 0xFD, 0xB2, - 0xD6, 0x4B, 0x56, 0x53, 0xE7, 0x47, 0x5D, 0xA7, - 0x46, 0xC2, 0x3A, 0x46, 0x13, 0xA8, 0x26, 0x87, - 0xA2, 0x80, 0x62, 0xD3, 0x23, 0x63, 0x64, 0x28, - 0x4A, 0xC0, 0x17, 0x20, 0xFF, 0xB4, 0x06, 0xCF, - 0xE2, 0x65, 0xC0, 0xDF, 0x62, 0x6A, 0x18, 0x8C, - 0x9E, 0x59, 0x63, 0xAC, 0xE5, 0xD3, 0xD5, 0xBB, - 0x36, 0x3E, 0x32, 0xC3, 0x8C, 0x21, 0x90, 0xA6 - }, - { - 0x82, 0xE7, 0x44, 0xC7, 0x5F, 0x46, 0x49, 0xEC, - 0x52, 0xB8, 0x07, 0x71, 0xA7, 0x7D, 0x47, 0x5A, - 0x3B, 0xC0, 0x91, 0x98, 0x95, 0x56, 0x96, 0x0E, - 0x27, 0x6A, 0x5F, 0x9E, 0xAD, 0x92, 0xA0, 0x3F, - 0x71, 0x87, 0x42, 0xCD, 0xCF, 0xEA, 0xEE, 0x5C, - 0xB8, 0x5C, 0x44, 0xAF, 0x19, 0x8A, 0xDC, 0x43, - 0xA4, 0xA4, 0x28, 0xF5, 0xF0, 0xC2, 0xDD, 0xB0, - 0xBE, 0x36, 0x05, 0x9F, 0x06, 0xD7, 0xDF, 0x73 - }, - { - 0x28, 0x34, 0xB7, 0xA7, 0x17, 0x0F, 0x1F, 0x5B, - 0x68, 0x55, 0x9A, 0xB7, 0x8C, 0x10, 0x50, 0xEC, - 0x21, 0xC9, 0x19, 0x74, 0x0B, 0x78, 0x4A, 0x90, - 0x72, 0xF6, 0xE5, 0xD6, 0x9F, 0x82, 0x8D, 0x70, - 0xC9, 0x19, 0xC5, 0x03, 0x9F, 0xB1, 0x48, 0xE3, - 0x9E, 0x2C, 0x8A, 0x52, 0x11, 0x83, 0x78, 0xB0, - 0x64, 0xCA, 0x8D, 0x50, 0x01, 0xCD, 0x10, 0xA5, - 0x47, 0x83, 0x87, 0xB9, 0x66, 0x71, 0x5E, 0xD6 - }, - { - 0x16, 0xB4, 0xAD, 0xA8, 0x83, 0xF7, 0x2F, 0x85, - 0x3B, 0xB7, 0xEF, 0x25, 0x3E, 0xFC, 0xAB, 0x0C, - 0x3E, 0x21, 0x61, 0x68, 0x7A, 0xD6, 0x15, 0x43, - 0xA0, 0xD2, 0x82, 0x4F, 0x91, 0xC1, 0xF8, 0x13, - 0x47, 0xD8, 0x6B, 0xE7, 0x09, 0xB1, 0x69, 0x96, - 0xE1, 0x7F, 0x2D, 0xD4, 0x86, 0x92, 0x7B, 0x02, - 0x88, 0xAD, 0x38, 0xD1, 0x30, 0x63, 0xC4, 0xA9, - 0x67, 0x2C, 0x39, 0x39, 0x7D, 0x37, 0x89, 0xB6 - }, - { - 0x78, 0xD0, 0x48, 0xF3, 0xA6, 0x9D, 0x8B, 0x54, - 0xAE, 0x0E, 0xD6, 0x3A, 0x57, 0x3A, 0xE3, 0x50, - 0xD8, 0x9F, 0x7C, 0x6C, 0xF1, 0xF3, 0x68, 0x89, - 0x30, 0xDE, 0x89, 0x9A, 0xFA, 0x03, 0x76, 0x97, - 0x62, 0x9B, 0x31, 0x4E, 0x5C, 0xD3, 0x03, 0xAA, - 0x62, 0xFE, 0xEA, 0x72, 0xA2, 0x5B, 0xF4, 0x2B, - 0x30, 0x4B, 0x6C, 0x6B, 0xCB, 0x27, 0xFA, 0xE2, - 0x1C, 0x16, 0xD9, 0x25, 0xE1, 0xFB, 0xDA, 0xC3 - }, - { - 0x0F, 0x74, 0x6A, 0x48, 0x74, 0x92, 0x87, 0xAD, - 0xA7, 0x7A, 0x82, 0x96, 0x1F, 0x05, 0xA4, 0xDA, - 0x4A, 0xBD, 0xB7, 0xD7, 0x7B, 0x12, 0x20, 0xF8, - 0x36, 0xD0, 0x9E, 0xC8, 0x14, 0x35, 0x9C, 0x0E, - 0xC0, 0x23, 0x9B, 0x8C, 0x7B, 0x9F, 0xF9, 0xE0, - 0x2F, 0x56, 0x9D, 0x1B, 0x30, 0x1E, 0xF6, 0x7C, - 0x46, 0x12, 0xD1, 0xDE, 0x4F, 0x73, 0x0F, 0x81, - 0xC1, 0x2C, 0x40, 0xCC, 0x06, 0x3C, 0x5C, 0xAA - }, - { - 0xF0, 0xFC, 0x85, 0x9D, 0x3B, 0xD1, 0x95, 0xFB, - 0xDC, 0x2D, 0x59, 0x1E, 0x4C, 0xDA, 0xC1, 0x51, - 0x79, 0xEC, 0x0F, 0x1D, 0xC8, 0x21, 0xC1, 0x1D, - 0xF1, 0xF0, 0xC1, 0xD2, 0x6E, 0x62, 0x60, 0xAA, - 0xA6, 0x5B, 0x79, 0xFA, 0xFA, 0xCA, 0xFD, 0x7D, - 0x3A, 0xD6, 0x1E, 0x60, 0x0F, 0x25, 0x09, 0x05, - 0xF5, 0x87, 0x8C, 0x87, 0x45, 0x28, 0x97, 0x64, - 0x7A, 0x35, 0xB9, 0x95, 0xBC, 0xAD, 0xC3, 0xA3 - }, - { - 0x26, 0x20, 0xF6, 0x87, 0xE8, 0x62, 0x5F, 0x6A, - 0x41, 0x24, 0x60, 0xB4, 0x2E, 0x2C, 0xEF, 0x67, - 0x63, 0x42, 0x08, 0xCE, 0x10, 0xA0, 0xCB, 0xD4, - 0xDF, 0xF7, 0x04, 0x4A, 0x41, 0xB7, 0x88, 0x00, - 0x77, 0xE9, 0xF8, 0xDC, 0x3B, 0x8D, 0x12, 0x16, - 0xD3, 0x37, 0x6A, 0x21, 0xE0, 0x15, 0xB5, 0x8F, - 0xB2, 0x79, 0xB5, 0x21, 0xD8, 0x3F, 0x93, 0x88, - 0xC7, 0x38, 0x2C, 0x85, 0x05, 0x59, 0x0B, 0x9B - }, - { - 0x22, 0x7E, 0x3A, 0xED, 0x8D, 0x2C, 0xB1, 0x0B, - 0x91, 0x8F, 0xCB, 0x04, 0xF9, 0xDE, 0x3E, 0x6D, - 0x0A, 0x57, 0xE0, 0x84, 0x76, 0xD9, 0x37, 0x59, - 0xCD, 0x7B, 0x2E, 0xD5, 0x4A, 0x1C, 0xBF, 0x02, - 0x39, 0xC5, 0x28, 0xFB, 0x04, 0xBB, 0xF2, 0x88, - 0x25, 0x3E, 0x60, 0x1D, 0x3B, 0xC3, 0x8B, 0x21, - 0x79, 0x4A, 0xFE, 0xF9, 0x0B, 0x17, 0x09, 0x4A, - 0x18, 0x2C, 0xAC, 0x55, 0x77, 0x45, 0xE7, 0x5F - }, - { - 0x1A, 0x92, 0x99, 0x01, 0xB0, 0x9C, 0x25, 0xF2, - 0x7D, 0x6B, 0x35, 0xBE, 0x7B, 0x2F, 0x1C, 0x47, - 0x45, 0x13, 0x1F, 0xDE, 0xBC, 0xA7, 0xF3, 0xE2, - 0x45, 0x19, 0x26, 0x72, 0x04, 0x34, 0xE0, 0xDB, - 0x6E, 0x74, 0xFD, 0x69, 0x3A, 0xD2, 0x9B, 0x77, - 0x7D, 0xC3, 0x35, 0x5C, 0x59, 0x2A, 0x36, 0x1C, - 0x48, 0x73, 0xB0, 0x11, 0x33, 0xA5, 0x7C, 0x2E, - 0x3B, 0x70, 0x75, 0xCB, 0xDB, 0x86, 0xF4, 0xFC - }, - { - 0x5F, 0xD7, 0x96, 0x8B, 0xC2, 0xFE, 0x34, 0xF2, - 0x20, 0xB5, 0xE3, 0xDC, 0x5A, 0xF9, 0x57, 0x17, - 0x42, 0xD7, 0x3B, 0x7D, 0x60, 0x81, 0x9F, 0x28, - 0x88, 0xB6, 0x29, 0x07, 0x2B, 0x96, 0xA9, 0xD8, - 0xAB, 0x2D, 0x91, 0xB8, 0x2D, 0x0A, 0x9A, 0xAB, - 0xA6, 0x1B, 0xBD, 0x39, 0x95, 0x81, 0x32, 0xFC, - 0xC4, 0x25, 0x70, 0x23, 0xD1, 0xEC, 0xA5, 0x91, - 0xB3, 0x05, 0x4E, 0x2D, 0xC8, 0x1C, 0x82, 0x00 - }, - { - 0xDF, 0xCC, 0xE8, 0xCF, 0x32, 0x87, 0x0C, 0xC6, - 0xA5, 0x03, 0xEA, 0xDA, 0xFC, 0x87, 0xFD, 0x6F, - 0x78, 0x91, 0x8B, 0x9B, 0x4D, 0x07, 0x37, 0xDB, - 0x68, 0x10, 0xBE, 0x99, 0x6B, 0x54, 0x97, 0xE7, - 0xE5, 0xCC, 0x80, 0xE3, 0x12, 0xF6, 0x1E, 0x71, - 0xFF, 0x3E, 0x96, 0x24, 0x43, 0x60, 0x73, 0x15, - 0x64, 0x03, 0xF7, 0x35, 0xF5, 0x6B, 0x0B, 0x01, - 0x84, 0x5C, 0x18, 0xF6, 0xCA, 0xF7, 0x72, 0xE6 - }, - { - 0x02, 0xF7, 0xEF, 0x3A, 0x9C, 0xE0, 0xFF, 0xF9, - 0x60, 0xF6, 0x70, 0x32, 0xB2, 0x96, 0xEF, 0xCA, - 0x30, 0x61, 0xF4, 0x93, 0x4D, 0x69, 0x07, 0x49, - 0xF2, 0xD0, 0x1C, 0x35, 0xC8, 0x1C, 0x14, 0xF3, - 0x9A, 0x67, 0xFA, 0x35, 0x0B, 0xC8, 0xA0, 0x35, - 0x9B, 0xF1, 0x72, 0x4B, 0xFF, 0xC3, 0xBC, 0xA6, - 0xD7, 0xC7, 0xBB, 0xA4, 0x79, 0x1F, 0xD5, 0x22, - 0xA3, 0xAD, 0x35, 0x3C, 0x02, 0xEC, 0x5A, 0xA8 - }, - { - 0x64, 0xBE, 0x5C, 0x6A, 0xBA, 0x65, 0xD5, 0x94, - 0x84, 0x4A, 0xE7, 0x8B, 0xB0, 0x22, 0xE5, 0xBE, - 0xBE, 0x12, 0x7F, 0xD6, 0xB6, 0xFF, 0xA5, 0xA1, - 0x37, 0x03, 0x85, 0x5A, 0xB6, 0x3B, 0x62, 0x4D, - 0xCD, 0x1A, 0x36, 0x3F, 0x99, 0x20, 0x3F, 0x63, - 0x2E, 0xC3, 0x86, 0xF3, 0xEA, 0x76, 0x7F, 0xC9, - 0x92, 0xE8, 0xED, 0x96, 0x86, 0x58, 0x6A, 0xA2, - 0x75, 0x55, 0xA8, 0x59, 0x9D, 0x5B, 0x80, 0x8F - }, - { - 0xF7, 0x85, 0x85, 0x50, 0x5C, 0x4E, 0xAA, 0x54, - 0xA8, 0xB5, 0xBE, 0x70, 0xA6, 0x1E, 0x73, 0x5E, - 0x0F, 0xF9, 0x7A, 0xF9, 0x44, 0xDD, 0xB3, 0x00, - 0x1E, 0x35, 0xD8, 0x6C, 0x4E, 0x21, 0x99, 0xD9, - 0x76, 0x10, 0x4B, 0x6A, 0xE3, 0x17, 0x50, 0xA3, - 0x6A, 0x72, 0x6E, 0xD2, 0x85, 0x06, 0x4F, 0x59, - 0x81, 0xB5, 0x03, 0x88, 0x9F, 0xEF, 0x82, 0x2F, - 0xCD, 0xC2, 0x89, 0x8D, 0xDD, 0xB7, 0x88, 0x9A - }, - { - 0xE4, 0xB5, 0x56, 0x60, 0x33, 0x86, 0x95, 0x72, - 0xED, 0xFD, 0x87, 0x47, 0x9A, 0x5B, 0xB7, 0x3C, - 0x80, 0xE8, 0x75, 0x9B, 0x91, 0x23, 0x28, 0x79, - 0xD9, 0x6B, 0x1D, 0xDA, 0x36, 0xC0, 0x12, 0x07, - 0x6E, 0xE5, 0xA2, 0xED, 0x7A, 0xE2, 0xDE, 0x63, - 0xEF, 0x84, 0x06, 0xA0, 0x6A, 0xEA, 0x82, 0xC1, - 0x88, 0x03, 0x1B, 0x56, 0x0B, 0xEA, 0xFB, 0x58, - 0x3F, 0xB3, 0xDE, 0x9E, 0x57, 0x95, 0x2A, 0x7E - }, - { - 0xE1, 0xB3, 0xE7, 0xED, 0x86, 0x7F, 0x6C, 0x94, - 0x84, 0xA2, 0xA9, 0x7F, 0x77, 0x15, 0xF2, 0x5E, - 0x25, 0x29, 0x4E, 0x99, 0x2E, 0x41, 0xF6, 0xA7, - 0xC1, 0x61, 0xFF, 0xC2, 0xAD, 0xC6, 0xDA, 0xAE, - 0xB7, 0x11, 0x31, 0x02, 0xD5, 0xE6, 0x09, 0x02, - 0x87, 0xFE, 0x6A, 0xD9, 0x4C, 0xE5, 0xD6, 0xB7, - 0x39, 0xC6, 0xCA, 0x24, 0x0B, 0x05, 0xC7, 0x6F, - 0xB7, 0x3F, 0x25, 0xDD, 0x02, 0x4B, 0xF9, 0x35 - }, - { - 0x85, 0xFD, 0x08, 0x5F, 0xDC, 0x12, 0xA0, 0x80, - 0x98, 0x3D, 0xF0, 0x7B, 0xD7, 0x01, 0x2B, 0x0D, - 0x40, 0x2A, 0x0F, 0x40, 0x43, 0xFC, 0xB2, 0x77, - 0x5A, 0xDF, 0x0B, 0xAD, 0x17, 0x4F, 0x9B, 0x08, - 0xD1, 0x67, 0x6E, 0x47, 0x69, 0x85, 0x78, 0x5C, - 0x0A, 0x5D, 0xCC, 0x41, 0xDB, 0xFF, 0x6D, 0x95, - 0xEF, 0x4D, 0x66, 0xA3, 0xFB, 0xDC, 0x4A, 0x74, - 0xB8, 0x2B, 0xA5, 0x2D, 0xA0, 0x51, 0x2B, 0x74 - }, - { - 0xAE, 0xD8, 0xFA, 0x76, 0x4B, 0x0F, 0xBF, 0xF8, - 0x21, 0xE0, 0x52, 0x33, 0xD2, 0xF7, 0xB0, 0x90, - 0x0E, 0xC4, 0x4D, 0x82, 0x6F, 0x95, 0xE9, 0x3C, - 0x34, 0x3C, 0x1B, 0xC3, 0xBA, 0x5A, 0x24, 0x37, - 0x4B, 0x1D, 0x61, 0x6E, 0x7E, 0x7A, 0xBA, 0x45, - 0x3A, 0x0A, 0xDA, 0x5E, 0x4F, 0xAB, 0x53, 0x82, - 0x40, 0x9E, 0x0D, 0x42, 0xCE, 0x9C, 0x2B, 0xC7, - 0xFB, 0x39, 0xA9, 0x9C, 0x34, 0x0C, 0x20, 0xF0 - }, - { - 0x7B, 0xA3, 0xB2, 0xE2, 0x97, 0x23, 0x35, 0x22, - 0xEE, 0xB3, 0x43, 0xBD, 0x3E, 0xBC, 0xFD, 0x83, - 0x5A, 0x04, 0x00, 0x77, 0x35, 0xE8, 0x7F, 0x0C, - 0xA3, 0x00, 0xCB, 0xEE, 0x6D, 0x41, 0x65, 0x65, - 0x16, 0x21, 0x71, 0x58, 0x1E, 0x40, 0x20, 0xFF, - 0x4C, 0xF1, 0x76, 0x45, 0x0F, 0x12, 0x91, 0xEA, - 0x22, 0x85, 0xCB, 0x9E, 0xBF, 0xFE, 0x4C, 0x56, - 0x66, 0x06, 0x27, 0x68, 0x51, 0x45, 0x05, 0x1C - }, - { - 0xDE, 0x74, 0x8B, 0xCF, 0x89, 0xEC, 0x88, 0x08, - 0x47, 0x21, 0xE1, 0x6B, 0x85, 0xF3, 0x0A, 0xDB, - 0x1A, 0x61, 0x34, 0xD6, 0x64, 0xB5, 0x84, 0x35, - 0x69, 0xBA, 0xBC, 0x5B, 0xBD, 0x1A, 0x15, 0xCA, - 0x9B, 0x61, 0x80, 0x3C, 0x90, 0x1A, 0x4F, 0xEF, - 0x32, 0x96, 0x5A, 0x17, 0x49, 0xC9, 0xF3, 0xA4, - 0xE2, 0x43, 0xE1, 0x73, 0x93, 0x9D, 0xC5, 0xA8, - 0xDC, 0x49, 0x5C, 0x67, 0x1A, 0xB5, 0x21, 0x45 - }, - { - 0xAA, 0xF4, 0xD2, 0xBD, 0xF2, 0x00, 0xA9, 0x19, - 0x70, 0x6D, 0x98, 0x42, 0xDC, 0xE1, 0x6C, 0x98, - 0x14, 0x0D, 0x34, 0xBC, 0x43, 0x3D, 0xF3, 0x20, - 0xAB, 0xA9, 0xBD, 0x42, 0x9E, 0x54, 0x9A, 0xA7, - 0xA3, 0x39, 0x76, 0x52, 0xA4, 0xD7, 0x68, 0x27, - 0x77, 0x86, 0xCF, 0x99, 0x3C, 0xDE, 0x23, 0x38, - 0x67, 0x3E, 0xD2, 0xE6, 0xB6, 0x6C, 0x96, 0x1F, - 0xEF, 0xB8, 0x2C, 0xD2, 0x0C, 0x93, 0x33, 0x8F - }, - { - 0xC4, 0x08, 0x21, 0x89, 0x68, 0xB7, 0x88, 0xBF, - 0x86, 0x4F, 0x09, 0x97, 0xE6, 0xBC, 0x4C, 0x3D, - 0xBA, 0x68, 0xB2, 0x76, 0xE2, 0x12, 0x5A, 0x48, - 0x43, 0x29, 0x60, 0x52, 0xFF, 0x93, 0xBF, 0x57, - 0x67, 0xB8, 0xCD, 0xCE, 0x71, 0x31, 0xF0, 0x87, - 0x64, 0x30, 0xC1, 0x16, 0x5F, 0xEC, 0x6C, 0x4F, - 0x47, 0xAD, 0xAA, 0x4F, 0xD8, 0xBC, 0xFA, 0xCE, - 0xF4, 0x63, 0xB5, 0xD3, 0xD0, 0xFA, 0x61, 0xA0 - }, - { - 0x76, 0xD2, 0xD8, 0x19, 0xC9, 0x2B, 0xCE, 0x55, - 0xFA, 0x8E, 0x09, 0x2A, 0xB1, 0xBF, 0x9B, 0x9E, - 0xAB, 0x23, 0x7A, 0x25, 0x26, 0x79, 0x86, 0xCA, - 0xCF, 0x2B, 0x8E, 0xE1, 0x4D, 0x21, 0x4D, 0x73, - 0x0D, 0xC9, 0xA5, 0xAA, 0x2D, 0x7B, 0x59, 0x6E, - 0x86, 0xA1, 0xFD, 0x8F, 0xA0, 0x80, 0x4C, 0x77, - 0x40, 0x2D, 0x2F, 0xCD, 0x45, 0x08, 0x36, 0x88, - 0xB2, 0x18, 0xB1, 0xCD, 0xFA, 0x0D, 0xCB, 0xCB - }, - { - 0x72, 0x06, 0x5E, 0xE4, 0xDD, 0x91, 0xC2, 0xD8, - 0x50, 0x9F, 0xA1, 0xFC, 0x28, 0xA3, 0x7C, 0x7F, - 0xC9, 0xFA, 0x7D, 0x5B, 0x3F, 0x8A, 0xD3, 0xD0, - 0xD7, 0xA2, 0x56, 0x26, 0xB5, 0x7B, 0x1B, 0x44, - 0x78, 0x8D, 0x4C, 0xAF, 0x80, 0x62, 0x90, 0x42, - 0x5F, 0x98, 0x90, 0xA3, 0xA2, 0xA3, 0x5A, 0x90, - 0x5A, 0xB4, 0xB3, 0x7A, 0xCF, 0xD0, 0xDA, 0x6E, - 0x45, 0x17, 0xB2, 0x52, 0x5C, 0x96, 0x51, 0xE4 - }, - { - 0x64, 0x47, 0x5D, 0xFE, 0x76, 0x00, 0xD7, 0x17, - 0x1B, 0xEA, 0x0B, 0x39, 0x4E, 0x27, 0xC9, 0xB0, - 0x0D, 0x8E, 0x74, 0xDD, 0x1E, 0x41, 0x6A, 0x79, - 0x47, 0x36, 0x82, 0xAD, 0x3D, 0xFD, 0xBB, 0x70, - 0x66, 0x31, 0x55, 0x80, 0x55, 0xCF, 0xC8, 0xA4, - 0x0E, 0x07, 0xBD, 0x01, 0x5A, 0x45, 0x40, 0xDC, - 0xDE, 0xA1, 0x58, 0x83, 0xCB, 0xBF, 0x31, 0x41, - 0x2D, 0xF1, 0xDE, 0x1C, 0xD4, 0x15, 0x2B, 0x91 - }, - { - 0x12, 0xCD, 0x16, 0x74, 0xA4, 0x48, 0x8A, 0x5D, - 0x7C, 0x2B, 0x31, 0x60, 0xD2, 0xE2, 0xC4, 0xB5, - 0x83, 0x71, 0xBE, 0xDA, 0xD7, 0x93, 0x41, 0x8D, - 0x6F, 0x19, 0xC6, 0xEE, 0x38, 0x5D, 0x70, 0xB3, - 0xE0, 0x67, 0x39, 0x36, 0x9D, 0x4D, 0xF9, 0x10, - 0xED, 0xB0, 0xB0, 0xA5, 0x4C, 0xBF, 0xF4, 0x3D, - 0x54, 0x54, 0x4C, 0xD3, 0x7A, 0xB3, 0xA0, 0x6C, - 0xFA, 0x0A, 0x3D, 0xDA, 0xC8, 0xB6, 0x6C, 0x89 - }, - { - 0x60, 0x75, 0x69, 0x66, 0x47, 0x9D, 0xED, 0xC6, - 0xDD, 0x4B, 0xCF, 0xF8, 0xEA, 0x7D, 0x1D, 0x4C, - 0xE4, 0xD4, 0xAF, 0x2E, 0x7B, 0x09, 0x7E, 0x32, - 0xE3, 0x76, 0x35, 0x18, 0x44, 0x11, 0x47, 0xCC, - 0x12, 0xB3, 0xC0, 0xEE, 0x6D, 0x2E, 0xCA, 0xBF, - 0x11, 0x98, 0xCE, 0xC9, 0x2E, 0x86, 0xA3, 0x61, - 0x6F, 0xBA, 0x4F, 0x4E, 0x87, 0x2F, 0x58, 0x25, - 0x33, 0x0A, 0xDB, 0xB4, 0xC1, 0xDE, 0xE4, 0x44 - }, - { - 0xA7, 0x80, 0x3B, 0xCB, 0x71, 0xBC, 0x1D, 0x0F, - 0x43, 0x83, 0xDD, 0xE1, 0xE0, 0x61, 0x2E, 0x04, - 0xF8, 0x72, 0xB7, 0x15, 0xAD, 0x30, 0x81, 0x5C, - 0x22, 0x49, 0xCF, 0x34, 0xAB, 0xB8, 0xB0, 0x24, - 0x91, 0x5C, 0xB2, 0xFC, 0x9F, 0x4E, 0x7C, 0xC4, - 0xC8, 0xCF, 0xD4, 0x5B, 0xE2, 0xD5, 0xA9, 0x1E, - 0xAB, 0x09, 0x41, 0xC7, 0xD2, 0x70, 0xE2, 0xDA, - 0x4C, 0xA4, 0xA9, 0xF7, 0xAC, 0x68, 0x66, 0x3A - }, - { - 0xB8, 0x4E, 0xF6, 0xA7, 0x22, 0x9A, 0x34, 0xA7, - 0x50, 0xD9, 0xA9, 0x8E, 0xE2, 0x52, 0x98, 0x71, - 0x81, 0x6B, 0x87, 0xFB, 0xE3, 0xBC, 0x45, 0xB4, - 0x5F, 0xA5, 0xAE, 0x82, 0xD5, 0x14, 0x15, 0x40, - 0x21, 0x11, 0x65, 0xC3, 0xC5, 0xD7, 0xA7, 0x47, - 0x6B, 0xA5, 0xA4, 0xAA, 0x06, 0xD6, 0x64, 0x76, - 0xF0, 0xD9, 0xDC, 0x49, 0xA3, 0xF1, 0xEE, 0x72, - 0xC3, 0xAC, 0xAB, 0xD4, 0x98, 0x96, 0x74, 0x14 - }, - { - 0xFA, 0xE4, 0xB6, 0xD8, 0xEF, 0xC3, 0xF8, 0xC8, - 0xE6, 0x4D, 0x00, 0x1D, 0xAB, 0xEC, 0x3A, 0x21, - 0xF5, 0x44, 0xE8, 0x27, 0x14, 0x74, 0x52, 0x51, - 0xB2, 0xB4, 0xB3, 0x93, 0xF2, 0xF4, 0x3E, 0x0D, - 0xA3, 0xD4, 0x03, 0xC6, 0x4D, 0xB9, 0x5A, 0x2C, - 0xB6, 0xE2, 0x3E, 0xBB, 0x7B, 0x9E, 0x94, 0xCD, - 0xD5, 0xDD, 0xAC, 0x54, 0xF0, 0x7C, 0x4A, 0x61, - 0xBD, 0x3C, 0xB1, 0x0A, 0xA6, 0xF9, 0x3B, 0x49 - }, - { - 0x34, 0xF7, 0x28, 0x66, 0x05, 0xA1, 0x22, 0x36, - 0x95, 0x40, 0x14, 0x1D, 0xED, 0x79, 0xB8, 0x95, - 0x72, 0x55, 0xDA, 0x2D, 0x41, 0x55, 0xAB, 0xBF, - 0x5A, 0x8D, 0xBB, 0x89, 0xC8, 0xEB, 0x7E, 0xDE, - 0x8E, 0xEE, 0xF1, 0xDA, 0xA4, 0x6D, 0xC2, 0x9D, - 0x75, 0x1D, 0x04, 0x5D, 0xC3, 0xB1, 0xD6, 0x58, - 0xBB, 0x64, 0xB8, 0x0F, 0xF8, 0x58, 0x9E, 0xDD, - 0xB3, 0x82, 0x4B, 0x13, 0xDA, 0x23, 0x5A, 0x6B - }, - { - 0x3B, 0x3B, 0x48, 0x43, 0x4B, 0xE2, 0x7B, 0x9E, - 0xAB, 0xAB, 0xBA, 0x43, 0xBF, 0x6B, 0x35, 0xF1, - 0x4B, 0x30, 0xF6, 0xA8, 0x8D, 0xC2, 0xE7, 0x50, - 0xC3, 0x58, 0x47, 0x0D, 0x6B, 0x3A, 0xA3, 0xC1, - 0x8E, 0x47, 0xDB, 0x40, 0x17, 0xFA, 0x55, 0x10, - 0x6D, 0x82, 0x52, 0xF0, 0x16, 0x37, 0x1A, 0x00, - 0xF5, 0xF8, 0xB0, 0x70, 0xB7, 0x4B, 0xA5, 0xF2, - 0x3C, 0xFF, 0xC5, 0x51, 0x1C, 0x9F, 0x09, 0xF0 - }, - { - 0xBA, 0x28, 0x9E, 0xBD, 0x65, 0x62, 0xC4, 0x8C, - 0x3E, 0x10, 0xA8, 0xAD, 0x6C, 0xE0, 0x2E, 0x73, - 0x43, 0x3D, 0x1E, 0x93, 0xD7, 0xC9, 0x27, 0x9D, - 0x4D, 0x60, 0xA7, 0xE8, 0x79, 0xEE, 0x11, 0xF4, - 0x41, 0xA0, 0x00, 0xF4, 0x8E, 0xD9, 0xF7, 0xC4, - 0xED, 0x87, 0xA4, 0x51, 0x36, 0xD7, 0xDC, 0xCD, - 0xCA, 0x48, 0x21, 0x09, 0xC7, 0x8A, 0x51, 0x06, - 0x2B, 0x3B, 0xA4, 0x04, 0x4A, 0xDA, 0x24, 0x69 - }, - { - 0x02, 0x29, 0x39, 0xE2, 0x38, 0x6C, 0x5A, 0x37, - 0x04, 0x98, 0x56, 0xC8, 0x50, 0xA2, 0xBB, 0x10, - 0xA1, 0x3D, 0xFE, 0xA4, 0x21, 0x2B, 0x4C, 0x73, - 0x2A, 0x88, 0x40, 0xA9, 0xFF, 0xA5, 0xFA, 0xF5, - 0x48, 0x75, 0xC5, 0x44, 0x88, 0x16, 0xB2, 0x78, - 0x5A, 0x00, 0x7D, 0xA8, 0xA8, 0xD2, 0xBC, 0x7D, - 0x71, 0xA5, 0x4E, 0x4E, 0x65, 0x71, 0xF1, 0x0B, - 0x60, 0x0C, 0xBD, 0xB2, 0x5D, 0x13, 0xED, 0xE3 - }, - { - 0xE6, 0xFE, 0xC1, 0x9D, 0x89, 0xCE, 0x87, 0x17, - 0xB1, 0xA0, 0x87, 0x02, 0x46, 0x70, 0xFE, 0x02, - 0x6F, 0x6C, 0x7C, 0xBD, 0xA1, 0x1C, 0xAE, 0xF9, - 0x59, 0xBB, 0x2D, 0x35, 0x1B, 0xF8, 0x56, 0xF8, - 0x05, 0x5D, 0x1C, 0x0E, 0xBD, 0xAA, 0xA9, 0xD1, - 0xB1, 0x78, 0x86, 0xFC, 0x2C, 0x56, 0x2B, 0x5E, - 0x99, 0x64, 0x2F, 0xC0, 0x64, 0x71, 0x0C, 0x0D, - 0x34, 0x88, 0xA0, 0x2B, 0x5E, 0xD7, 0xF6, 0xFD - }, - { - 0x94, 0xC9, 0x6F, 0x02, 0xA8, 0xF5, 0x76, 0xAC, - 0xA3, 0x2B, 0xA6, 0x1C, 0x2B, 0x20, 0x6F, 0x90, - 0x72, 0x85, 0xD9, 0x29, 0x9B, 0x83, 0xAC, 0x17, - 0x5C, 0x20, 0x9A, 0x8D, 0x43, 0xD5, 0x3B, 0xFE, - 0x68, 0x3D, 0xD1, 0xD8, 0x3E, 0x75, 0x49, 0xCB, - 0x90, 0x6C, 0x28, 0xF5, 0x9A, 0xB7, 0xC4, 0x6F, - 0x87, 0x51, 0x36, 0x6A, 0x28, 0xC3, 0x9D, 0xD5, - 0xFE, 0x26, 0x93, 0xC9, 0x01, 0x96, 0x66, 0xC8 - }, - { - 0x31, 0xA0, 0xCD, 0x21, 0x5E, 0xBD, 0x2C, 0xB6, - 0x1D, 0xE5, 0xB9, 0xED, 0xC9, 0x1E, 0x61, 0x95, - 0xE3, 0x1C, 0x59, 0xA5, 0x64, 0x8D, 0x5C, 0x9F, - 0x73, 0x7E, 0x12, 0x5B, 0x26, 0x05, 0x70, 0x8F, - 0x2E, 0x32, 0x5A, 0xB3, 0x38, 0x1C, 0x8D, 0xCE, - 0x1A, 0x3E, 0x95, 0x88, 0x86, 0xF1, 0xEC, 0xDC, - 0x60, 0x31, 0x8F, 0x88, 0x2C, 0xFE, 0x20, 0xA2, - 0x41, 0x91, 0x35, 0x2E, 0x61, 0x7B, 0x0F, 0x21 - }, - { - 0x91, 0xAB, 0x50, 0x4A, 0x52, 0x2D, 0xCE, 0x78, - 0x77, 0x9F, 0x4C, 0x6C, 0x6B, 0xA2, 0xE6, 0xB6, - 0xDB, 0x55, 0x65, 0xC7, 0x6D, 0x3E, 0x7E, 0x7C, - 0x92, 0x0C, 0xAF, 0x7F, 0x75, 0x7E, 0xF9, 0xDB, - 0x7C, 0x8F, 0xCF, 0x10, 0xE5, 0x7F, 0x03, 0x37, - 0x9E, 0xA9, 0xBF, 0x75, 0xEB, 0x59, 0x89, 0x5D, - 0x96, 0xE1, 0x49, 0x80, 0x0B, 0x6A, 0xAE, 0x01, - 0xDB, 0x77, 0x8B, 0xB9, 0x0A, 0xFB, 0xC9, 0x89 - }, - { - 0xD8, 0x5C, 0xAB, 0xC6, 0xBD, 0x5B, 0x1A, 0x01, - 0xA5, 0xAF, 0xD8, 0xC6, 0x73, 0x47, 0x40, 0xDA, - 0x9F, 0xD1, 0xC1, 0xAC, 0xC6, 0xDB, 0x29, 0xBF, - 0xC8, 0xA2, 0xE5, 0xB6, 0x68, 0xB0, 0x28, 0xB6, - 0xB3, 0x15, 0x4B, 0xFB, 0x87, 0x03, 0xFA, 0x31, - 0x80, 0x25, 0x1D, 0x58, 0x9A, 0xD3, 0x80, 0x40, - 0xCE, 0xB7, 0x07, 0xC4, 0xBA, 0xD1, 0xB5, 0x34, - 0x3C, 0xB4, 0x26, 0xB6, 0x1E, 0xAA, 0x49, 0xC1 - }, - { - 0xD6, 0x2E, 0xFB, 0xEC, 0x2C, 0xA9, 0xC1, 0xF8, - 0xBD, 0x66, 0xCE, 0x8B, 0x3F, 0x6A, 0x89, 0x8C, - 0xB3, 0xF7, 0x56, 0x6B, 0xA6, 0x56, 0x8C, 0x61, - 0x8A, 0xD1, 0xFE, 0xB2, 0xB6, 0x5B, 0x76, 0xC3, - 0xCE, 0x1D, 0xD2, 0x0F, 0x73, 0x95, 0x37, 0x2F, - 0xAF, 0x28, 0x42, 0x7F, 0x61, 0xC9, 0x27, 0x80, - 0x49, 0xCF, 0x01, 0x40, 0xDF, 0x43, 0x4F, 0x56, - 0x33, 0x04, 0x8C, 0x86, 0xB8, 0x1E, 0x03, 0x99 - }, - { - 0x7C, 0x8F, 0xDC, 0x61, 0x75, 0x43, 0x9E, 0x2C, - 0x3D, 0xB1, 0x5B, 0xAF, 0xA7, 0xFB, 0x06, 0x14, - 0x3A, 0x6A, 0x23, 0xBC, 0x90, 0xF4, 0x49, 0xE7, - 0x9D, 0xEE, 0xF7, 0x3C, 0x3D, 0x49, 0x2A, 0x67, - 0x17, 0x15, 0xC1, 0x93, 0xB6, 0xFE, 0xA9, 0xF0, - 0x36, 0x05, 0x0B, 0x94, 0x60, 0x69, 0x85, 0x6B, - 0x89, 0x7E, 0x08, 0xC0, 0x07, 0x68, 0xF5, 0xEE, - 0x5D, 0xDC, 0xF7, 0x0B, 0x7C, 0xD6, 0xD0, 0xE0 - }, - { - 0x58, 0x60, 0x2E, 0xE7, 0x46, 0x8E, 0x6B, 0xC9, - 0xDF, 0x21, 0xBD, 0x51, 0xB2, 0x3C, 0x00, 0x5F, - 0x72, 0xD6, 0xCB, 0x01, 0x3F, 0x0A, 0x1B, 0x48, - 0xCB, 0xEC, 0x5E, 0xCA, 0x29, 0x92, 0x99, 0xF9, - 0x7F, 0x09, 0xF5, 0x4A, 0x9A, 0x01, 0x48, 0x3E, - 0xAE, 0xB3, 0x15, 0xA6, 0x47, 0x8B, 0xAD, 0x37, - 0xBA, 0x47, 0xCA, 0x13, 0x47, 0xC7, 0xC8, 0xFC, - 0x9E, 0x66, 0x95, 0x59, 0x2C, 0x91, 0xD7, 0x23 - }, - { - 0x27, 0xF5, 0xB7, 0x9E, 0xD2, 0x56, 0xB0, 0x50, - 0x99, 0x3D, 0x79, 0x34, 0x96, 0xED, 0xF4, 0x80, - 0x7C, 0x1D, 0x85, 0xA7, 0xB0, 0xA6, 0x7C, 0x9C, - 0x4F, 0xA9, 0x98, 0x60, 0x75, 0x0B, 0x0A, 0xE6, - 0x69, 0x89, 0x67, 0x0A, 0x8F, 0xFD, 0x78, 0x56, - 0xD7, 0xCE, 0x41, 0x15, 0x99, 0xE5, 0x8C, 0x4D, - 0x77, 0xB2, 0x32, 0xA6, 0x2B, 0xEF, 0x64, 0xD1, - 0x52, 0x75, 0xBE, 0x46, 0xA6, 0x82, 0x35, 0xFF - }, - { - 0x39, 0x57, 0xA9, 0x76, 0xB9, 0xF1, 0x88, 0x7B, - 0xF0, 0x04, 0xA8, 0xDC, 0xA9, 0x42, 0xC9, 0x2D, - 0x2B, 0x37, 0xEA, 0x52, 0x60, 0x0F, 0x25, 0xE0, - 0xC9, 0xBC, 0x57, 0x07, 0xD0, 0x27, 0x9C, 0x00, - 0xC6, 0xE8, 0x5A, 0x83, 0x9B, 0x0D, 0x2D, 0x8E, - 0xB5, 0x9C, 0x51, 0xD9, 0x47, 0x88, 0xEB, 0xE6, - 0x24, 0x74, 0xA7, 0x91, 0xCA, 0xDF, 0x52, 0xCC, - 0xCF, 0x20, 0xF5, 0x07, 0x0B, 0x65, 0x73, 0xFC - }, - { - 0xEA, 0xA2, 0x37, 0x6D, 0x55, 0x38, 0x0B, 0xF7, - 0x72, 0xEC, 0xCA, 0x9C, 0xB0, 0xAA, 0x46, 0x68, - 0xC9, 0x5C, 0x70, 0x71, 0x62, 0xFA, 0x86, 0xD5, - 0x18, 0xC8, 0xCE, 0x0C, 0xA9, 0xBF, 0x73, 0x62, - 0xB9, 0xF2, 0xA0, 0xAD, 0xC3, 0xFF, 0x59, 0x92, - 0x2D, 0xF9, 0x21, 0xB9, 0x45, 0x67, 0xE8, 0x1E, - 0x45, 0x2F, 0x6C, 0x1A, 0x07, 0xFC, 0x81, 0x7C, - 0xEB, 0xE9, 0x96, 0x04, 0xB3, 0x50, 0x5D, 0x38 - }, - { - 0xC1, 0xE2, 0xC7, 0x8B, 0x6B, 0x27, 0x34, 0xE2, - 0x48, 0x0E, 0xC5, 0x50, 0x43, 0x4C, 0xB5, 0xD6, - 0x13, 0x11, 0x1A, 0xDC, 0xC2, 0x1D, 0x47, 0x55, - 0x45, 0xC3, 0xB1, 0xB7, 0xE6, 0xFF, 0x12, 0x44, - 0x44, 0x76, 0xE5, 0xC0, 0x55, 0x13, 0x2E, 0x22, - 0x29, 0xDC, 0x0F, 0x80, 0x70, 0x44, 0xBB, 0x91, - 0x9B, 0x1A, 0x56, 0x62, 0xDD, 0x38, 0xA9, 0xEE, - 0x65, 0xE2, 0x43, 0xA3, 0x91, 0x1A, 0xED, 0x1A - }, - { - 0x8A, 0xB4, 0x87, 0x13, 0x38, 0x9D, 0xD0, 0xFC, - 0xF9, 0xF9, 0x65, 0xD3, 0xCE, 0x66, 0xB1, 0xE5, - 0x59, 0xA1, 0xF8, 0xC5, 0x87, 0x41, 0xD6, 0x76, - 0x83, 0xCD, 0x97, 0x13, 0x54, 0xF4, 0x52, 0xE6, - 0x2D, 0x02, 0x07, 0xA6, 0x5E, 0x43, 0x6C, 0x5D, - 0x5D, 0x8F, 0x8E, 0xE7, 0x1C, 0x6A, 0xBF, 0xE5, - 0x0E, 0x66, 0x90, 0x04, 0xC3, 0x02, 0xB3, 0x1A, - 0x7E, 0xA8, 0x31, 0x1D, 0x4A, 0x91, 0x60, 0x51 - }, - { - 0x24, 0xCE, 0x0A, 0xDD, 0xAA, 0x4C, 0x65, 0x03, - 0x8B, 0xD1, 0xB1, 0xC0, 0xF1, 0x45, 0x2A, 0x0B, - 0x12, 0x87, 0x77, 0xAA, 0xBC, 0x94, 0xA2, 0x9D, - 0xF2, 0xFD, 0x6C, 0x7E, 0x2F, 0x85, 0xF8, 0xAB, - 0x9A, 0xC7, 0xEF, 0xF5, 0x16, 0xB0, 0xE0, 0xA8, - 0x25, 0xC8, 0x4A, 0x24, 0xCF, 0xE4, 0x92, 0xEA, - 0xAD, 0x0A, 0x63, 0x08, 0xE4, 0x6D, 0xD4, 0x2F, - 0xE8, 0x33, 0x3A, 0xB9, 0x71, 0xBB, 0x30, 0xCA - }, - { - 0x51, 0x54, 0xF9, 0x29, 0xEE, 0x03, 0x04, 0x5B, - 0x6B, 0x0C, 0x00, 0x04, 0xFA, 0x77, 0x8E, 0xDE, - 0xE1, 0xD1, 0x39, 0x89, 0x32, 0x67, 0xCC, 0x84, - 0x82, 0x5A, 0xD7, 0xB3, 0x6C, 0x63, 0xDE, 0x32, - 0x79, 0x8E, 0x4A, 0x16, 0x6D, 0x24, 0x68, 0x65, - 0x61, 0x35, 0x4F, 0x63, 0xB0, 0x07, 0x09, 0xA1, - 0x36, 0x4B, 0x3C, 0x24, 0x1D, 0xE3, 0xFE, 0xBF, - 0x07, 0x54, 0x04, 0x58, 0x97, 0x46, 0x7C, 0xD4 - }, - { - 0xE7, 0x4E, 0x90, 0x79, 0x20, 0xFD, 0x87, 0xBD, - 0x5A, 0xD6, 0x36, 0xDD, 0x11, 0x08, 0x5E, 0x50, - 0xEE, 0x70, 0x45, 0x9C, 0x44, 0x3E, 0x1C, 0xE5, - 0x80, 0x9A, 0xF2, 0xBC, 0x2E, 0xBA, 0x39, 0xF9, - 0xE6, 0xD7, 0x12, 0x8E, 0x0E, 0x37, 0x12, 0xC3, - 0x16, 0xDA, 0x06, 0xF4, 0x70, 0x5D, 0x78, 0xA4, - 0x83, 0x8E, 0x28, 0x12, 0x1D, 0x43, 0x44, 0xA2, - 0xC7, 0x9C, 0x5E, 0x0D, 0xB3, 0x07, 0xA6, 0x77 - }, - { - 0xBF, 0x91, 0xA2, 0x23, 0x34, 0xBA, 0xC2, 0x0F, - 0x3F, 0xD8, 0x06, 0x63, 0xB3, 0xCD, 0x06, 0xC4, - 0xE8, 0x80, 0x2F, 0x30, 0xE6, 0xB5, 0x9F, 0x90, - 0xD3, 0x03, 0x5C, 0xC9, 0x79, 0x8A, 0x21, 0x7E, - 0xD5, 0xA3, 0x1A, 0xBB, 0xDA, 0x7F, 0xA6, 0x84, - 0x28, 0x27, 0xBD, 0xF2, 0xA7, 0xA1, 0xC2, 0x1F, - 0x6F, 0xCF, 0xCC, 0xBB, 0x54, 0xC6, 0xC5, 0x29, - 0x26, 0xF3, 0x2D, 0xA8, 0x16, 0x26, 0x9B, 0xE1 - }, - { - 0xD9, 0xD5, 0xC7, 0x4B, 0xE5, 0x12, 0x1B, 0x0B, - 0xD7, 0x42, 0xF2, 0x6B, 0xFF, 0xB8, 0xC8, 0x9F, - 0x89, 0x17, 0x1F, 0x3F, 0x93, 0x49, 0x13, 0x49, - 0x2B, 0x09, 0x03, 0xC2, 0x71, 0xBB, 0xE2, 0xB3, - 0x39, 0x5E, 0xF2, 0x59, 0x66, 0x9B, 0xEF, 0x43, - 0xB5, 0x7F, 0x7F, 0xCC, 0x30, 0x27, 0xDB, 0x01, - 0x82, 0x3F, 0x6B, 0xAE, 0xE6, 0x6E, 0x4F, 0x9F, - 0xEA, 0xD4, 0xD6, 0x72, 0x6C, 0x74, 0x1F, 0xCE - }, - { - 0x50, 0xC8, 0xB8, 0xCF, 0x34, 0xCD, 0x87, 0x9F, - 0x80, 0xE2, 0xFA, 0xAB, 0x32, 0x30, 0xB0, 0xC0, - 0xE1, 0xCC, 0x3E, 0x9D, 0xCA, 0xDE, 0xB1, 0xB9, - 0xD9, 0x7A, 0xB9, 0x23, 0x41, 0x5D, 0xD9, 0xA1, - 0xFE, 0x38, 0xAD, 0xDD, 0x5C, 0x11, 0x75, 0x6C, - 0x67, 0x99, 0x0B, 0x25, 0x6E, 0x95, 0xAD, 0x6D, - 0x8F, 0x9F, 0xED, 0xCE, 0x10, 0xBF, 0x1C, 0x90, - 0x67, 0x9C, 0xDE, 0x0E, 0xCF, 0x1B, 0xE3, 0x47 - }, - { - 0x0A, 0x38, 0x6E, 0x7C, 0xD5, 0xDD, 0x9B, 0x77, - 0xA0, 0x35, 0xE0, 0x9F, 0xE6, 0xFE, 0xE2, 0xC8, - 0xCE, 0x61, 0xB5, 0x38, 0x3C, 0x87, 0xEA, 0x43, - 0x20, 0x50, 0x59, 0xC5, 0xE4, 0xCD, 0x4F, 0x44, - 0x08, 0x31, 0x9B, 0xB0, 0xA8, 0x23, 0x60, 0xF6, - 0xA5, 0x8E, 0x6C, 0x9C, 0xE3, 0xF4, 0x87, 0xC4, - 0x46, 0x06, 0x3B, 0xF8, 0x13, 0xBC, 0x6B, 0xA5, - 0x35, 0xE1, 0x7F, 0xC1, 0x82, 0x6C, 0xFC, 0x91 - }, - { - 0x1F, 0x14, 0x59, 0xCB, 0x6B, 0x61, 0xCB, 0xAC, - 0x5F, 0x0E, 0xFE, 0x8F, 0xC4, 0x87, 0x53, 0x8F, - 0x42, 0x54, 0x89, 0x87, 0xFC, 0xD5, 0x62, 0x21, - 0xCF, 0xA7, 0xBE, 0xB2, 0x25, 0x04, 0x76, 0x9E, - 0x79, 0x2C, 0x45, 0xAD, 0xFB, 0x1D, 0x6B, 0x3D, - 0x60, 0xD7, 0xB7, 0x49, 0xC8, 0xA7, 0x5B, 0x0B, - 0xDF, 0x14, 0xE8, 0xEA, 0x72, 0x1B, 0x95, 0xDC, - 0xA5, 0x38, 0xCA, 0x6E, 0x25, 0x71, 0x12, 0x09 - }, - { - 0xE5, 0x8B, 0x38, 0x36, 0xB7, 0xD8, 0xFE, 0xDB, - 0xB5, 0x0C, 0xA5, 0x72, 0x5C, 0x65, 0x71, 0xE7, - 0x4C, 0x07, 0x85, 0xE9, 0x78, 0x21, 0xDA, 0xB8, - 0xB6, 0x29, 0x8C, 0x10, 0xE4, 0xC0, 0x79, 0xD4, - 0xA6, 0xCD, 0xF2, 0x2F, 0x0F, 0xED, 0xB5, 0x50, - 0x32, 0x92, 0x5C, 0x16, 0x74, 0x81, 0x15, 0xF0, - 0x1A, 0x10, 0x5E, 0x77, 0xE0, 0x0C, 0xEE, 0x3D, - 0x07, 0x92, 0x4D, 0xC0, 0xD8, 0xF9, 0x06, 0x59 - }, - { - 0xB9, 0x29, 0xCC, 0x65, 0x05, 0xF0, 0x20, 0x15, - 0x86, 0x72, 0xDE, 0xDA, 0x56, 0xD0, 0xDB, 0x08, - 0x1A, 0x2E, 0xE3, 0x4C, 0x00, 0xC1, 0x10, 0x00, - 0x29, 0xBD, 0xF8, 0xEA, 0x98, 0x03, 0x4F, 0xA4, - 0xBF, 0x3E, 0x86, 0x55, 0xEC, 0x69, 0x7F, 0xE3, - 0x6F, 0x40, 0x55, 0x3C, 0x5B, 0xB4, 0x68, 0x01, - 0x64, 0x4A, 0x62, 0x7D, 0x33, 0x42, 0xF4, 0xFC, - 0x92, 0xB6, 0x1F, 0x03, 0x29, 0x0F, 0xB3, 0x81 - }, - { - 0x72, 0xD3, 0x53, 0x99, 0x4B, 0x49, 0xD3, 0xE0, - 0x31, 0x53, 0x92, 0x9A, 0x1E, 0x4D, 0x4F, 0x18, - 0x8E, 0xE5, 0x8A, 0xB9, 0xE7, 0x2E, 0xE8, 0xE5, - 0x12, 0xF2, 0x9B, 0xC7, 0x73, 0x91, 0x38, 0x19, - 0xCE, 0x05, 0x7D, 0xDD, 0x70, 0x02, 0xC0, 0x43, - 0x3E, 0xE0, 0xA1, 0x61, 0x14, 0xE3, 0xD1, 0x56, - 0xDD, 0x2C, 0x4A, 0x7E, 0x80, 0xEE, 0x53, 0x37, - 0x8B, 0x86, 0x70, 0xF2, 0x3E, 0x33, 0xEF, 0x56 - }, - { - 0xC7, 0x0E, 0xF9, 0xBF, 0xD7, 0x75, 0xD4, 0x08, - 0x17, 0x67, 0x37, 0xA0, 0x73, 0x6D, 0x68, 0x51, - 0x7C, 0xE1, 0xAA, 0xAD, 0x7E, 0x81, 0xA9, 0x3C, - 0x8C, 0x1E, 0xD9, 0x67, 0xEA, 0x21, 0x4F, 0x56, - 0xC8, 0xA3, 0x77, 0xB1, 0x76, 0x3E, 0x67, 0x66, - 0x15, 0xB6, 0x0F, 0x39, 0x88, 0x24, 0x1E, 0xAE, - 0x6E, 0xAB, 0x96, 0x85, 0xA5, 0x12, 0x49, 0x29, - 0xD2, 0x81, 0x88, 0xF2, 0x9E, 0xAB, 0x06, 0xF7 - }, - { - 0xC2, 0x30, 0xF0, 0x80, 0x26, 0x79, 0xCB, 0x33, - 0x82, 0x2E, 0xF8, 0xB3, 0xB2, 0x1B, 0xF7, 0xA9, - 0xA2, 0x89, 0x42, 0x09, 0x29, 0x01, 0xD7, 0xDA, - 0xC3, 0x76, 0x03, 0x00, 0x83, 0x10, 0x26, 0xCF, - 0x35, 0x4C, 0x92, 0x32, 0xDF, 0x3E, 0x08, 0x4D, - 0x99, 0x03, 0x13, 0x0C, 0x60, 0x1F, 0x63, 0xC1, - 0xF4, 0xA4, 0xA4, 0xB8, 0x10, 0x6E, 0x46, 0x8C, - 0xD4, 0x43, 0xBB, 0xE5, 0xA7, 0x34, 0xF4, 0x5F - }, - { - 0x6F, 0x43, 0x09, 0x4C, 0xAF, 0xB5, 0xEB, 0xF1, - 0xF7, 0xA4, 0x93, 0x7E, 0xC5, 0x0F, 0x56, 0xA4, - 0xC9, 0xDA, 0x30, 0x3C, 0xBB, 0x55, 0xAC, 0x1F, - 0x27, 0xF1, 0xF1, 0x97, 0x6C, 0xD9, 0x6B, 0xED, - 0xA9, 0x46, 0x4F, 0x0E, 0x7B, 0x9C, 0x54, 0x62, - 0x0B, 0x8A, 0x9F, 0xBA, 0x98, 0x31, 0x64, 0xB8, - 0xBE, 0x35, 0x78, 0x42, 0x5A, 0x02, 0x4F, 0x5F, - 0xE1, 0x99, 0xC3, 0x63, 0x56, 0xB8, 0x89, 0x72 - }, - { - 0x37, 0x45, 0x27, 0x3F, 0x4C, 0x38, 0x22, 0x5D, - 0xB2, 0x33, 0x73, 0x81, 0x87, 0x1A, 0x0C, 0x6A, - 0xAF, 0xD3, 0xAF, 0x9B, 0x01, 0x8C, 0x88, 0xAA, - 0x02, 0x02, 0x58, 0x50, 0xA5, 0xDC, 0x3A, 0x42, - 0xA1, 0xA3, 0xE0, 0x3E, 0x56, 0xCB, 0xF1, 0xB0, - 0x87, 0x6D, 0x63, 0xA4, 0x41, 0xF1, 0xD2, 0x85, - 0x6A, 0x39, 0xB8, 0x80, 0x1E, 0xB5, 0xAF, 0x32, - 0x52, 0x01, 0xC4, 0x15, 0xD6, 0x5E, 0x97, 0xFE - }, - { - 0xC5, 0x0C, 0x44, 0xCC, 0xA3, 0xEC, 0x3E, 0xDA, - 0xAE, 0x77, 0x9A, 0x7E, 0x17, 0x94, 0x50, 0xEB, - 0xDD, 0xA2, 0xF9, 0x70, 0x67, 0xC6, 0x90, 0xAA, - 0x6C, 0x5A, 0x4A, 0xC7, 0xC3, 0x01, 0x39, 0xBB, - 0x27, 0xC0, 0xDF, 0x4D, 0xB3, 0x22, 0x0E, 0x63, - 0xCB, 0x11, 0x0D, 0x64, 0xF3, 0x7F, 0xFE, 0x07, - 0x8D, 0xB7, 0x26, 0x53, 0xE2, 0xDA, 0xAC, 0xF9, - 0x3A, 0xE3, 0xF0, 0xA2, 0xD1, 0xA7, 0xEB, 0x2E - }, - { - 0x8A, 0xEF, 0x26, 0x3E, 0x38, 0x5C, 0xBC, 0x61, - 0xE1, 0x9B, 0x28, 0x91, 0x42, 0x43, 0x26, 0x2A, - 0xF5, 0xAF, 0xE8, 0x72, 0x6A, 0xF3, 0xCE, 0x39, - 0xA7, 0x9C, 0x27, 0x02, 0x8C, 0xF3, 0xEC, 0xD3, - 0xF8, 0xD2, 0xDF, 0xD9, 0xCF, 0xC9, 0xAD, 0x91, - 0xB5, 0x8F, 0x6F, 0x20, 0x77, 0x8F, 0xD5, 0xF0, - 0x28, 0x94, 0xA3, 0xD9, 0x1C, 0x7D, 0x57, 0xD1, - 0xE4, 0xB8, 0x66, 0xA7, 0xF3, 0x64, 0xB6, 0xBE - }, - { - 0x28, 0x69, 0x61, 0x41, 0xDE, 0x6E, 0x2D, 0x9B, - 0xCB, 0x32, 0x35, 0x57, 0x8A, 0x66, 0x16, 0x6C, - 0x14, 0x48, 0xD3, 0xE9, 0x05, 0xA1, 0xB4, 0x82, - 0xD4, 0x23, 0xBE, 0x4B, 0xC5, 0x36, 0x9B, 0xC8, - 0xC7, 0x4D, 0xAE, 0x0A, 0xCC, 0x9C, 0xC1, 0x23, - 0xE1, 0xD8, 0xDD, 0xCE, 0x9F, 0x97, 0x91, 0x7E, - 0x8C, 0x01, 0x9C, 0x55, 0x2D, 0xA3, 0x2D, 0x39, - 0xD2, 0x21, 0x9B, 0x9A, 0xBF, 0x0F, 0xA8, 0xC8 - }, - { - 0x2F, 0xB9, 0xEB, 0x20, 0x85, 0x83, 0x01, 0x81, - 0x90, 0x3A, 0x9D, 0xAF, 0xE3, 0xDB, 0x42, 0x8E, - 0xE1, 0x5B, 0xE7, 0x66, 0x22, 0x24, 0xEF, 0xD6, - 0x43, 0x37, 0x1F, 0xB2, 0x56, 0x46, 0xAE, 0xE7, - 0x16, 0xE5, 0x31, 0xEC, 0xA6, 0x9B, 0x2B, 0xDC, - 0x82, 0x33, 0xF1, 0xA8, 0x08, 0x1F, 0xA4, 0x3D, - 0xA1, 0x50, 0x03, 0x02, 0x97, 0x5A, 0x77, 0xF4, - 0x2F, 0xA5, 0x92, 0x13, 0x67, 0x10, 0xE9, 0xDC - }, - { - 0x66, 0xF9, 0xA7, 0x14, 0x3F, 0x7A, 0x33, 0x14, - 0xA6, 0x69, 0xBF, 0x2E, 0x24, 0xBB, 0xB3, 0x50, - 0x14, 0x26, 0x1D, 0x63, 0x9F, 0x49, 0x5B, 0x6C, - 0x9C, 0x1F, 0x10, 0x4F, 0xE8, 0xE3, 0x20, 0xAC, - 0xA6, 0x0D, 0x45, 0x50, 0xD6, 0x9D, 0x52, 0xED, - 0xBD, 0x5A, 0x3C, 0xDE, 0xB4, 0x01, 0x4A, 0xE6, - 0x5B, 0x1D, 0x87, 0xAA, 0x77, 0x0B, 0x69, 0xAE, - 0x5C, 0x15, 0xF4, 0x33, 0x0B, 0x0B, 0x0A, 0xD8 - }, - { - 0xF4, 0xC4, 0xDD, 0x1D, 0x59, 0x4C, 0x35, 0x65, - 0xE3, 0xE2, 0x5C, 0xA4, 0x3D, 0xAD, 0x82, 0xF6, - 0x2A, 0xBE, 0xA4, 0x83, 0x5E, 0xD4, 0xCD, 0x81, - 0x1B, 0xCD, 0x97, 0x5E, 0x46, 0x27, 0x98, 0x28, - 0xD4, 0x4D, 0x4C, 0x62, 0xC3, 0x67, 0x9F, 0x1B, - 0x7F, 0x7B, 0x9D, 0xD4, 0x57, 0x1D, 0x7B, 0x49, - 0x55, 0x73, 0x47, 0xB8, 0xC5, 0x46, 0x0C, 0xBD, - 0xC1, 0xBE, 0xF6, 0x90, 0xFB, 0x2A, 0x08, 0xC0 - }, - { - 0x8F, 0x1D, 0xC9, 0x64, 0x9C, 0x3A, 0x84, 0x55, - 0x1F, 0x8F, 0x6E, 0x91, 0xCA, 0xC6, 0x82, 0x42, - 0xA4, 0x3B, 0x1F, 0x8F, 0x32, 0x8E, 0xE9, 0x22, - 0x80, 0x25, 0x73, 0x87, 0xFA, 0x75, 0x59, 0xAA, - 0x6D, 0xB1, 0x2E, 0x4A, 0xEA, 0xDC, 0x2D, 0x26, - 0x09, 0x91, 0x78, 0x74, 0x9C, 0x68, 0x64, 0xB3, - 0x57, 0xF3, 0xF8, 0x3B, 0x2F, 0xB3, 0xEF, 0xA8, - 0xD2, 0xA8, 0xDB, 0x05, 0x6B, 0xED, 0x6B, 0xCC - }, - { - 0x31, 0x39, 0xC1, 0xA7, 0xF9, 0x7A, 0xFD, 0x16, - 0x75, 0xD4, 0x60, 0xEB, 0xBC, 0x07, 0xF2, 0x72, - 0x8A, 0xA1, 0x50, 0xDF, 0x84, 0x96, 0x24, 0x51, - 0x1E, 0xE0, 0x4B, 0x74, 0x3B, 0xA0, 0xA8, 0x33, - 0x09, 0x2F, 0x18, 0xC1, 0x2D, 0xC9, 0x1B, 0x4D, - 0xD2, 0x43, 0xF3, 0x33, 0x40, 0x2F, 0x59, 0xFE, - 0x28, 0xAB, 0xDB, 0xBB, 0xAE, 0x30, 0x1E, 0x7B, - 0x65, 0x9C, 0x7A, 0x26, 0xD5, 0xC0, 0xF9, 0x79 - }, - { - 0x06, 0xF9, 0x4A, 0x29, 0x96, 0x15, 0x8A, 0x81, - 0x9F, 0xE3, 0x4C, 0x40, 0xDE, 0x3C, 0xF0, 0x37, - 0x9F, 0xD9, 0xFB, 0x85, 0xB3, 0xE3, 0x63, 0xBA, - 0x39, 0x26, 0xA0, 0xE7, 0xD9, 0x60, 0xE3, 0xF4, - 0xC2, 0xE0, 0xC7, 0x0C, 0x7C, 0xE0, 0xCC, 0xB2, - 0xA6, 0x4F, 0xC2, 0x98, 0x69, 0xF6, 0xE7, 0xAB, - 0x12, 0xBD, 0x4D, 0x3F, 0x14, 0xFC, 0xE9, 0x43, - 0x27, 0x90, 0x27, 0xE7, 0x85, 0xFB, 0x5C, 0x29 - }, - { - 0xC2, 0x9C, 0x39, 0x9E, 0xF3, 0xEE, 0xE8, 0x96, - 0x1E, 0x87, 0x56, 0x5C, 0x1C, 0xE2, 0x63, 0x92, - 0x5F, 0xC3, 0xD0, 0xCE, 0x26, 0x7D, 0x13, 0xE4, - 0x8D, 0xD9, 0xE7, 0x32, 0xEE, 0x67, 0xB0, 0xF6, - 0x9F, 0xAD, 0x56, 0x40, 0x1B, 0x0F, 0x10, 0xFC, - 0xAA, 0xC1, 0x19, 0x20, 0x10, 0x46, 0xCC, 0xA2, - 0x8C, 0x5B, 0x14, 0xAB, 0xDE, 0xA3, 0x21, 0x2A, - 0xE6, 0x55, 0x62, 0xF7, 0xF1, 0x38, 0xDB, 0x3D - }, - { - 0x4C, 0xEC, 0x4C, 0x9D, 0xF5, 0x2E, 0xEF, 0x05, - 0xC3, 0xF6, 0xFA, 0xAA, 0x97, 0x91, 0xBC, 0x74, - 0x45, 0x93, 0x71, 0x83, 0x22, 0x4E, 0xCC, 0x37, - 0xA1, 0xE5, 0x8D, 0x01, 0x32, 0xD3, 0x56, 0x17, - 0x53, 0x1D, 0x7E, 0x79, 0x5F, 0x52, 0xAF, 0x7B, - 0x1E, 0xB9, 0xD1, 0x47, 0xDE, 0x12, 0x92, 0xD3, - 0x45, 0xFE, 0x34, 0x18, 0x23, 0xF8, 0xE6, 0xBC, - 0x1E, 0x5B, 0xAD, 0xCA, 0x5C, 0x65, 0x61, 0x08 - }, - { - 0x89, 0x8B, 0xFB, 0xAE, 0x93, 0xB3, 0xE1, 0x8D, - 0x00, 0x69, 0x7E, 0xAB, 0x7D, 0x97, 0x04, 0xFA, - 0x36, 0xEC, 0x33, 0x9D, 0x07, 0x61, 0x31, 0xCE, - 0xFD, 0xF3, 0x0E, 0xDB, 0xE8, 0xD9, 0xCC, 0x81, - 0xC3, 0xA8, 0x0B, 0x12, 0x96, 0x59, 0xB1, 0x63, - 0xA3, 0x23, 0xBA, 0xB9, 0x79, 0x3D, 0x4F, 0xEE, - 0xD9, 0x2D, 0x54, 0xDA, 0xE9, 0x66, 0xC7, 0x75, - 0x29, 0x76, 0x4A, 0x09, 0xBE, 0x88, 0xDB, 0x45 - }, - { - 0xEE, 0x9B, 0xD0, 0x46, 0x9D, 0x3A, 0xAF, 0x4F, - 0x14, 0x03, 0x5B, 0xE4, 0x8A, 0x2C, 0x3B, 0x84, - 0xD9, 0xB4, 0xB1, 0xFF, 0xF1, 0xD9, 0x45, 0xE1, - 0xF1, 0xC1, 0xD3, 0x89, 0x80, 0xA9, 0x51, 0xBE, - 0x19, 0x7B, 0x25, 0xFE, 0x22, 0xC7, 0x31, 0xF2, - 0x0A, 0xEA, 0xCC, 0x93, 0x0B, 0xA9, 0xC4, 0xA1, - 0xF4, 0x76, 0x22, 0x27, 0x61, 0x7A, 0xD3, 0x50, - 0xFD, 0xAB, 0xB4, 0xE8, 0x02, 0x73, 0xA0, 0xF4 - }, - { - 0x3D, 0x4D, 0x31, 0x13, 0x30, 0x05, 0x81, 0xCD, - 0x96, 0xAC, 0xBF, 0x09, 0x1C, 0x3D, 0x0F, 0x3C, - 0x31, 0x01, 0x38, 0xCD, 0x69, 0x79, 0xE6, 0x02, - 0x6C, 0xDE, 0x62, 0x3E, 0x2D, 0xD1, 0xB2, 0x4D, - 0x4A, 0x86, 0x38, 0xBE, 0xD1, 0x07, 0x33, 0x44, - 0x78, 0x3A, 0xD0, 0x64, 0x9C, 0xC6, 0x30, 0x5C, - 0xCE, 0xC0, 0x4B, 0xEB, 0x49, 0xF3, 0x1C, 0x63, - 0x30, 0x88, 0xA9, 0x9B, 0x65, 0x13, 0x02, 0x67 - }, - { - 0x95, 0xC0, 0x59, 0x1A, 0xD9, 0x1F, 0x92, 0x1A, - 0xC7, 0xBE, 0x6D, 0x9C, 0xE3, 0x7E, 0x06, 0x63, - 0xED, 0x80, 0x11, 0xC1, 0xCF, 0xD6, 0xD0, 0x16, - 0x2A, 0x55, 0x72, 0xE9, 0x43, 0x68, 0xBA, 0xC0, - 0x20, 0x24, 0x48, 0x5E, 0x6A, 0x39, 0x85, 0x4A, - 0xA4, 0x6F, 0xE3, 0x8E, 0x97, 0xD6, 0xC6, 0xB1, - 0x94, 0x7C, 0xD2, 0x72, 0xD8, 0x6B, 0x06, 0xBB, - 0x5B, 0x2F, 0x78, 0xB9, 0xB6, 0x8D, 0x55, 0x9D - }, - { - 0x22, 0x7B, 0x79, 0xDE, 0xD3, 0x68, 0x15, 0x3B, - 0xF4, 0x6C, 0x0A, 0x3C, 0xA9, 0x78, 0xBF, 0xDB, - 0xEF, 0x31, 0xF3, 0x02, 0x4A, 0x56, 0x65, 0x84, - 0x24, 0x68, 0x49, 0x0B, 0x0F, 0xF7, 0x48, 0xAE, - 0x04, 0xE7, 0x83, 0x2E, 0xD4, 0xC9, 0xF4, 0x9D, - 0xE9, 0xB1, 0x70, 0x67, 0x09, 0xD6, 0x23, 0xE5, - 0xC8, 0xC1, 0x5E, 0x3C, 0xAE, 0xCA, 0xE8, 0xD5, - 0xE4, 0x33, 0x43, 0x0F, 0xF7, 0x2F, 0x20, 0xEB - }, - { - 0x5D, 0x34, 0xF3, 0x95, 0x2F, 0x01, 0x05, 0xEE, - 0xF8, 0x8A, 0xE8, 0xB6, 0x4C, 0x6C, 0xE9, 0x5E, - 0xBF, 0xAD, 0xE0, 0xE0, 0x2C, 0x69, 0xB0, 0x87, - 0x62, 0xA8, 0x71, 0x2D, 0x2E, 0x49, 0x11, 0xAD, - 0x3F, 0x94, 0x1F, 0xC4, 0x03, 0x4D, 0xC9, 0xB2, - 0xE4, 0x79, 0xFD, 0xBC, 0xD2, 0x79, 0xB9, 0x02, - 0xFA, 0xF5, 0xD8, 0x38, 0xBB, 0x2E, 0x0C, 0x64, - 0x95, 0xD3, 0x72, 0xB5, 0xB7, 0x02, 0x98, 0x13 - }, - { - 0x7F, 0x93, 0x9B, 0xF8, 0x35, 0x3A, 0xBC, 0xE4, - 0x9E, 0x77, 0xF1, 0x4F, 0x37, 0x50, 0xAF, 0x20, - 0xB7, 0xB0, 0x39, 0x02, 0xE1, 0xA1, 0xE7, 0xFB, - 0x6A, 0xAF, 0x76, 0xD0, 0x25, 0x9C, 0xD4, 0x01, - 0xA8, 0x31, 0x90, 0xF1, 0x56, 0x40, 0xE7, 0x4F, - 0x3E, 0x6C, 0x5A, 0x90, 0xE8, 0x39, 0xC7, 0x82, - 0x1F, 0x64, 0x74, 0x75, 0x7F, 0x75, 0xC7, 0xBF, - 0x90, 0x02, 0x08, 0x4D, 0xDC, 0x7A, 0x62, 0xDC - }, - { - 0x06, 0x2B, 0x61, 0xA2, 0xF9, 0xA3, 0x3A, 0x71, - 0xD7, 0xD0, 0xA0, 0x61, 0x19, 0x64, 0x4C, 0x70, - 0xB0, 0x71, 0x6A, 0x50, 0x4D, 0xE7, 0xE5, 0xE1, - 0xBE, 0x49, 0xBD, 0x7B, 0x86, 0xE7, 0xED, 0x68, - 0x17, 0x71, 0x4F, 0x9F, 0x0F, 0xC3, 0x13, 0xD0, - 0x61, 0x29, 0x59, 0x7E, 0x9A, 0x22, 0x35, 0xEC, - 0x85, 0x21, 0xDE, 0x36, 0xF7, 0x29, 0x0A, 0x90, - 0xCC, 0xFC, 0x1F, 0xFA, 0x6D, 0x0A, 0xEE, 0x29 - }, - { - 0xF2, 0x9E, 0x01, 0xEE, 0xAE, 0x64, 0x31, 0x1E, - 0xB7, 0xF1, 0xC6, 0x42, 0x2F, 0x94, 0x6B, 0xF7, - 0xBE, 0xA3, 0x63, 0x79, 0x52, 0x3E, 0x7B, 0x2B, - 0xBA, 0xBA, 0x7D, 0x1D, 0x34, 0xA2, 0x2D, 0x5E, - 0xA5, 0xF1, 0xC5, 0xA0, 0x9D, 0x5C, 0xE1, 0xFE, - 0x68, 0x2C, 0xCE, 0xD9, 0xA4, 0x79, 0x8D, 0x1A, - 0x05, 0xB4, 0x6C, 0xD7, 0x2D, 0xFF, 0x5C, 0x1B, - 0x35, 0x54, 0x40, 0xB2, 0xA2, 0xD4, 0x76, 0xBC - }, - { - 0xEC, 0x38, 0xCD, 0x3B, 0xBA, 0xB3, 0xEF, 0x35, - 0xD7, 0xCB, 0x6D, 0x5C, 0x91, 0x42, 0x98, 0x35, - 0x1D, 0x8A, 0x9D, 0xC9, 0x7F, 0xCE, 0xE0, 0x51, - 0xA8, 0xA0, 0x2F, 0x58, 0xE3, 0xED, 0x61, 0x84, - 0xD0, 0xB7, 0x81, 0x0A, 0x56, 0x15, 0x41, 0x1A, - 0xB1, 0xB9, 0x52, 0x09, 0xC3, 0xC8, 0x10, 0x11, - 0x4F, 0xDE, 0xB2, 0x24, 0x52, 0x08, 0x4E, 0x77, - 0xF3, 0xF8, 0x47, 0xC6, 0xDB, 0xAA, 0xFE, 0x16 - }, - { - 0xC2, 0xAE, 0xF5, 0xE0, 0xCA, 0x43, 0xE8, 0x26, - 0x41, 0x56, 0x5B, 0x8C, 0xB9, 0x43, 0xAA, 0x8B, - 0xA5, 0x35, 0x50, 0xCA, 0xEF, 0x79, 0x3B, 0x65, - 0x32, 0xFA, 0xFA, 0xD9, 0x4B, 0x81, 0x60, 0x82, - 0xF0, 0x11, 0x3A, 0x3E, 0xA2, 0xF6, 0x36, 0x08, - 0xAB, 0x40, 0x43, 0x7E, 0xCC, 0x0F, 0x02, 0x29, - 0xCB, 0x8F, 0xA2, 0x24, 0xDC, 0xF1, 0xC4, 0x78, - 0xA6, 0x7D, 0x9B, 0x64, 0x16, 0x2B, 0x92, 0xD1 - }, - { - 0x15, 0xF5, 0x34, 0xEF, 0xFF, 0x71, 0x05, 0xCD, - 0x1C, 0x25, 0x4D, 0x07, 0x4E, 0x27, 0xD5, 0x89, - 0x8B, 0x89, 0x31, 0x3B, 0x7D, 0x36, 0x6D, 0xC2, - 0xD7, 0xD8, 0x71, 0x13, 0xFA, 0x7D, 0x53, 0xAA, - 0xE1, 0x3F, 0x6D, 0xBA, 0x48, 0x7A, 0xD8, 0x10, - 0x3D, 0x5E, 0x85, 0x4C, 0x91, 0xFD, 0xB6, 0xE1, - 0xE7, 0x4B, 0x2E, 0xF6, 0xD1, 0x43, 0x17, 0x69, - 0xC3, 0x07, 0x67, 0xDD, 0xE0, 0x67, 0xA3, 0x5C - }, - { - 0x89, 0xAC, 0xBC, 0xA0, 0xB1, 0x69, 0x89, 0x7A, - 0x0A, 0x27, 0x14, 0xC2, 0xDF, 0x8C, 0x95, 0xB5, - 0xB7, 0x9C, 0xB6, 0x93, 0x90, 0x14, 0x2B, 0x7D, - 0x60, 0x18, 0xBB, 0x3E, 0x30, 0x76, 0xB0, 0x99, - 0xB7, 0x9A, 0x96, 0x41, 0x52, 0xA9, 0xD9, 0x12, - 0xB1, 0xB8, 0x64, 0x12, 0xB7, 0xE3, 0x72, 0xE9, - 0xCE, 0xCA, 0xD7, 0xF2, 0x5D, 0x4C, 0xBA, 0xB8, - 0xA3, 0x17, 0xBE, 0x36, 0x49, 0x2A, 0x67, 0xD7 - }, - { - 0xE3, 0xC0, 0x73, 0x91, 0x90, 0xED, 0x84, 0x9C, - 0x9C, 0x96, 0x2F, 0xD9, 0xDB, 0xB5, 0x5E, 0x20, - 0x7E, 0x62, 0x4F, 0xCA, 0xC1, 0xEB, 0x41, 0x76, - 0x91, 0x51, 0x54, 0x99, 0xEE, 0xA8, 0xD8, 0x26, - 0x7B, 0x7E, 0x8F, 0x12, 0x87, 0xA6, 0x36, 0x33, - 0xAF, 0x50, 0x11, 0xFD, 0xE8, 0xC4, 0xDD, 0xF5, - 0x5B, 0xFD, 0xF7, 0x22, 0xED, 0xF8, 0x88, 0x31, - 0x41, 0x4F, 0x2C, 0xFA, 0xED, 0x59, 0xCB, 0x9A - }, - { - 0x8D, 0x6C, 0xF8, 0x7C, 0x08, 0x38, 0x0D, 0x2D, - 0x15, 0x06, 0xEE, 0xE4, 0x6F, 0xD4, 0x22, 0x2D, - 0x21, 0xD8, 0xC0, 0x4E, 0x58, 0x5F, 0xBF, 0xD0, - 0x82, 0x69, 0xC9, 0x8F, 0x70, 0x28, 0x33, 0xA1, - 0x56, 0x32, 0x6A, 0x07, 0x24, 0x65, 0x64, 0x00, - 0xEE, 0x09, 0x35, 0x1D, 0x57, 0xB4, 0x40, 0x17, - 0x5E, 0x2A, 0x5D, 0xE9, 0x3C, 0xC5, 0xF8, 0x0D, - 0xB6, 0xDA, 0xF8, 0x35, 0x76, 0xCF, 0x75, 0xFA - }, - { - 0xDA, 0x24, 0xBE, 0xDE, 0x38, 0x36, 0x66, 0xD5, - 0x63, 0xEE, 0xED, 0x37, 0xF6, 0x31, 0x9B, 0xAF, - 0x20, 0xD5, 0xC7, 0x5D, 0x16, 0x35, 0xA6, 0xBA, - 0x5E, 0xF4, 0xCF, 0xA1, 0xAC, 0x95, 0x48, 0x7E, - 0x96, 0xF8, 0xC0, 0x8A, 0xF6, 0x00, 0xAA, 0xB8, - 0x7C, 0x98, 0x6E, 0xBA, 0xD4, 0x9F, 0xC7, 0x0A, - 0x58, 0xB4, 0x89, 0x0B, 0x9C, 0x87, 0x6E, 0x09, - 0x10, 0x16, 0xDA, 0xF4, 0x9E, 0x1D, 0x32, 0x2E - }, - { - 0xF9, 0xD1, 0xD1, 0xB1, 0xE8, 0x7E, 0xA7, 0xAE, - 0x75, 0x3A, 0x02, 0x97, 0x50, 0xCC, 0x1C, 0xF3, - 0xD0, 0x15, 0x7D, 0x41, 0x80, 0x5E, 0x24, 0x5C, - 0x56, 0x17, 0xBB, 0x93, 0x4E, 0x73, 0x2F, 0x0A, - 0xE3, 0x18, 0x0B, 0x78, 0xE0, 0x5B, 0xFE, 0x76, - 0xC7, 0xC3, 0x05, 0x1E, 0x3E, 0x3A, 0xC7, 0x8B, - 0x9B, 0x50, 0xC0, 0x51, 0x42, 0x65, 0x7E, 0x1E, - 0x03, 0x21, 0x5D, 0x6E, 0xC7, 0xBF, 0xD0, 0xFC - }, - { - 0x11, 0xB7, 0xBC, 0x16, 0x68, 0x03, 0x20, 0x48, - 0xAA, 0x43, 0x34, 0x3D, 0xE4, 0x76, 0x39, 0x5E, - 0x81, 0x4B, 0xBB, 0xC2, 0x23, 0x67, 0x8D, 0xB9, - 0x51, 0xA1, 0xB0, 0x3A, 0x02, 0x1E, 0xFA, 0xC9, - 0x48, 0xCF, 0xBE, 0x21, 0x5F, 0x97, 0xFE, 0x9A, - 0x72, 0xA2, 0xF6, 0xBC, 0x03, 0x9E, 0x39, 0x56, - 0xBF, 0xA4, 0x17, 0xC1, 0xA9, 0xF1, 0x0D, 0x6D, - 0x7B, 0xA5, 0xD3, 0xD3, 0x2F, 0xF3, 0x23, 0xE5 - }, - { - 0xB8, 0xD9, 0x00, 0x0E, 0x4F, 0xC2, 0xB0, 0x66, - 0xED, 0xB9, 0x1A, 0xFE, 0xE8, 0xE7, 0xEB, 0x0F, - 0x24, 0xE3, 0xA2, 0x01, 0xDB, 0x8B, 0x67, 0x93, - 0xC0, 0x60, 0x85, 0x81, 0xE6, 0x28, 0xED, 0x0B, - 0xCC, 0x4E, 0x5A, 0xA6, 0x78, 0x79, 0x92, 0xA4, - 0xBC, 0xC4, 0x4E, 0x28, 0x80, 0x93, 0xE6, 0x3E, - 0xE8, 0x3A, 0xBD, 0x0B, 0xC3, 0xEC, 0x6D, 0x09, - 0x34, 0xA6, 0x74, 0xA4, 0xDA, 0x13, 0x83, 0x8A - }, - { - 0xCE, 0x32, 0x5E, 0x29, 0x4F, 0x9B, 0x67, 0x19, - 0xD6, 0xB6, 0x12, 0x78, 0x27, 0x6A, 0xE0, 0x6A, - 0x25, 0x64, 0xC0, 0x3B, 0xB0, 0xB7, 0x83, 0xFA, - 0xFE, 0x78, 0x5B, 0xDF, 0x89, 0xC7, 0xD5, 0xAC, - 0xD8, 0x3E, 0x78, 0x75, 0x6D, 0x30, 0x1B, 0x44, - 0x56, 0x99, 0x02, 0x4E, 0xAE, 0xB7, 0x7B, 0x54, - 0xD4, 0x77, 0x33, 0x6E, 0xC2, 0xA4, 0xF3, 0x32, - 0xF2, 0xB3, 0xF8, 0x87, 0x65, 0xDD, 0xB0, 0xC3 - }, - { - 0x29, 0xAC, 0xC3, 0x0E, 0x96, 0x03, 0xAE, 0x2F, - 0xCC, 0xF9, 0x0B, 0xF9, 0x7E, 0x6C, 0xC4, 0x63, - 0xEB, 0xE2, 0x8C, 0x1B, 0x2F, 0x9B, 0x4B, 0x76, - 0x5E, 0x70, 0x53, 0x7C, 0x25, 0xC7, 0x02, 0xA2, - 0x9D, 0xCB, 0xFB, 0xF1, 0x4C, 0x99, 0xC5, 0x43, - 0x45, 0xBA, 0x2B, 0x51, 0xF1, 0x7B, 0x77, 0xB5, - 0xF1, 0x5D, 0xB9, 0x2B, 0xBA, 0xD8, 0xFA, 0x95, - 0xC4, 0x71, 0xF5, 0xD0, 0x70, 0xA1, 0x37, 0xCC - }, - { - 0x33, 0x79, 0xCB, 0xAA, 0xE5, 0x62, 0xA8, 0x7B, - 0x4C, 0x04, 0x25, 0x55, 0x0F, 0xFD, 0xD6, 0xBF, - 0xE1, 0x20, 0x3F, 0x0D, 0x66, 0x6C, 0xC7, 0xEA, - 0x09, 0x5B, 0xE4, 0x07, 0xA5, 0xDF, 0xE6, 0x1E, - 0xE9, 0x14, 0x41, 0xCD, 0x51, 0x54, 0xB3, 0xE5, - 0x3B, 0x4F, 0x5F, 0xB3, 0x1A, 0xD4, 0xC7, 0xA9, - 0xAD, 0x5C, 0x7A, 0xF4, 0xAE, 0x67, 0x9A, 0xA5, - 0x1A, 0x54, 0x00, 0x3A, 0x54, 0xCA, 0x6B, 0x2D - }, - { - 0x30, 0x95, 0xA3, 0x49, 0xD2, 0x45, 0x70, 0x8C, - 0x7C, 0xF5, 0x50, 0x11, 0x87, 0x03, 0xD7, 0x30, - 0x2C, 0x27, 0xB6, 0x0A, 0xF5, 0xD4, 0xE6, 0x7F, - 0xC9, 0x78, 0xF8, 0xA4, 0xE6, 0x09, 0x53, 0xC7, - 0xA0, 0x4F, 0x92, 0xFC, 0xF4, 0x1A, 0xEE, 0x64, - 0x32, 0x1C, 0xCB, 0x70, 0x7A, 0x89, 0x58, 0x51, - 0x55, 0x2B, 0x1E, 0x37, 0xB0, 0x0B, 0xC5, 0xE6, - 0xB7, 0x2F, 0xA5, 0xBC, 0xEF, 0x9E, 0x3F, 0xFF - }, - { - 0x07, 0x26, 0x2D, 0x73, 0x8B, 0x09, 0x32, 0x1F, - 0x4D, 0xBC, 0xCE, 0xC4, 0xBB, 0x26, 0xF4, 0x8C, - 0xB0, 0xF0, 0xED, 0x24, 0x6C, 0xE0, 0xB3, 0x1B, - 0x9A, 0x6E, 0x7B, 0xC6, 0x83, 0x04, 0x9F, 0x1F, - 0x3E, 0x55, 0x45, 0xF2, 0x8C, 0xE9, 0x32, 0xDD, - 0x98, 0x5C, 0x5A, 0xB0, 0xF4, 0x3B, 0xD6, 0xDE, - 0x07, 0x70, 0x56, 0x0A, 0xF3, 0x29, 0x06, 0x5E, - 0xD2, 0xE4, 0x9D, 0x34, 0x62, 0x4C, 0x2C, 0xBB - }, - { - 0xB6, 0x40, 0x5E, 0xCA, 0x8E, 0xE3, 0x31, 0x6C, - 0x87, 0x06, 0x1C, 0xC6, 0xEC, 0x18, 0xDB, 0xA5, - 0x3E, 0x6C, 0x25, 0x0C, 0x63, 0xBA, 0x1F, 0x3B, - 0xAE, 0x9E, 0x55, 0xDD, 0x34, 0x98, 0x03, 0x6A, - 0xF0, 0x8C, 0xD2, 0x72, 0xAA, 0x24, 0xD7, 0x13, - 0xC6, 0x02, 0x0D, 0x77, 0xAB, 0x2F, 0x39, 0x19, - 0xAF, 0x1A, 0x32, 0xF3, 0x07, 0x42, 0x06, 0x18, - 0xAB, 0x97, 0xE7, 0x39, 0x53, 0x99, 0x4F, 0xB4 - }, - { - 0x7E, 0xE6, 0x82, 0xF6, 0x31, 0x48, 0xEE, 0x45, - 0xF6, 0xE5, 0x31, 0x5D, 0xA8, 0x1E, 0x5C, 0x6E, - 0x55, 0x7C, 0x2C, 0x34, 0x64, 0x1F, 0xC5, 0x09, - 0xC7, 0xA5, 0x70, 0x10, 0x88, 0xC3, 0x8A, 0x74, - 0x75, 0x61, 0x68, 0xE2, 0xCD, 0x8D, 0x35, 0x1E, - 0x88, 0xFD, 0x1A, 0x45, 0x1F, 0x36, 0x0A, 0x01, - 0xF5, 0xB2, 0x58, 0x0F, 0x9B, 0x5A, 0x2E, 0x8C, - 0xFC, 0x13, 0x8F, 0x3D, 0xD5, 0x9A, 0x3F, 0xFC - }, - { - 0x1D, 0x26, 0x3C, 0x17, 0x9D, 0x6B, 0x26, 0x8F, - 0x6F, 0xA0, 0x16, 0xF3, 0xA4, 0xF2, 0x9E, 0x94, - 0x38, 0x91, 0x12, 0x5E, 0xD8, 0x59, 0x3C, 0x81, - 0x25, 0x60, 0x59, 0xF5, 0xA7, 0xB4, 0x4A, 0xF2, - 0xDC, 0xB2, 0x03, 0x0D, 0x17, 0x5C, 0x00, 0xE6, - 0x2E, 0xCA, 0xF7, 0xEE, 0x96, 0x68, 0x2A, 0xA0, - 0x7A, 0xB2, 0x0A, 0x61, 0x10, 0x24, 0xA2, 0x85, - 0x32, 0xB1, 0xC2, 0x5B, 0x86, 0x65, 0x79, 0x02 - }, - { - 0x10, 0x6D, 0x13, 0x2C, 0xBD, 0xB4, 0xCD, 0x25, - 0x97, 0x81, 0x28, 0x46, 0xE2, 0xBC, 0x1B, 0xF7, - 0x32, 0xFE, 0xC5, 0xF0, 0xA5, 0xF6, 0x5D, 0xBB, - 0x39, 0xEC, 0x4E, 0x6D, 0xC6, 0x4A, 0xB2, 0xCE, - 0x6D, 0x24, 0x63, 0x0D, 0x0F, 0x15, 0xA8, 0x05, - 0xC3, 0x54, 0x00, 0x25, 0xD8, 0x4A, 0xFA, 0x98, - 0xE3, 0x67, 0x03, 0xC3, 0xDB, 0xEE, 0x71, 0x3E, - 0x72, 0xDD, 0xE8, 0x46, 0x5B, 0xC1, 0xBE, 0x7E - }, - { - 0x0E, 0x79, 0x96, 0x82, 0x26, 0x65, 0x06, 0x67, - 0xA8, 0xD8, 0x62, 0xEA, 0x8D, 0xA4, 0x89, 0x1A, - 0xF5, 0x6A, 0x4E, 0x3A, 0x8B, 0x6D, 0x17, 0x50, - 0xE3, 0x94, 0xF0, 0xDE, 0xA7, 0x6D, 0x64, 0x0D, - 0x85, 0x07, 0x7B, 0xCE, 0xC2, 0xCC, 0x86, 0x88, - 0x6E, 0x50, 0x67, 0x51, 0xB4, 0xF6, 0xA5, 0x83, - 0x8F, 0x7F, 0x0B, 0x5F, 0xEF, 0x76, 0x5D, 0x9D, - 0xC9, 0x0D, 0xCD, 0xCB, 0xAF, 0x07, 0x9F, 0x08 - }, - { - 0x52, 0x11, 0x56, 0xA8, 0x2A, 0xB0, 0xC4, 0xE5, - 0x66, 0xE5, 0x84, 0x4D, 0x5E, 0x31, 0xAD, 0x9A, - 0xAF, 0x14, 0x4B, 0xBD, 0x5A, 0x46, 0x4F, 0xDC, - 0xA3, 0x4D, 0xBD, 0x57, 0x17, 0xE8, 0xFF, 0x71, - 0x1D, 0x3F, 0xFE, 0xBB, 0xFA, 0x08, 0x5D, 0x67, - 0xFE, 0x99, 0x6A, 0x34, 0xF6, 0xD3, 0xE4, 0xE6, - 0x0B, 0x13, 0x96, 0xBF, 0x4B, 0x16, 0x10, 0xC2, - 0x63, 0xBD, 0xBB, 0x83, 0x4D, 0x56, 0x08, 0x16 - }, - { - 0x1A, 0xBA, 0x88, 0xBE, 0xFC, 0x55, 0xBC, 0x25, - 0xEF, 0xBC, 0xE0, 0x2D, 0xB8, 0xB9, 0x93, 0x3E, - 0x46, 0xF5, 0x76, 0x61, 0xBA, 0xEA, 0xBE, 0xB2, - 0x1C, 0xC2, 0x57, 0x4D, 0x2A, 0x51, 0x8A, 0x3C, - 0xBA, 0x5D, 0xC5, 0xA3, 0x8E, 0x49, 0x71, 0x34, - 0x40, 0xB2, 0x5F, 0x9C, 0x74, 0x4E, 0x75, 0xF6, - 0xB8, 0x5C, 0x9D, 0x8F, 0x46, 0x81, 0xF6, 0x76, - 0x16, 0x0F, 0x61, 0x05, 0x35, 0x7B, 0x84, 0x06 - }, - { - 0x5A, 0x99, 0x49, 0xFC, 0xB2, 0xC4, 0x73, 0xCD, - 0xA9, 0x68, 0xAC, 0x1B, 0x5D, 0x08, 0x56, 0x6D, - 0xC2, 0xD8, 0x16, 0xD9, 0x60, 0xF5, 0x7E, 0x63, - 0xB8, 0x98, 0xFA, 0x70, 0x1C, 0xF8, 0xEB, 0xD3, - 0xF5, 0x9B, 0x12, 0x4D, 0x95, 0xBF, 0xBB, 0xED, - 0xC5, 0xF1, 0xCF, 0x0E, 0x17, 0xD5, 0xEA, 0xED, - 0x0C, 0x02, 0xC5, 0x0B, 0x69, 0xD8, 0xA4, 0x02, - 0xCA, 0xBC, 0xCA, 0x44, 0x33, 0xB5, 0x1F, 0xD4 - }, - { - 0xB0, 0xCE, 0xAD, 0x09, 0x80, 0x7C, 0x67, 0x2A, - 0xF2, 0xEB, 0x2B, 0x0F, 0x06, 0xDD, 0xE4, 0x6C, - 0xF5, 0x37, 0x0E, 0x15, 0xA4, 0x09, 0x6B, 0x1A, - 0x7D, 0x7C, 0xBB, 0x36, 0xEC, 0x31, 0xC2, 0x05, - 0xFB, 0xEF, 0xCA, 0x00, 0xB7, 0xA4, 0x16, 0x2F, - 0xA8, 0x9F, 0xB4, 0xFB, 0x3E, 0xB7, 0x8D, 0x79, - 0x77, 0x0C, 0x23, 0xF4, 0x4E, 0x72, 0x06, 0x66, - 0x4C, 0xE3, 0xCD, 0x93, 0x1C, 0x29, 0x1E, 0x5D - }, - { - 0xBB, 0x66, 0x64, 0x93, 0x1E, 0xC9, 0x70, 0x44, - 0xE4, 0x5B, 0x2A, 0xE4, 0x20, 0xAE, 0x1C, 0x55, - 0x1A, 0x88, 0x74, 0xBC, 0x93, 0x7D, 0x08, 0xE9, - 0x69, 0x39, 0x9C, 0x39, 0x64, 0xEB, 0xDB, 0xA8, - 0x34, 0x6C, 0xDD, 0x5D, 0x09, 0xCA, 0xAF, 0xE4, - 0xC2, 0x8B, 0xA7, 0xEC, 0x78, 0x81, 0x91, 0xCE, - 0xCA, 0x65, 0xDD, 0xD6, 0xF9, 0x5F, 0x18, 0x58, - 0x3E, 0x04, 0x0D, 0x0F, 0x30, 0xD0, 0x36, 0x4D - }, - { - 0x65, 0xBC, 0x77, 0x0A, 0x5F, 0xAA, 0x37, 0x92, - 0x36, 0x98, 0x03, 0x68, 0x3E, 0x84, 0x4B, 0x0B, - 0xE7, 0xEE, 0x96, 0xF2, 0x9F, 0x6D, 0x6A, 0x35, - 0x56, 0x80, 0x06, 0xBD, 0x55, 0x90, 0xF9, 0xA4, - 0xEF, 0x63, 0x9B, 0x7A, 0x80, 0x61, 0xC7, 0xB0, - 0x42, 0x4B, 0x66, 0xB6, 0x0A, 0xC3, 0x4A, 0xF3, - 0x11, 0x99, 0x05, 0xF3, 0x3A, 0x9D, 0x8C, 0x3A, - 0xE1, 0x83, 0x82, 0xCA, 0x9B, 0x68, 0x99, 0x00 - }, - { - 0xEA, 0x9B, 0x4D, 0xCA, 0x33, 0x33, 0x36, 0xAA, - 0xF8, 0x39, 0xA4, 0x5C, 0x6E, 0xAA, 0x48, 0xB8, - 0xCB, 0x4C, 0x7D, 0xDA, 0xBF, 0xFE, 0xA4, 0xF6, - 0x43, 0xD6, 0x35, 0x7E, 0xA6, 0x62, 0x8A, 0x48, - 0x0A, 0x5B, 0x45, 0xF2, 0xB0, 0x52, 0xC1, 0xB0, - 0x7D, 0x1F, 0xED, 0xCA, 0x91, 0x8B, 0x6F, 0x11, - 0x39, 0xD8, 0x0F, 0x74, 0xC2, 0x45, 0x10, 0xDC, - 0xBA, 0xA4, 0xBE, 0x70, 0xEA, 0xCC, 0x1B, 0x06 - }, - { - 0xE6, 0x34, 0x2F, 0xB4, 0xA7, 0x80, 0xAD, 0x97, - 0x5D, 0x0E, 0x24, 0xBC, 0xE1, 0x49, 0x98, 0x9B, - 0x91, 0xD3, 0x60, 0x55, 0x7E, 0x87, 0x99, 0x4F, - 0x6B, 0x45, 0x7B, 0x89, 0x55, 0x75, 0xCC, 0x02, - 0xD0, 0xC1, 0x5B, 0xAD, 0x3C, 0xE7, 0x57, 0x7F, - 0x4C, 0x63, 0x92, 0x7F, 0xF1, 0x3F, 0x3E, 0x38, - 0x1F, 0xF7, 0xE7, 0x2B, 0xDB, 0xE7, 0x45, 0x32, - 0x48, 0x44, 0xA9, 0xD2, 0x7E, 0x3F, 0x1C, 0x01 - }, - { - 0x3E, 0x20, 0x9C, 0x9B, 0x33, 0xE8, 0xE4, 0x61, - 0x17, 0x8A, 0xB4, 0x6B, 0x1C, 0x64, 0xB4, 0x9A, - 0x07, 0xFB, 0x74, 0x5F, 0x1C, 0x8B, 0xC9, 0x5F, - 0xBF, 0xB9, 0x4C, 0x6B, 0x87, 0xC6, 0x95, 0x16, - 0x65, 0x1B, 0x26, 0x4E, 0xF9, 0x80, 0x93, 0x7F, - 0xAD, 0x41, 0x23, 0x8B, 0x91, 0xDD, 0xC0, 0x11, - 0xA5, 0xDD, 0x77, 0x7C, 0x7E, 0xFD, 0x44, 0x94, - 0xB4, 0xB6, 0xEC, 0xD3, 0xA9, 0xC2, 0x2A, 0xC0 - }, - { - 0xFD, 0x6A, 0x3D, 0x5B, 0x18, 0x75, 0xD8, 0x04, - 0x86, 0xD6, 0xE6, 0x96, 0x94, 0xA5, 0x6D, 0xBB, - 0x04, 0xA9, 0x9A, 0x4D, 0x05, 0x1F, 0x15, 0xDB, - 0x26, 0x89, 0x77, 0x6B, 0xA1, 0xC4, 0x88, 0x2E, - 0x6D, 0x46, 0x2A, 0x60, 0x3B, 0x70, 0x15, 0xDC, - 0x9F, 0x4B, 0x74, 0x50, 0xF0, 0x53, 0x94, 0x30, - 0x3B, 0x86, 0x52, 0xCF, 0xB4, 0x04, 0xA2, 0x66, - 0x96, 0x2C, 0x41, 0xBA, 0xE6, 0xE1, 0x8A, 0x94 - }, - { - 0x95, 0x1E, 0x27, 0x51, 0x7E, 0x6B, 0xAD, 0x9E, - 0x41, 0x95, 0xFC, 0x86, 0x71, 0xDE, 0xE3, 0xE7, - 0xE9, 0xBE, 0x69, 0xCE, 0xE1, 0x42, 0x2C, 0xB9, - 0xFE, 0xCF, 0xCE, 0x0D, 0xBA, 0x87, 0x5F, 0x7B, - 0x31, 0x0B, 0x93, 0xEE, 0x3A, 0x3D, 0x55, 0x8F, - 0x94, 0x1F, 0x63, 0x5F, 0x66, 0x8F, 0xF8, 0x32, - 0xD2, 0xC1, 0xD0, 0x33, 0xC5, 0xE2, 0xF0, 0x99, - 0x7E, 0x4C, 0x66, 0xF1, 0x47, 0x34, 0x4E, 0x02 - }, - { - 0x8E, 0xBA, 0x2F, 0x87, 0x4F, 0x1A, 0xE8, 0x40, - 0x41, 0x90, 0x3C, 0x7C, 0x42, 0x53, 0xC8, 0x22, - 0x92, 0x53, 0x0F, 0xC8, 0x50, 0x95, 0x50, 0xBF, - 0xDC, 0x34, 0xC9, 0x5C, 0x7E, 0x28, 0x89, 0xD5, - 0x65, 0x0B, 0x0A, 0xD8, 0xCB, 0x98, 0x8E, 0x5C, - 0x48, 0x94, 0xCB, 0x87, 0xFB, 0xFB, 0xB1, 0x96, - 0x12, 0xEA, 0x93, 0xCC, 0xC4, 0xC5, 0xCA, 0xD1, - 0x71, 0x58, 0xB9, 0x76, 0x34, 0x64, 0xB4, 0x92 - }, - { - 0x16, 0xF7, 0x12, 0xEA, 0xA1, 0xB7, 0xC6, 0x35, - 0x47, 0x19, 0xA8, 0xE7, 0xDB, 0xDF, 0xAF, 0x55, - 0xE4, 0x06, 0x3A, 0x4D, 0x27, 0x7D, 0x94, 0x75, - 0x50, 0x01, 0x9B, 0x38, 0xDF, 0xB5, 0x64, 0x83, - 0x09, 0x11, 0x05, 0x7D, 0x50, 0x50, 0x61, 0x36, - 0xE2, 0x39, 0x4C, 0x3B, 0x28, 0x94, 0x5C, 0xC9, - 0x64, 0x96, 0x7D, 0x54, 0xE3, 0x00, 0x0C, 0x21, - 0x81, 0x62, 0x6C, 0xFB, 0x9B, 0x73, 0xEF, 0xD2 - }, - { - 0xC3, 0x96, 0x39, 0xE7, 0xD5, 0xC7, 0xFB, 0x8C, - 0xDD, 0x0F, 0xD3, 0xE6, 0xA5, 0x20, 0x96, 0x03, - 0x94, 0x37, 0x12, 0x2F, 0x21, 0xC7, 0x8F, 0x16, - 0x79, 0xCE, 0xA9, 0xD7, 0x8A, 0x73, 0x4C, 0x56, - 0xEC, 0xBE, 0xB2, 0x86, 0x54, 0xB4, 0xF1, 0x8E, - 0x34, 0x2C, 0x33, 0x1F, 0x6F, 0x72, 0x29, 0xEC, - 0x4B, 0x4B, 0xC2, 0x81, 0xB2, 0xD8, 0x0A, 0x6E, - 0xB5, 0x00, 0x43, 0xF3, 0x17, 0x96, 0xC8, 0x8C - }, - { - 0x72, 0xD0, 0x81, 0xAF, 0x99, 0xF8, 0xA1, 0x73, - 0xDC, 0xC9, 0xA0, 0xAC, 0x4E, 0xB3, 0x55, 0x74, - 0x05, 0x63, 0x9A, 0x29, 0x08, 0x4B, 0x54, 0xA4, - 0x01, 0x72, 0x91, 0x2A, 0x2F, 0x8A, 0x39, 0x51, - 0x29, 0xD5, 0x53, 0x6F, 0x09, 0x18, 0xE9, 0x02, - 0xF9, 0xE8, 0xFA, 0x60, 0x00, 0x99, 0x5F, 0x41, - 0x68, 0xDD, 0xC5, 0xF8, 0x93, 0x01, 0x1B, 0xE6, - 0xA0, 0xDB, 0xC9, 0xB8, 0xA1, 0xA3, 0xF5, 0xBB - }, - { - 0xC1, 0x1A, 0xA8, 0x1E, 0x5E, 0xFD, 0x24, 0xD5, - 0xFC, 0x27, 0xEE, 0x58, 0x6C, 0xFD, 0x88, 0x47, - 0xFB, 0xB0, 0xE2, 0x76, 0x01, 0xCC, 0xEC, 0xE5, - 0xEC, 0xCA, 0x01, 0x98, 0xE3, 0xC7, 0x76, 0x53, - 0x93, 0xBB, 0x74, 0x45, 0x7C, 0x7E, 0x7A, 0x27, - 0xEB, 0x91, 0x70, 0x35, 0x0E, 0x1F, 0xB5, 0x38, - 0x57, 0x17, 0x75, 0x06, 0xBE, 0x3E, 0x76, 0x2C, - 0xC0, 0xF1, 0x4D, 0x8C, 0x3A, 0xFE, 0x90, 0x77 - }, - { - 0xC2, 0x8F, 0x21, 0x50, 0xB4, 0x52, 0xE6, 0xC0, - 0xC4, 0x24, 0xBC, 0xDE, 0x6F, 0x8D, 0x72, 0x00, - 0x7F, 0x93, 0x10, 0xFE, 0xD7, 0xF2, 0xF8, 0x7D, - 0xE0, 0xDB, 0xB6, 0x4F, 0x44, 0x79, 0xD6, 0xC1, - 0x44, 0x1B, 0xA6, 0x6F, 0x44, 0xB2, 0xAC, 0xCE, - 0xE6, 0x16, 0x09, 0x17, 0x7E, 0xD3, 0x40, 0x12, - 0x8B, 0x40, 0x7E, 0xCE, 0xC7, 0xC6, 0x4B, 0xBE, - 0x50, 0xD6, 0x3D, 0x22, 0xD8, 0x62, 0x77, 0x27 - }, - { - 0xF6, 0x3D, 0x88, 0x12, 0x28, 0x77, 0xEC, 0x30, - 0xB8, 0xC8, 0xB0, 0x0D, 0x22, 0xE8, 0x90, 0x00, - 0xA9, 0x66, 0x42, 0x61, 0x12, 0xBD, 0x44, 0x16, - 0x6E, 0x2F, 0x52, 0x5B, 0x76, 0x9C, 0xCB, 0xE9, - 0xB2, 0x86, 0xD4, 0x37, 0xA0, 0x12, 0x91, 0x30, - 0xDD, 0xE1, 0xA8, 0x6C, 0x43, 0xE0, 0x4B, 0xED, - 0xB5, 0x94, 0xE6, 0x71, 0xD9, 0x82, 0x83, 0xAF, - 0xE6, 0x4C, 0xE3, 0x31, 0xDE, 0x98, 0x28, 0xFD - }, - { - 0x34, 0x8B, 0x05, 0x32, 0x88, 0x0B, 0x88, 0xA6, - 0x61, 0x4A, 0x8D, 0x74, 0x08, 0xC3, 0xF9, 0x13, - 0x35, 0x7F, 0xBB, 0x60, 0xE9, 0x95, 0xC6, 0x02, - 0x05, 0xBE, 0x91, 0x39, 0xE7, 0x49, 0x98, 0xAE, - 0xDE, 0x7F, 0x45, 0x81, 0xE4, 0x2F, 0x6B, 0x52, - 0x69, 0x8F, 0x7F, 0xA1, 0x21, 0x97, 0x08, 0xC1, - 0x44, 0x98, 0x06, 0x7F, 0xD1, 0xE0, 0x95, 0x02, - 0xDE, 0x83, 0xA7, 0x7D, 0xD2, 0x81, 0x15, 0x0C - }, - { - 0x51, 0x33, 0xDC, 0x8B, 0xEF, 0x72, 0x53, 0x59, - 0xDF, 0xF5, 0x97, 0x92, 0xD8, 0x5E, 0xAF, 0x75, - 0xB7, 0xE1, 0xDC, 0xD1, 0x97, 0x8B, 0x01, 0xC3, - 0x5B, 0x1B, 0x85, 0xFC, 0xEB, 0xC6, 0x33, 0x88, - 0xAD, 0x99, 0xA1, 0x7B, 0x63, 0x46, 0xA2, 0x17, - 0xDC, 0x1A, 0x96, 0x22, 0xEB, 0xD1, 0x22, 0xEC, - 0xF6, 0x91, 0x3C, 0x4D, 0x31, 0xA6, 0xB5, 0x2A, - 0x69, 0x5B, 0x86, 0xAF, 0x00, 0xD7, 0x41, 0xA0 - }, - { - 0x27, 0x53, 0xC4, 0xC0, 0xE9, 0x8E, 0xCA, 0xD8, - 0x06, 0xE8, 0x87, 0x80, 0xEC, 0x27, 0xFC, 0xCD, - 0x0F, 0x5C, 0x1A, 0xB5, 0x47, 0xF9, 0xE4, 0xBF, - 0x16, 0x59, 0xD1, 0x92, 0xC2, 0x3A, 0xA2, 0xCC, - 0x97, 0x1B, 0x58, 0xB6, 0x80, 0x25, 0x80, 0xBA, - 0xEF, 0x8A, 0xDC, 0x3B, 0x77, 0x6E, 0xF7, 0x08, - 0x6B, 0x25, 0x45, 0xC2, 0x98, 0x7F, 0x34, 0x8E, - 0xE3, 0x71, 0x9C, 0xDE, 0xF2, 0x58, 0xC4, 0x03 - }, - { - 0xB1, 0x66, 0x35, 0x73, 0xCE, 0x4B, 0x9D, 0x8C, - 0xAE, 0xFC, 0x86, 0x50, 0x12, 0xF3, 0xE3, 0x97, - 0x14, 0xB9, 0x89, 0x8A, 0x5D, 0xA6, 0xCE, 0x17, - 0xC2, 0x5A, 0x6A, 0x47, 0x93, 0x1A, 0x9D, 0xDB, - 0x9B, 0xBE, 0x98, 0xAD, 0xAA, 0x55, 0x3B, 0xEE, - 0xD4, 0x36, 0xE8, 0x95, 0x78, 0x45, 0x54, 0x16, - 0xC2, 0xA5, 0x2A, 0x52, 0x5C, 0xF2, 0x86, 0x2B, - 0x8D, 0x1D, 0x49, 0xA2, 0x53, 0x1B, 0x73, 0x91 - }, - { - 0x64, 0xF5, 0x8B, 0xD6, 0xBF, 0xC8, 0x56, 0xF5, - 0xE8, 0x73, 0xB2, 0xA2, 0x95, 0x6E, 0xA0, 0xED, - 0xA0, 0xD6, 0xDB, 0x0D, 0xA3, 0x9C, 0x8C, 0x7F, - 0xC6, 0x7C, 0x9F, 0x9F, 0xEE, 0xFC, 0xFF, 0x30, - 0x72, 0xCD, 0xF9, 0xE6, 0xEA, 0x37, 0xF6, 0x9A, - 0x44, 0xF0, 0xC6, 0x1A, 0xA0, 0xDA, 0x36, 0x93, - 0xC2, 0xDB, 0x5B, 0x54, 0x96, 0x0C, 0x02, 0x81, - 0xA0, 0x88, 0x15, 0x1D, 0xB4, 0x2B, 0x11, 0xE8 - }, - { - 0x07, 0x64, 0xC7, 0xBE, 0x28, 0x12, 0x5D, 0x90, - 0x65, 0xC4, 0xB9, 0x8A, 0x69, 0xD6, 0x0A, 0xED, - 0xE7, 0x03, 0x54, 0x7C, 0x66, 0xA1, 0x2E, 0x17, - 0xE1, 0xC6, 0x18, 0x99, 0x41, 0x32, 0xF5, 0xEF, - 0x82, 0x48, 0x2C, 0x1E, 0x3F, 0xE3, 0x14, 0x6C, - 0xC6, 0x53, 0x76, 0xCC, 0x10, 0x9F, 0x01, 0x38, - 0xED, 0x9A, 0x80, 0xE4, 0x9F, 0x1F, 0x3C, 0x7D, - 0x61, 0x0D, 0x2F, 0x24, 0x32, 0xF2, 0x06, 0x05 - }, - { - 0xF7, 0x48, 0x78, 0x43, 0x98, 0xA2, 0xFF, 0x03, - 0xEB, 0xEB, 0x07, 0xE1, 0x55, 0xE6, 0x61, 0x16, - 0xA8, 0x39, 0x74, 0x1A, 0x33, 0x6E, 0x32, 0xDA, - 0x71, 0xEC, 0x69, 0x60, 0x01, 0xF0, 0xAD, 0x1B, - 0x25, 0xCD, 0x48, 0xC6, 0x9C, 0xFC, 0xA7, 0x26, - 0x5E, 0xCA, 0x1D, 0xD7, 0x19, 0x04, 0xA0, 0xCE, - 0x74, 0x8A, 0xC4, 0x12, 0x4F, 0x35, 0x71, 0x07, - 0x6D, 0xFA, 0x71, 0x16, 0xA9, 0xCF, 0x00, 0xE9 - }, - { - 0x3F, 0x0D, 0xBC, 0x01, 0x86, 0xBC, 0xEB, 0x6B, - 0x78, 0x5B, 0xA7, 0x8D, 0x2A, 0x2A, 0x01, 0x3C, - 0x91, 0x0B, 0xE1, 0x57, 0xBD, 0xAF, 0xFA, 0xE8, - 0x1B, 0xB6, 0x66, 0x3B, 0x1A, 0x73, 0x72, 0x2F, - 0x7F, 0x12, 0x28, 0x79, 0x5F, 0x3E, 0xCA, 0xDA, - 0x87, 0xCF, 0x6E, 0xF0, 0x07, 0x84, 0x74, 0xAF, - 0x73, 0xF3, 0x1E, 0xCA, 0x0C, 0xC2, 0x00, 0xED, - 0x97, 0x5B, 0x68, 0x93, 0xF7, 0x61, 0xCB, 0x6D - }, - { - 0xD4, 0x76, 0x2C, 0xD4, 0x59, 0x98, 0x76, 0xCA, - 0x75, 0xB2, 0xB8, 0xFE, 0x24, 0x99, 0x44, 0xDB, - 0xD2, 0x7A, 0xCE, 0x74, 0x1F, 0xDA, 0xB9, 0x36, - 0x16, 0xCB, 0xC6, 0xE4, 0x25, 0x46, 0x0F, 0xEB, - 0x51, 0xD4, 0xE7, 0xAD, 0xCC, 0x38, 0x18, 0x0E, - 0x7F, 0xC4, 0x7C, 0x89, 0x02, 0x4A, 0x7F, 0x56, - 0x19, 0x1A, 0xDB, 0x87, 0x8D, 0xFD, 0xE4, 0xEA, - 0xD6, 0x22, 0x23, 0xF5, 0xA2, 0x61, 0x0E, 0xFE - }, - { - 0xCD, 0x36, 0xB3, 0xD5, 0xB4, 0xC9, 0x1B, 0x90, - 0xFC, 0xBB, 0xA7, 0x95, 0x13, 0xCF, 0xEE, 0x19, - 0x07, 0xD8, 0x64, 0x5A, 0x16, 0x2A, 0xFD, 0x0C, - 0xD4, 0xCF, 0x41, 0x92, 0xD4, 0xA5, 0xF4, 0xC8, - 0x92, 0x18, 0x3A, 0x8E, 0xAC, 0xDB, 0x2B, 0x6B, - 0x6A, 0x9D, 0x9A, 0xA8, 0xC1, 0x1A, 0xC1, 0xB2, - 0x61, 0xB3, 0x80, 0xDB, 0xEE, 0x24, 0xCA, 0x46, - 0x8F, 0x1B, 0xFD, 0x04, 0x3C, 0x58, 0xEE, 0xFE - }, - { - 0x98, 0x59, 0x34, 0x52, 0x28, 0x16, 0x61, 0xA5, - 0x3C, 0x48, 0xA9, 0xD8, 0xCD, 0x79, 0x08, 0x26, - 0xC1, 0xA1, 0xCE, 0x56, 0x77, 0x38, 0x05, 0x3D, - 0x0B, 0xEE, 0x4A, 0x91, 0xA3, 0xD5, 0xBD, 0x92, - 0xEE, 0xFD, 0xBA, 0xBE, 0xBE, 0x32, 0x04, 0xF2, - 0x03, 0x1C, 0xA5, 0xF7, 0x81, 0xBD, 0xA9, 0x9E, - 0xF5, 0xD8, 0xAE, 0x56, 0xE5, 0xB0, 0x4A, 0x9E, - 0x1E, 0xCD, 0x21, 0xB0, 0xEB, 0x05, 0xD3, 0xE1 - }, - { - 0x77, 0x1F, 0x57, 0xDD, 0x27, 0x75, 0xCC, 0xDA, - 0xB5, 0x59, 0x21, 0xD3, 0xE8, 0xE3, 0x0C, 0xCF, - 0x48, 0x4D, 0x61, 0xFE, 0x1C, 0x1B, 0x9C, 0x2A, - 0xE8, 0x19, 0xD0, 0xFB, 0x2A, 0x12, 0xFA, 0xB9, - 0xBE, 0x70, 0xC4, 0xA7, 0xA1, 0x38, 0xDA, 0x84, - 0xE8, 0x28, 0x04, 0x35, 0xDA, 0xAD, 0xE5, 0xBB, - 0xE6, 0x6A, 0xF0, 0x83, 0x6A, 0x15, 0x4F, 0x81, - 0x7F, 0xB1, 0x7F, 0x33, 0x97, 0xE7, 0x25, 0xA3 - }, - { - 0xC6, 0x08, 0x97, 0xC6, 0xF8, 0x28, 0xE2, 0x1F, - 0x16, 0xFB, 0xB5, 0xF1, 0x5B, 0x32, 0x3F, 0x87, - 0xB6, 0xC8, 0x95, 0x5E, 0xAB, 0xF1, 0xD3, 0x80, - 0x61, 0xF7, 0x07, 0xF6, 0x08, 0xAB, 0xDD, 0x99, - 0x3F, 0xAC, 0x30, 0x70, 0x63, 0x3E, 0x28, 0x6C, - 0xF8, 0x33, 0x9C, 0xE2, 0x95, 0xDD, 0x35, 0x2D, - 0xF4, 0xB4, 0xB4, 0x0B, 0x2F, 0x29, 0xDA, 0x1D, - 0xD5, 0x0B, 0x3A, 0x05, 0xD0, 0x79, 0xE6, 0xBB - }, - { - 0x82, 0x10, 0xCD, 0x2C, 0x2D, 0x3B, 0x13, 0x5C, - 0x2C, 0xF0, 0x7F, 0xA0, 0xD1, 0x43, 0x3C, 0xD7, - 0x71, 0xF3, 0x25, 0xD0, 0x75, 0xC6, 0x46, 0x9D, - 0x9C, 0x7F, 0x1B, 0xA0, 0x94, 0x3C, 0xD4, 0xAB, - 0x09, 0x80, 0x8C, 0xAB, 0xF4, 0xAC, 0xB9, 0xCE, - 0x5B, 0xB8, 0x8B, 0x49, 0x89, 0x29, 0xB4, 0xB8, - 0x47, 0xF6, 0x81, 0xAD, 0x2C, 0x49, 0x0D, 0x04, - 0x2D, 0xB2, 0xAE, 0xC9, 0x42, 0x14, 0xB0, 0x6B - }, - { - 0x1D, 0x4E, 0xDF, 0xFF, 0xD8, 0xFD, 0x80, 0xF7, - 0xE4, 0x10, 0x78, 0x40, 0xFA, 0x3A, 0xA3, 0x1E, - 0x32, 0x59, 0x84, 0x91, 0xE4, 0xAF, 0x70, 0x13, - 0xC1, 0x97, 0xA6, 0x5B, 0x7F, 0x36, 0xDD, 0x3A, - 0xC4, 0xB4, 0x78, 0x45, 0x61, 0x11, 0xCD, 0x43, - 0x09, 0xD9, 0x24, 0x35, 0x10, 0x78, 0x2F, 0xA3, - 0x1B, 0x7C, 0x4C, 0x95, 0xFA, 0x95, 0x15, 0x20, - 0xD0, 0x20, 0xEB, 0x7E, 0x5C, 0x36, 0xE4, 0xEF - }, - { - 0xAF, 0x8E, 0x6E, 0x91, 0xFA, 0xB4, 0x6C, 0xE4, - 0x87, 0x3E, 0x1A, 0x50, 0xA8, 0xEF, 0x44, 0x8C, - 0xC2, 0x91, 0x21, 0xF7, 0xF7, 0x4D, 0xEE, 0xF3, - 0x4A, 0x71, 0xEF, 0x89, 0xCC, 0x00, 0xD9, 0x27, - 0x4B, 0xC6, 0xC2, 0x45, 0x4B, 0xBB, 0x32, 0x30, - 0xD8, 0xB2, 0xEC, 0x94, 0xC6, 0x2B, 0x1D, 0xEC, - 0x85, 0xF3, 0x59, 0x3B, 0xFA, 0x30, 0xEA, 0x6F, - 0x7A, 0x44, 0xD7, 0xC0, 0x94, 0x65, 0xA2, 0x53 - }, - { - 0x29, 0xFD, 0x38, 0x4E, 0xD4, 0x90, 0x6F, 0x2D, - 0x13, 0xAA, 0x9F, 0xE7, 0xAF, 0x90, 0x59, 0x90, - 0x93, 0x8B, 0xED, 0x80, 0x7F, 0x18, 0x32, 0x45, - 0x4A, 0x37, 0x2A, 0xB4, 0x12, 0xEE, 0xA1, 0xF5, - 0x62, 0x5A, 0x1F, 0xCC, 0x9A, 0xC8, 0x34, 0x3B, - 0x7C, 0x67, 0xC5, 0xAB, 0xA6, 0xE0, 0xB1, 0xCC, - 0x46, 0x44, 0x65, 0x49, 0x13, 0x69, 0x2C, 0x6B, - 0x39, 0xEB, 0x91, 0x87, 0xCE, 0xAC, 0xD3, 0xEC - }, - { - 0xA2, 0x68, 0xC7, 0x88, 0x5D, 0x98, 0x74, 0xA5, - 0x1C, 0x44, 0xDF, 0xFE, 0xD8, 0xEA, 0x53, 0xE9, - 0x4F, 0x78, 0x45, 0x6E, 0x0B, 0x2E, 0xD9, 0x9F, - 0xF5, 0xA3, 0x92, 0x47, 0x60, 0x81, 0x38, 0x26, - 0xD9, 0x60, 0xA1, 0x5E, 0xDB, 0xED, 0xBB, 0x5D, - 0xE5, 0x22, 0x6B, 0xA4, 0xB0, 0x74, 0xE7, 0x1B, - 0x05, 0xC5, 0x5B, 0x97, 0x56, 0xBB, 0x79, 0xE5, - 0x5C, 0x02, 0x75, 0x4C, 0x2C, 0x7B, 0x6C, 0x8A - }, - { - 0x0C, 0xF8, 0x54, 0x54, 0x88, 0xD5, 0x6A, 0x86, - 0x81, 0x7C, 0xD7, 0xEC, 0xB1, 0x0F, 0x71, 0x16, - 0xB7, 0xEA, 0x53, 0x0A, 0x45, 0xB6, 0xEA, 0x49, - 0x7B, 0x6C, 0x72, 0xC9, 0x97, 0xE0, 0x9E, 0x3D, - 0x0D, 0xA8, 0x69, 0x8F, 0x46, 0xBB, 0x00, 0x6F, - 0xC9, 0x77, 0xC2, 0xCD, 0x3D, 0x11, 0x77, 0x46, - 0x3A, 0xC9, 0x05, 0x7F, 0xDD, 0x16, 0x62, 0xC8, - 0x5D, 0x0C, 0x12, 0x64, 0x43, 0xC1, 0x04, 0x73 - }, - { - 0xB3, 0x96, 0x14, 0x26, 0x8F, 0xDD, 0x87, 0x81, - 0x51, 0x5E, 0x2C, 0xFE, 0xBF, 0x89, 0xB4, 0xD5, - 0x40, 0x2B, 0xAB, 0x10, 0xC2, 0x26, 0xE6, 0x34, - 0x4E, 0x6B, 0x9A, 0xE0, 0x00, 0xFB, 0x0D, 0x6C, - 0x79, 0xCB, 0x2F, 0x3E, 0xC8, 0x0E, 0x80, 0xEA, - 0xEB, 0x19, 0x80, 0xD2, 0xF8, 0x69, 0x89, 0x16, - 0xBD, 0x2E, 0x9F, 0x74, 0x72, 0x36, 0x65, 0x51, - 0x16, 0x64, 0x9C, 0xD3, 0xCA, 0x23, 0xA8, 0x37 - }, - { - 0x74, 0xBE, 0xF0, 0x92, 0xFC, 0x6F, 0x1E, 0x5D, - 0xBA, 0x36, 0x63, 0xA3, 0xFB, 0x00, 0x3B, 0x2A, - 0x5B, 0xA2, 0x57, 0x49, 0x65, 0x36, 0xD9, 0x9F, - 0x62, 0xB9, 0xD7, 0x3F, 0x8F, 0x9E, 0xB3, 0xCE, - 0x9F, 0xF3, 0xEE, 0xC7, 0x09, 0xEB, 0x88, 0x36, - 0x55, 0xEC, 0x9E, 0xB8, 0x96, 0xB9, 0x12, 0x8F, - 0x2A, 0xFC, 0x89, 0xCF, 0x7D, 0x1A, 0xB5, 0x8A, - 0x72, 0xF4, 0xA3, 0xBF, 0x03, 0x4D, 0x2B, 0x4A - }, - { - 0x3A, 0x98, 0x8D, 0x38, 0xD7, 0x56, 0x11, 0xF3, - 0xEF, 0x38, 0xB8, 0x77, 0x49, 0x80, 0xB3, 0x3E, - 0x57, 0x3B, 0x6C, 0x57, 0xBE, 0xE0, 0x46, 0x9B, - 0xA5, 0xEE, 0xD9, 0xB4, 0x4F, 0x29, 0x94, 0x5E, - 0x73, 0x47, 0x96, 0x7F, 0xBA, 0x2C, 0x16, 0x2E, - 0x1C, 0x3B, 0xE7, 0xF3, 0x10, 0xF2, 0xF7, 0x5E, - 0xE2, 0x38, 0x1E, 0x7B, 0xFD, 0x6B, 0x3F, 0x0B, - 0xAE, 0xA8, 0xD9, 0x5D, 0xFB, 0x1D, 0xAF, 0xB1 - }, - { - 0x58, 0xAE, 0xDF, 0xCE, 0x6F, 0x67, 0xDD, 0xC8, - 0x5A, 0x28, 0xC9, 0x92, 0xF1, 0xC0, 0xBD, 0x09, - 0x69, 0xF0, 0x41, 0xE6, 0x6F, 0x1E, 0xE8, 0x80, - 0x20, 0xA1, 0x25, 0xCB, 0xFC, 0xFE, 0xBC, 0xD6, - 0x17, 0x09, 0xC9, 0xC4, 0xEB, 0xA1, 0x92, 0xC1, - 0x5E, 0x69, 0xF0, 0x20, 0xD4, 0x62, 0x48, 0x60, - 0x19, 0xFA, 0x8D, 0xEA, 0x0C, 0xD7, 0xA4, 0x29, - 0x21, 0xA1, 0x9D, 0x2F, 0xE5, 0x46, 0xD4, 0x3D - }, - { - 0x93, 0x47, 0xBD, 0x29, 0x14, 0x73, 0xE6, 0xB4, - 0xE3, 0x68, 0x43, 0x7B, 0x8E, 0x56, 0x1E, 0x06, - 0x5F, 0x64, 0x9A, 0x6D, 0x8A, 0xDA, 0x47, 0x9A, - 0xD0, 0x9B, 0x19, 0x99, 0xA8, 0xF2, 0x6B, 0x91, - 0xCF, 0x61, 0x20, 0xFD, 0x3B, 0xFE, 0x01, 0x4E, - 0x83, 0xF2, 0x3A, 0xCF, 0xA4, 0xC0, 0xAD, 0x7B, - 0x37, 0x12, 0xB2, 0xC3, 0xC0, 0x73, 0x32, 0x70, - 0x66, 0x31, 0x12, 0xCC, 0xD9, 0x28, 0x5C, 0xD9 - }, - { - 0xB3, 0x21, 0x63, 0xE7, 0xC5, 0xDB, 0xB5, 0xF5, - 0x1F, 0xDC, 0x11, 0xD2, 0xEA, 0xC8, 0x75, 0xEF, - 0xBB, 0xCB, 0x7E, 0x76, 0x99, 0x09, 0x0A, 0x7E, - 0x7F, 0xF8, 0xA8, 0xD5, 0x07, 0x95, 0xAF, 0x5D, - 0x74, 0xD9, 0xFF, 0x98, 0x54, 0x3E, 0xF8, 0xCD, - 0xF8, 0x9A, 0xC1, 0x3D, 0x04, 0x85, 0x27, 0x87, - 0x56, 0xE0, 0xEF, 0x00, 0xC8, 0x17, 0x74, 0x56, - 0x61, 0xE1, 0xD5, 0x9F, 0xE3, 0x8E, 0x75, 0x37 - }, - { - 0x10, 0x85, 0xD7, 0x83, 0x07, 0xB1, 0xC4, 0xB0, - 0x08, 0xC5, 0x7A, 0x2E, 0x7E, 0x5B, 0x23, 0x46, - 0x58, 0xA0, 0xA8, 0x2E, 0x4F, 0xF1, 0xE4, 0xAA, - 0xAC, 0x72, 0xB3, 0x12, 0xFD, 0xA0, 0xFE, 0x27, - 0xD2, 0x33, 0xBC, 0x5B, 0x10, 0xE9, 0xCC, 0x17, - 0xFD, 0xC7, 0x69, 0x7B, 0x54, 0x0C, 0x7D, 0x95, - 0xEB, 0x21, 0x5A, 0x19, 0xA1, 0xA0, 0xE2, 0x0E, - 0x1A, 0xBF, 0xA1, 0x26, 0xEF, 0xD5, 0x68, 0xC7 - }, - { - 0x4E, 0x5C, 0x73, 0x4C, 0x7D, 0xDE, 0x01, 0x1D, - 0x83, 0xEA, 0xC2, 0xB7, 0x34, 0x7B, 0x37, 0x35, - 0x94, 0xF9, 0x2D, 0x70, 0x91, 0xB9, 0xCA, 0x34, - 0xCB, 0x9C, 0x6F, 0x39, 0xBD, 0xF5, 0xA8, 0xD2, - 0xF1, 0x34, 0x37, 0x9E, 0x16, 0xD8, 0x22, 0xF6, - 0x52, 0x21, 0x70, 0xCC, 0xF2, 0xDD, 0xD5, 0x5C, - 0x84, 0xB9, 0xE6, 0xC6, 0x4F, 0xC9, 0x27, 0xAC, - 0x4C, 0xF8, 0xDF, 0xB2, 0xA1, 0x77, 0x01, 0xF2 - }, - { - 0x69, 0x5D, 0x83, 0xBD, 0x99, 0x0A, 0x11, 0x17, - 0xB3, 0xD0, 0xCE, 0x06, 0xCC, 0x88, 0x80, 0x27, - 0xD1, 0x2A, 0x05, 0x4C, 0x26, 0x77, 0xFD, 0x82, - 0xF0, 0xD4, 0xFB, 0xFC, 0x93, 0x57, 0x55, 0x23, - 0xE7, 0x99, 0x1A, 0x5E, 0x35, 0xA3, 0x75, 0x2E, - 0x9B, 0x70, 0xCE, 0x62, 0x99, 0x2E, 0x26, 0x8A, - 0x87, 0x77, 0x44, 0xCD, 0xD4, 0x35, 0xF5, 0xF1, - 0x30, 0x86, 0x9C, 0x9A, 0x20, 0x74, 0xB3, 0x38 - }, - { - 0xA6, 0x21, 0x37, 0x43, 0x56, 0x8E, 0x3B, 0x31, - 0x58, 0xB9, 0x18, 0x43, 0x01, 0xF3, 0x69, 0x08, - 0x47, 0x55, 0x4C, 0x68, 0x45, 0x7C, 0xB4, 0x0F, - 0xC9, 0xA4, 0xB8, 0xCF, 0xD8, 0xD4, 0xA1, 0x18, - 0xC3, 0x01, 0xA0, 0x77, 0x37, 0xAE, 0xDA, 0x0F, - 0x92, 0x9C, 0x68, 0x91, 0x3C, 0x5F, 0x51, 0xC8, - 0x03, 0x94, 0xF5, 0x3B, 0xFF, 0x1C, 0x3E, 0x83, - 0xB2, 0xE4, 0x0C, 0xA9, 0x7E, 0xBA, 0x9E, 0x15 - }, - { - 0xD4, 0x44, 0xBF, 0xA2, 0x36, 0x2A, 0x96, 0xDF, - 0x21, 0x3D, 0x07, 0x0E, 0x33, 0xFA, 0x84, 0x1F, - 0x51, 0x33, 0x4E, 0x4E, 0x76, 0x86, 0x6B, 0x81, - 0x39, 0xE8, 0xAF, 0x3B, 0xB3, 0x39, 0x8B, 0xE2, - 0xDF, 0xAD, 0xDC, 0xBC, 0x56, 0xB9, 0x14, 0x6D, - 0xE9, 0xF6, 0x81, 0x18, 0xDC, 0x58, 0x29, 0xE7, - 0x4B, 0x0C, 0x28, 0xD7, 0x71, 0x19, 0x07, 0xB1, - 0x21, 0xF9, 0x16, 0x1C, 0xB9, 0x2B, 0x69, 0xA9 - }, - { - 0x14, 0x27, 0x09, 0xD6, 0x2E, 0x28, 0xFC, 0xCC, - 0xD0, 0xAF, 0x97, 0xFA, 0xD0, 0xF8, 0x46, 0x5B, - 0x97, 0x1E, 0x82, 0x20, 0x1D, 0xC5, 0x10, 0x70, - 0xFA, 0xA0, 0x37, 0x2A, 0xA4, 0x3E, 0x92, 0x48, - 0x4B, 0xE1, 0xC1, 0xE7, 0x3B, 0xA1, 0x09, 0x06, - 0xD5, 0xD1, 0x85, 0x3D, 0xB6, 0xA4, 0x10, 0x6E, - 0x0A, 0x7B, 0xF9, 0x80, 0x0D, 0x37, 0x3D, 0x6D, - 0xEE, 0x2D, 0x46, 0xD6, 0x2E, 0xF2, 0xA4, 0x61 - }, -}; - - - - -static const uint8_t blake2sp_kat[KAT_LENGTH][BLAKE2S_OUTBYTES] = -{ - { - 0xDD, 0x0E, 0x89, 0x17, 0x76, 0x93, 0x3F, 0x43, - 0xC7, 0xD0, 0x32, 0xB0, 0x8A, 0x91, 0x7E, 0x25, - 0x74, 0x1F, 0x8A, 0xA9, 0xA1, 0x2C, 0x12, 0xE1, - 0xCA, 0xC8, 0x80, 0x15, 0x00, 0xF2, 0xCA, 0x4F - }, - { - 0xA6, 0xB9, 0xEE, 0xCC, 0x25, 0x22, 0x7A, 0xD7, - 0x88, 0xC9, 0x9D, 0x3F, 0x23, 0x6D, 0xEB, 0xC8, - 0xDA, 0x40, 0x88, 0x49, 0xE9, 0xA5, 0x17, 0x89, - 0x78, 0x72, 0x7A, 0x81, 0x45, 0x7F, 0x72, 0x39 - }, - { - 0xDA, 0xCA, 0xDE, 0xCE, 0x7A, 0x8E, 0x6B, 0xF3, - 0xAB, 0xFE, 0x32, 0x4C, 0xA6, 0x95, 0x43, 0x69, - 0x84, 0xB8, 0x19, 0x5D, 0x29, 0xF6, 0xBB, 0xD8, - 0x96, 0xE4, 0x1E, 0x18, 0xE2, 0x1C, 0x91, 0x45 - }, - { - 0xED, 0x14, 0x41, 0x3B, 0x40, 0xDA, 0x68, 0x9F, - 0x1F, 0x7F, 0xED, 0x2B, 0x08, 0xDF, 0xF4, 0x5B, - 0x80, 0x92, 0xDB, 0x5E, 0xC2, 0xC3, 0x61, 0x0E, - 0x02, 0x72, 0x4D, 0x20, 0x2F, 0x42, 0x3C, 0x46 - }, - { - 0x9B, 0x8A, 0x52, 0x7B, 0x52, 0x72, 0x25, 0x0A, - 0x1E, 0xC3, 0x97, 0x38, 0x8F, 0x04, 0x09, 0x14, - 0x95, 0x48, 0x06, 0xE7, 0x94, 0xDB, 0x04, 0xB7, - 0x0A, 0x46, 0x11, 0xBC, 0x59, 0x58, 0x6A, 0x83 - }, - { - 0x2B, 0xB6, 0x33, 0x37, 0x29, 0x00, 0x0B, 0xE3, - 0xD5, 0xA2, 0x1B, 0x98, 0xF8, 0xE7, 0xEA, 0xD0, - 0x77, 0xF1, 0x51, 0xA5, 0x39, 0x39, 0x19, 0xEB, - 0x67, 0xC8, 0x76, 0xEE, 0x00, 0xBB, 0xBB, 0x04 - }, - { - 0x63, 0xC0, 0x14, 0x08, 0x15, 0x4A, 0xD1, 0x9D, - 0x7F, 0xB7, 0x39, 0xF3, 0x11, 0x78, 0x17, 0x80, - 0x46, 0x2C, 0xF2, 0xEE, 0xCC, 0xE6, 0x0F, 0x06, - 0x4E, 0x85, 0x34, 0x87, 0xC2, 0x72, 0xE3, 0xEB - }, - { - 0x3D, 0x05, 0x1A, 0x11, 0x76, 0x01, 0x9C, 0xA3, - 0x7B, 0xF3, 0x3D, 0x60, 0x42, 0x7F, 0x8D, 0x9D, - 0x1C, 0x3A, 0xBD, 0x59, 0x82, 0x97, 0xCF, 0xB4, - 0x23, 0x5F, 0x74, 0x7D, 0x7C, 0x7C, 0x7F, 0xEC - }, - { - 0x39, 0x1E, 0xA9, 0x12, 0xDF, 0x4D, 0x4D, 0x79, - 0xA4, 0x64, 0x6D, 0x9D, 0xA2, 0x54, 0x9A, 0x44, - 0x6D, 0x22, 0x40, 0xF6, 0x24, 0x15, 0xD0, 0x70, - 0xA2, 0xE0, 0x93, 0x99, 0x2B, 0x47, 0x1F, 0xBA - }, - { - 0x32, 0x46, 0x40, 0x44, 0x0E, 0xA5, 0xC3, 0x08, - 0x2D, 0xDC, 0x30, 0x9E, 0x78, 0x09, 0xD7, 0x41, - 0xD6, 0xCC, 0x1B, 0x2D, 0x49, 0x0F, 0xF8, 0xC0, - 0x52, 0x12, 0x8A, 0x6E, 0xEB, 0x40, 0x9D, 0x62 - }, - { - 0xAB, 0x85, 0x5E, 0x6F, 0xA3, 0x9A, 0x5E, 0x8F, - 0xC9, 0x0E, 0xAC, 0xB9, 0x99, 0xC7, 0xF7, 0x8A, - 0xE7, 0x1E, 0x59, 0xC3, 0xD9, 0x7D, 0x60, 0xAF, - 0xE5, 0x17, 0xD5, 0x87, 0x92, 0x3B, 0x77, 0x11 - }, - { - 0x2A, 0x39, 0xDA, 0x45, 0x86, 0xEF, 0xC4, 0x77, - 0x85, 0xA7, 0xA8, 0xDA, 0x85, 0x68, 0x3A, 0x51, - 0x72, 0x4C, 0xDE, 0xF5, 0x41, 0x3B, 0x35, 0x6D, - 0xC4, 0xFB, 0x50, 0x05, 0x13, 0xF8, 0xFA, 0x2E - }, - { - 0x8A, 0x00, 0x57, 0xC1, 0xF7, 0x8A, 0xD6, 0x21, - 0x45, 0x55, 0xC0, 0x67, 0x07, 0x33, 0xE2, 0x9A, - 0x4C, 0x7E, 0x95, 0x62, 0x27, 0x66, 0x0E, 0xFE, - 0xB1, 0xD7, 0xFC, 0x79, 0xF5, 0x8E, 0xC6, 0xF2 - }, - { - 0x07, 0x64, 0xB0, 0x01, 0x7F, 0x5B, 0xD9, 0x51, - 0xF0, 0x1D, 0x9F, 0xDF, 0x95, 0xC0, 0xCB, 0x41, - 0x38, 0x98, 0x5D, 0x84, 0x79, 0x9C, 0xD4, 0x29, - 0x84, 0xE2, 0x5B, 0x51, 0x28, 0x00, 0xE7, 0x3C - }, - { - 0xCC, 0x02, 0x49, 0x56, 0x93, 0xC8, 0xE1, 0x84, - 0xAD, 0x2E, 0xD0, 0x9D, 0x53, 0x3D, 0xC3, 0x3B, - 0x76, 0xA7, 0x78, 0x3D, 0x62, 0x07, 0xFC, 0xAC, - 0xCB, 0x64, 0xF3, 0xED, 0x2C, 0x6D, 0x66, 0xE0 - }, - { - 0xC0, 0xDF, 0x49, 0xC2, 0x06, 0xA3, 0x42, 0x88, - 0x14, 0x32, 0x16, 0x84, 0x7D, 0xF3, 0x34, 0xD4, - 0x56, 0x9D, 0xAD, 0x73, 0xC2, 0xB1, 0xFF, 0x62, - 0x84, 0x88, 0x4F, 0xD3, 0x89, 0x41, 0xFB, 0x95 - }, - { - 0xB9, 0x19, 0x45, 0x19, 0xE4, 0x97, 0x8A, 0x9D, - 0xC8, 0x93, 0xB2, 0x8B, 0xD8, 0x08, 0xCD, 0xFA, - 0xBB, 0x1B, 0xD5, 0x10, 0xD8, 0x62, 0xB3, 0x17, - 0x1F, 0xF6, 0xE0, 0x17, 0xA4, 0x1B, 0x80, 0x4C - }, - { - 0xBB, 0xA9, 0x27, 0xAC, 0xF1, 0x1B, 0xEB, 0xD3, - 0x62, 0xA3, 0xA3, 0xEB, 0x78, 0xC4, 0xBB, 0x65, - 0xE6, 0x02, 0xA8, 0x70, 0x9F, 0xCE, 0xF3, 0x8D, - 0xC6, 0xC8, 0xB7, 0xBD, 0xA6, 0x64, 0xC3, 0x2C - }, - { - 0xEC, 0xB4, 0x90, 0x0A, 0x63, 0x92, 0x4E, 0x72, - 0x0D, 0x40, 0xF2, 0xD2, 0xB1, 0x4D, 0x1B, 0xB3, - 0x9C, 0x37, 0x01, 0xAD, 0x73, 0x46, 0xBD, 0x0B, - 0x67, 0x23, 0x42, 0x70, 0xBF, 0xBE, 0x7E, 0x70 - }, - { - 0xF8, 0x31, 0x5A, 0x21, 0xB2, 0x5E, 0x6B, 0xA8, - 0xBF, 0x59, 0xB1, 0x7B, 0x05, 0x91, 0x3B, 0x8C, - 0xA4, 0x65, 0x9F, 0x1C, 0xD8, 0x38, 0xFC, 0xC7, - 0x73, 0xC9, 0xEB, 0x12, 0xE7, 0x00, 0x4E, 0x09 - }, - { - 0x4B, 0x77, 0xAF, 0x67, 0xA9, 0x23, 0x2B, 0xF1, - 0x18, 0x4E, 0x57, 0x81, 0x82, 0x94, 0x03, 0x1E, - 0x55, 0xF1, 0xF8, 0x53, 0xC9, 0x4D, 0xBA, 0xB5, - 0x57, 0x75, 0x47, 0x33, 0x0D, 0x65, 0xAA, 0x61 - }, - { - 0x76, 0x85, 0x68, 0x39, 0x0F, 0xD2, 0xB8, 0x70, - 0x94, 0x11, 0x4E, 0xD4, 0xCF, 0x72, 0x3E, 0xA3, - 0x20, 0xFE, 0x97, 0x7B, 0x53, 0x18, 0x03, 0x05, - 0xC3, 0x84, 0x33, 0x54, 0x79, 0xF0, 0xB5, 0x9B - }, - { - 0xA4, 0x31, 0xCB, 0x27, 0x0F, 0x3E, 0x2C, 0x9B, - 0x7A, 0x95, 0x93, 0xB1, 0x55, 0xCC, 0xEC, 0xFF, - 0x5B, 0x5C, 0x4A, 0x2D, 0xCD, 0x5D, 0x6B, 0xB1, - 0xC4, 0x85, 0xAA, 0x28, 0x69, 0x97, 0xF9, 0x15 - }, - { - 0xD6, 0x91, 0xFA, 0x6A, 0x79, 0x0B, 0x1A, 0x51, - 0x79, 0x80, 0x08, 0x7F, 0x50, 0xB0, 0x3D, 0xED, - 0x8C, 0x6E, 0xD4, 0x86, 0xD0, 0x84, 0x22, 0x1C, - 0x82, 0x7D, 0x9B, 0xD9, 0x22, 0xBE, 0xB8, 0xC0 - }, - { - 0x8F, 0x97, 0x8A, 0x49, 0x32, 0xF4, 0x45, 0x98, - 0x13, 0xE8, 0xFE, 0x15, 0x68, 0x6E, 0x4E, 0xFA, - 0x25, 0xC2, 0xC5, 0xFF, 0x5A, 0x3A, 0x4F, 0x8C, - 0x9B, 0x14, 0x96, 0x5D, 0x2F, 0x0B, 0xE4, 0x61 - }, - { - 0x1E, 0xFB, 0xD0, 0xC1, 0x31, 0x44, 0x91, 0x42, - 0xF2, 0x29, 0x5F, 0x2D, 0x42, 0x41, 0x1D, 0xFE, - 0x0F, 0x48, 0xD4, 0xAC, 0xAE, 0x76, 0x2D, 0x8D, - 0xF6, 0x7A, 0x57, 0x0B, 0xF7, 0xB1, 0xDC, 0xD5 - }, - { - 0xD5, 0x3B, 0xA9, 0x33, 0x46, 0x14, 0x3A, 0xB8, - 0xE0, 0xD3, 0xD1, 0xBF, 0x27, 0x27, 0x06, 0xD1, - 0x69, 0xE6, 0x6C, 0x69, 0xC7, 0xB8, 0xF4, 0xA5, - 0xE8, 0x2F, 0xEF, 0x44, 0x07, 0x02, 0xBC, 0xF2 - }, - { - 0xF7, 0x1A, 0x3E, 0xC0, 0x1A, 0xA3, 0x82, 0xEA, - 0x76, 0x99, 0x2B, 0x43, 0x0A, 0x7F, 0x42, 0xC7, - 0xAD, 0x2A, 0x86, 0xAE, 0xA9, 0xC1, 0x9E, 0x76, - 0xCD, 0x17, 0x32, 0xEC, 0x68, 0x30, 0xDE, 0x6F - }, - { - 0x80, 0xA6, 0xAB, 0x7B, 0x71, 0x04, 0x64, 0xF9, - 0x3E, 0x6C, 0xBA, 0x96, 0x86, 0x4A, 0xA6, 0x40, - 0x9B, 0xCA, 0xFC, 0x1B, 0xF4, 0xB3, 0x2A, 0x30, - 0x93, 0x72, 0xE8, 0x57, 0xE8, 0x04, 0x06, 0x8C - }, - { - 0xDB, 0xDE, 0x81, 0xE5, 0x1A, 0x52, 0x17, 0x4B, - 0x10, 0x14, 0x90, 0x1B, 0x53, 0xBE, 0xF8, 0x8D, - 0xE9, 0x3B, 0x29, 0xE2, 0x74, 0x34, 0x7E, 0x8E, - 0x9A, 0x7B, 0x03, 0x74, 0x56, 0x62, 0x9F, 0x35 - }, - { - 0x75, 0xF2, 0x74, 0x46, 0x6B, 0x1A, 0x2D, 0x0F, - 0xD8, 0x45, 0xBB, 0xB5, 0x7C, 0x38, 0xC9, 0x89, - 0x51, 0x6E, 0x15, 0x68, 0x32, 0x0A, 0xB5, 0x17, - 0xB1, 0x63, 0xEA, 0xF7, 0x09, 0x23, 0x4C, 0xC7 - }, - { - 0xAF, 0xE1, 0xA0, 0x59, 0x1C, 0x49, 0x1D, 0x41, - 0x6E, 0xB6, 0x4F, 0x62, 0x86, 0xF3, 0xBA, 0x29, - 0xD4, 0xC9, 0x99, 0x82, 0x14, 0xA3, 0x83, 0x1C, - 0x39, 0x01, 0x4A, 0xC0, 0x30, 0x55, 0x79, 0x45 - }, - { - 0x67, 0xFF, 0x6A, 0xCD, 0xBE, 0x8A, 0x99, 0xA1, - 0x66, 0xA5, 0xD9, 0xCF, 0x32, 0x13, 0x65, 0x06, - 0xB5, 0x48, 0xD6, 0xC9, 0x47, 0xC2, 0x4C, 0x69, - 0x9C, 0xEA, 0x3A, 0xFD, 0x92, 0xAD, 0xFA, 0xCA - }, - { - 0xBF, 0xB4, 0xD0, 0xC7, 0x11, 0x20, 0x75, 0x26, - 0x2C, 0x2D, 0xD2, 0x48, 0xF3, 0x34, 0xB2, 0xEF, - 0x15, 0x40, 0x08, 0x7E, 0xCC, 0x73, 0x82, 0xBC, - 0x2A, 0x27, 0x25, 0x75, 0xC5, 0x00, 0x9F, 0x70 - }, - { - 0x17, 0xC9, 0x4B, 0x9C, 0x53, 0x72, 0x43, 0xF2, - 0x33, 0x5B, 0x86, 0x39, 0x49, 0xB2, 0xB9, 0x1C, - 0x98, 0xA6, 0x95, 0x6D, 0x7C, 0x10, 0xAA, 0x98, - 0x99, 0x59, 0xA8, 0x0F, 0x91, 0x0C, 0x25, 0x22 - }, - { - 0xF6, 0x33, 0x8F, 0x43, 0x4D, 0x31, 0x94, 0x10, - 0x19, 0x6D, 0x95, 0x19, 0xAB, 0xCA, 0xEF, 0xF7, - 0xD5, 0x54, 0x39, 0xFD, 0x2A, 0xA5, 0xBA, 0xBF, - 0x7A, 0x7E, 0x79, 0x13, 0xB2, 0x94, 0xED, 0x4D - }, - { - 0x08, 0xEF, 0x7D, 0x65, 0xF9, 0xBB, 0xF3, 0xDA, - 0x1F, 0x78, 0x84, 0xAE, 0x9B, 0x75, 0x90, 0x1F, - 0xD8, 0x52, 0x95, 0x66, 0x2A, 0x6E, 0xA7, 0x1D, - 0xE0, 0x8B, 0xEE, 0x38, 0x34, 0x57, 0x62, 0x78 - }, - { - 0x16, 0x47, 0xEC, 0xC2, 0xBA, 0x13, 0xF8, 0xB9, - 0x3B, 0x2F, 0xBC, 0xDC, 0x4E, 0x8F, 0x1D, 0xFA, - 0x47, 0xFE, 0x3B, 0xE1, 0x2A, 0xAA, 0x0E, 0x45, - 0x9B, 0x0E, 0x5A, 0x87, 0xF3, 0xA6, 0x9B, 0xB0 - }, - { - 0xFF, 0x92, 0x7A, 0x71, 0x78, 0x81, 0xF6, 0xFD, - 0x8E, 0xD8, 0xBF, 0x5D, 0x5E, 0x35, 0xBD, 0x80, - 0x16, 0x15, 0x73, 0xE5, 0x82, 0x94, 0x04, 0xC3, - 0x2D, 0x2A, 0x27, 0x6A, 0x01, 0xF4, 0xB9, 0x06 - }, - { - 0xC8, 0xCA, 0xF1, 0x36, 0xFF, 0x20, 0x9C, 0x82, - 0xE0, 0x24, 0x0C, 0x1E, 0x62, 0xA3, 0xBC, 0x7E, - 0x9C, 0xAC, 0x87, 0x3B, 0x01, 0x1C, 0xF7, 0xC5, - 0xE6, 0x7E, 0xC1, 0x87, 0xA5, 0xFB, 0xCD, 0x96 - }, - { - 0xD9, 0xAC, 0xC7, 0x3E, 0x3F, 0x42, 0x1E, 0x18, - 0x83, 0xB5, 0xED, 0x53, 0xD8, 0x2A, 0x9A, 0xEC, - 0x8F, 0x5D, 0xC9, 0x80, 0xC4, 0x2B, 0xCA, 0xEB, - 0x0E, 0x7D, 0x89, 0x76, 0xA3, 0x38, 0xEF, 0x51 - }, - { - 0x9F, 0x17, 0x3F, 0xCF, 0x08, 0xA5, 0x36, 0x21, - 0x93, 0xF3, 0x52, 0xC8, 0x25, 0x6A, 0xE5, 0x34, - 0xAE, 0x9C, 0xE7, 0xBF, 0xA4, 0xBC, 0x09, 0xFA, - 0xC9, 0x00, 0x98, 0xF9, 0x8A, 0x71, 0x62, 0x94 - }, - { - 0x0A, 0x72, 0x45, 0x79, 0xDC, 0x80, 0xBC, 0x0C, - 0x90, 0x04, 0xE5, 0x1B, 0xE7, 0xEF, 0xF3, 0xAF, - 0xA5, 0x30, 0x75, 0xAB, 0x4A, 0x32, 0x55, 0x77, - 0x33, 0x58, 0x6E, 0x82, 0x0F, 0xD3, 0x64, 0x23 - }, - { - 0x38, 0xF7, 0xC3, 0x40, 0xF4, 0xB1, 0x59, 0xB1, - 0xE5, 0x94, 0xF6, 0xEB, 0x83, 0x28, 0x49, 0x17, - 0xB7, 0xAA, 0x19, 0xC7, 0x4F, 0x57, 0x11, 0x7A, - 0x4E, 0x08, 0xCF, 0x7C, 0x4E, 0x32, 0xA2, 0x3C - }, - { - 0x1C, 0x67, 0x4B, 0xE2, 0x57, 0xE9, 0xB3, 0x31, - 0x34, 0xD4, 0x16, 0x8F, 0x15, 0x2F, 0x8B, 0x63, - 0xDF, 0xD7, 0x80, 0xC9, 0x7D, 0xC4, 0xDC, 0x37, - 0xAC, 0x26, 0xCC, 0x0A, 0xEF, 0xB7, 0x9C, 0x1A - }, - { - 0x2F, 0x0C, 0x59, 0x76, 0x16, 0xD5, 0x75, 0x17, - 0x14, 0xA5, 0xFB, 0x4E, 0xBF, 0x3C, 0x48, 0x1A, - 0x96, 0xC3, 0xAD, 0x14, 0x5E, 0xBD, 0xE0, 0x65, - 0x09, 0xF3, 0xA2, 0xE5, 0xF2, 0xC1, 0x3F, 0xC8 - }, - { - 0xFD, 0xDC, 0x69, 0xE0, 0xC9, 0x83, 0xCD, 0x82, - 0x83, 0xED, 0x81, 0x88, 0xBE, 0xC4, 0xE5, 0xF4, - 0x1D, 0xEA, 0x3D, 0x01, 0xB9, 0xE7, 0x4C, 0x4B, - 0xAF, 0x73, 0x41, 0xD8, 0xB4, 0xBF, 0x55, 0x3D - }, - { - 0x24, 0xD0, 0x83, 0xCB, 0xA0, 0x38, 0xC8, 0x7E, - 0x9A, 0xCB, 0x86, 0x81, 0x82, 0x02, 0x08, 0xB7, - 0x5C, 0xB3, 0x29, 0x3A, 0x96, 0xC9, 0xEF, 0xA7, - 0x5D, 0x2C, 0x63, 0xF1, 0x6B, 0x85, 0xFE, 0x1E - }, - { - 0x7F, 0x6A, 0x64, 0x9C, 0xCA, 0x89, 0xB2, 0x53, - 0xFF, 0xBD, 0x20, 0xC0, 0x16, 0x98, 0x01, 0x00, - 0xA8, 0x7C, 0x16, 0x81, 0x09, 0x62, 0x8F, 0xCC, - 0x66, 0x52, 0x5D, 0x8B, 0xAA, 0xFE, 0x50, 0x5F - }, - { - 0x6D, 0xA3, 0x73, 0xB4, 0xC1, 0x87, 0x92, 0xB3, - 0x20, 0x9A, 0xDD, 0x15, 0xA5, 0x07, 0x4A, 0x1D, - 0x70, 0xC1, 0x0B, 0xB3, 0x94, 0x80, 0xCA, 0x3F, - 0xE5, 0xC4, 0x39, 0xD9, 0x5F, 0xC2, 0x86, 0xCA - }, - { - 0x27, 0x0A, 0xFF, 0xA6, 0x42, 0x6F, 0x1A, 0x51, - 0x5C, 0x9B, 0x76, 0xDF, 0xC2, 0x7D, 0x18, 0x1F, - 0xC2, 0xFD, 0x57, 0xD0, 0x82, 0xA3, 0xBA, 0x2C, - 0x1E, 0xEF, 0x07, 0x15, 0x33, 0xA6, 0xDF, 0xB7 - }, - { - 0xC2, 0x2E, 0x15, 0xCF, 0xC5, 0xA3, 0xD1, 0x4B, - 0x64, 0xD1, 0x31, 0xF3, 0x5F, 0xB3, 0x5D, 0xD5, - 0xE6, 0xC5, 0x7D, 0xC4, 0xAF, 0xC5, 0x52, 0x27, - 0x75, 0x01, 0xEC, 0xA7, 0x64, 0xDA, 0x74, 0xBF - }, - { - 0xAD, 0x68, 0x3E, 0x96, 0xB8, 0xAC, 0x65, 0x8C, - 0x4F, 0x3F, 0x10, 0xAD, 0x22, 0xD9, 0x9B, 0x07, - 0xCB, 0x5E, 0xF9, 0xE3, 0x1C, 0xBE, 0x11, 0xE7, - 0xF7, 0xDC, 0x29, 0xF2, 0xAE, 0xE5, 0x02, 0x4C - }, - { - 0x78, 0xD3, 0xCE, 0xDA, 0x1C, 0xE0, 0x52, 0x93, - 0xF4, 0x30, 0xF6, 0x16, 0x7B, 0x33, 0xC9, 0x9F, - 0x0B, 0x1D, 0x6D, 0xAD, 0xE5, 0x21, 0x43, 0xC2, - 0x92, 0x55, 0x77, 0xC0, 0xBA, 0x82, 0x53, 0xEB - }, - { - 0xE0, 0x06, 0x45, 0x63, 0x44, 0xF9, 0x0F, 0x50, - 0x1C, 0x25, 0x81, 0x3F, 0x9B, 0xE2, 0xA3, 0xF4, - 0x0B, 0x98, 0x74, 0xFA, 0x05, 0x63, 0x98, 0x1C, - 0xD4, 0x56, 0xEE, 0x8D, 0x44, 0x80, 0x7C, 0x93 - }, - { - 0x39, 0x08, 0xE8, 0xD5, 0x47, 0xC0, 0xAF, 0xB1, - 0x13, 0x49, 0x49, 0x46, 0x63, 0x04, 0xA1, 0x45, - 0x02, 0x7E, 0x6B, 0xB7, 0xA7, 0x4D, 0xD1, 0xC1, - 0x62, 0xCD, 0xF0, 0xBC, 0xF7, 0x72, 0x37, 0xE8 - }, - { - 0x1B, 0x6C, 0x87, 0xA3, 0x48, 0x38, 0xC7, 0xCD, - 0x5F, 0xD0, 0x89, 0x14, 0x22, 0x4E, 0x90, 0xC2, - 0x2A, 0xBF, 0x5A, 0x97, 0xB1, 0x06, 0x46, 0xD9, - 0x8C, 0x49, 0x16, 0xD3, 0xA8, 0x93, 0x9E, 0x62 - }, - { - 0xB0, 0xD3, 0x8F, 0x82, 0xF2, 0x48, 0x91, 0x69, - 0x52, 0xB3, 0x16, 0xB6, 0xD3, 0x6D, 0x9E, 0x02, - 0x2D, 0xF6, 0xEE, 0xCC, 0x26, 0xC7, 0x62, 0xA6, - 0x55, 0xCF, 0x5F, 0x0A, 0xE6, 0x49, 0xE2, 0xBD - }, - { - 0x8D, 0x66, 0xFC, 0x9C, 0xED, 0xA5, 0xED, 0xDF, - 0xB1, 0xE0, 0x4D, 0x09, 0x6C, 0xA7, 0x0E, 0xF5, - 0x06, 0x50, 0xFB, 0x87, 0xCC, 0x6A, 0x9F, 0xFB, - 0xB3, 0xD2, 0x0B, 0xCE, 0x7B, 0x5A, 0x60, 0x74 - }, - { - 0x06, 0x43, 0x54, 0xE8, 0xE1, 0x1C, 0xF7, 0x13, - 0xB2, 0xC7, 0x2B, 0xA6, 0x7A, 0xC7, 0xD7, 0x6E, - 0x41, 0xBA, 0x61, 0xDB, 0x9C, 0x2D, 0xEA, 0x52, - 0x2E, 0x0B, 0xDA, 0x17, 0xCB, 0xA5, 0xE3, 0x92 - }, - { - 0xC8, 0xEF, 0x5F, 0x49, 0x8B, 0xD1, 0xBC, 0x70, - 0x7F, 0xBC, 0x7B, 0x5C, 0xBC, 0x2D, 0xFF, 0x04, - 0x93, 0x14, 0x4A, 0xC5, 0x27, 0x86, 0xDB, 0x3C, - 0x79, 0x3E, 0xF4, 0xAE, 0x8A, 0x83, 0x88, 0x47 - }, - { - 0x8A, 0x23, 0x97, 0xDF, 0x31, 0xE7, 0xF0, 0xCC, - 0x29, 0x0D, 0xA9, 0xA8, 0xBB, 0xE4, 0xF5, 0xF7, - 0xA3, 0xA1, 0x37, 0x50, 0x73, 0x0D, 0xB6, 0x2D, - 0xC2, 0x54, 0x0F, 0xDB, 0xD6, 0x18, 0x85, 0x89 - }, - { - 0xF1, 0x2D, 0x0B, 0x13, 0xC6, 0xAD, 0xFB, 0x3B, - 0xE5, 0x0A, 0x51, 0xEB, 0x6B, 0xAF, 0x65, 0xAB, - 0xFB, 0x17, 0x00, 0xBA, 0xA8, 0x7E, 0x52, 0x7D, - 0xBE, 0x3E, 0x67, 0x5A, 0x7A, 0x99, 0x46, 0x61 - }, - { - 0x10, 0x24, 0xC9, 0x40, 0xBE, 0x73, 0x41, 0x44, - 0x9B, 0x50, 0x10, 0x52, 0x2B, 0x50, 0x9F, 0x65, - 0xBB, 0xDC, 0x12, 0x87, 0xB4, 0x55, 0xC2, 0xBB, - 0x7F, 0x72, 0xB2, 0xC9, 0x2F, 0xD0, 0xD1, 0x89 - }, - { - 0x52, 0x60, 0x3B, 0x6C, 0xBF, 0xAD, 0x49, 0x66, - 0xCB, 0x04, 0x4C, 0xB2, 0x67, 0x56, 0x83, 0x85, - 0xCF, 0x35, 0xF2, 0x1E, 0x6C, 0x45, 0xCF, 0x30, - 0xAE, 0xD1, 0x98, 0x32, 0xCB, 0x51, 0xE9, 0xF5 - }, - { - 0xFF, 0xF2, 0x4D, 0x3C, 0xC7, 0x29, 0xD3, 0x95, - 0xDA, 0xF9, 0x78, 0xB0, 0x15, 0x73, 0x06, 0xCB, - 0x49, 0x57, 0x97, 0xE6, 0xC8, 0xDC, 0xA1, 0x73, - 0x1D, 0x2F, 0x6F, 0x81, 0xB8, 0x49, 0xBA, 0xAE - }, - { - 0x41, 0xEE, 0xE9, 0x0D, 0x47, 0xEC, 0x27, 0x72, - 0xCD, 0x35, 0x2D, 0xFD, 0x67, 0xE0, 0x60, 0x5F, - 0xBD, 0xFC, 0x5F, 0xD6, 0xD8, 0x26, 0x45, 0x1E, - 0x3D, 0x06, 0x4D, 0x38, 0x28, 0xBD, 0x3B, 0xAE - }, - { - 0x30, 0x0B, 0x6B, 0x36, 0xE5, 0x9F, 0x85, 0x1D, - 0xDD, 0xC2, 0x9B, 0xFA, 0x93, 0x08, 0x25, 0x20, - 0xCD, 0x77, 0xC5, 0x1E, 0x00, 0x7E, 0x00, 0xD2, - 0xD7, 0x8B, 0x26, 0xF4, 0xAF, 0x96, 0x15, 0x32 - }, - { - 0x9E, 0xF3, 0x03, 0x14, 0x83, 0x4E, 0x40, 0x1C, - 0x87, 0x1A, 0x20, 0x04, 0xE3, 0x8D, 0x5C, 0xE3, - 0x2E, 0xD2, 0x8E, 0x11, 0x37, 0xF1, 0x97, 0x0F, - 0x4F, 0x43, 0x78, 0xC7, 0x37, 0x06, 0x76, 0x3D - }, - { - 0x3F, 0xBD, 0xCD, 0xE7, 0xB6, 0x43, 0x04, 0x02, - 0x5E, 0xC0, 0x58, 0x26, 0x09, 0x03, 0x1E, 0xC2, - 0x66, 0xD5, 0x0F, 0x56, 0x83, 0x5A, 0xE0, 0xCB, - 0x72, 0xD8, 0xCD, 0xB4, 0xCF, 0xAF, 0x44, 0x19 - }, - { - 0xE9, 0x0E, 0xAD, 0x3B, 0x98, 0x2B, 0x43, 0x5B, - 0x66, 0x36, 0x6A, 0x49, 0x6C, 0x3F, 0x8A, 0xE6, - 0x5B, 0x17, 0x61, 0x37, 0x00, 0xF5, 0x47, 0x67, - 0x3F, 0x62, 0x15, 0x35, 0x41, 0x91, 0x28, 0x64 - }, - { - 0xAB, 0xE3, 0x54, 0x7B, 0x33, 0x6D, 0x6E, 0x24, - 0x0D, 0x7F, 0xE6, 0x82, 0xD7, 0x4B, 0x9C, 0xC7, - 0xE8, 0xD7, 0xF9, 0xB5, 0x66, 0x48, 0x58, 0xB9, - 0x4D, 0xF5, 0x9E, 0x9F, 0xC3, 0x30, 0xD9, 0xE5 - }, - { - 0xB2, 0x99, 0x64, 0x20, 0x95, 0xB8, 0x28, 0x6C, - 0x52, 0x1C, 0xDB, 0x21, 0xED, 0x0F, 0xE0, 0x57, - 0x27, 0x80, 0x21, 0xBB, 0x40, 0x38, 0xEB, 0x5A, - 0x3D, 0x79, 0x54, 0x2F, 0x5D, 0x75, 0x1F, 0x54 - }, - { - 0xE4, 0xD7, 0x58, 0x35, 0x9F, 0x08, 0x67, 0x93, - 0xA8, 0x37, 0x54, 0xAC, 0xA6, 0x96, 0x8C, 0x3E, - 0x9F, 0xD9, 0x4B, 0x40, 0x49, 0x7F, 0x2E, 0xC2, - 0x24, 0xA2, 0x91, 0x60, 0x63, 0xA2, 0x14, 0xA3 - }, - { - 0x59, 0xA3, 0x04, 0xFC, 0x03, 0xAB, 0x75, 0xD5, - 0x57, 0xDB, 0x04, 0xEB, 0xD0, 0x2D, 0xD4, 0xC6, - 0xB8, 0x10, 0xA1, 0x38, 0xBB, 0xFE, 0xEA, 0x5D, - 0xFC, 0xEE, 0xAA, 0x2B, 0x75, 0xB0, 0x64, 0x91 - }, - { - 0x39, 0x95, 0x10, 0x22, 0x15, 0xF5, 0xFE, 0x92, - 0x10, 0xEB, 0x30, 0xD9, 0x52, 0xD8, 0xC9, 0x19, - 0x58, 0x9E, 0x71, 0x45, 0xFC, 0xD4, 0x95, 0xEA, - 0x78, 0xD0, 0x2B, 0x9C, 0x14, 0x8F, 0xAF, 0x09 - }, - { - 0x47, 0x2E, 0xE7, 0x11, 0x56, 0x35, 0x06, 0xA5, - 0xF0, 0x08, 0x3F, 0xE8, 0x2B, 0x08, 0xB9, 0x92, - 0x3C, 0xF6, 0xC8, 0x40, 0x4D, 0x0C, 0xBA, 0xCB, - 0xF8, 0x48, 0x64, 0xF6, 0x48, 0x54, 0x2A, 0xC0 - }, - { - 0x68, 0xFD, 0xB8, 0x2A, 0xDA, 0xE7, 0x9B, 0xEF, - 0x59, 0x0A, 0xBA, 0x62, 0xD7, 0xAC, 0x55, 0x32, - 0x12, 0x06, 0x1C, 0x36, 0xE3, 0x6F, 0x12, 0xC0, - 0xEF, 0xA2, 0x9A, 0x17, 0x62, 0xDE, 0x3B, 0x6A - }, - { - 0x75, 0x85, 0xC0, 0x77, 0x33, 0x83, 0xF1, 0x74, - 0xFD, 0x66, 0x65, 0x49, 0xA8, 0x35, 0x2B, 0x30, - 0x5B, 0xF6, 0x85, 0x5B, 0xC9, 0x8B, 0xEA, 0x28, - 0xC3, 0x91, 0xB3, 0xC0, 0x34, 0xDA, 0x5A, 0x5A - }, - { - 0xAC, 0xC5, 0x75, 0xFE, 0x2C, 0xD7, 0xBA, 0x2A, - 0x31, 0xFC, 0x7D, 0x67, 0x0A, 0x92, 0x34, 0xAF, - 0x68, 0x50, 0x33, 0x86, 0xE9, 0x59, 0x07, 0x3D, - 0x16, 0xA8, 0x1B, 0x33, 0xB9, 0x22, 0xB5, 0x0E - }, - { - 0x9E, 0xC7, 0xD2, 0x99, 0x59, 0x43, 0xD3, 0x9D, - 0x6B, 0x97, 0x14, 0x93, 0xB8, 0x97, 0xA0, 0xEE, - 0x2D, 0x33, 0x92, 0xA7, 0x2D, 0xB8, 0x75, 0xC2, - 0x40, 0x5D, 0x35, 0x71, 0x78, 0xFB, 0x69, 0x11 - }, - { - 0x2D, 0x7E, 0xF1, 0x94, 0x01, 0x42, 0x5A, 0xBA, - 0x45, 0x0E, 0x82, 0xD3, 0x6D, 0x0F, 0xE7, 0xB2, - 0x08, 0x5E, 0xA0, 0xAF, 0x60, 0x45, 0xA5, 0x99, - 0x4C, 0xF4, 0x31, 0xEA, 0x59, 0x93, 0x9C, 0xC9 - }, - { - 0xF3, 0x2F, 0xD8, 0x55, 0xF0, 0x11, 0xC7, 0x18, - 0x02, 0x7F, 0x2E, 0xBE, 0x37, 0x7D, 0x69, 0x39, - 0xF1, 0x23, 0x70, 0xCA, 0xFF, 0x15, 0x1C, 0x1E, - 0x5A, 0xCE, 0x43, 0x8D, 0x70, 0x3C, 0x6D, 0x9F - }, - { - 0xB2, 0xBD, 0x83, 0xD2, 0x31, 0x0D, 0x3D, 0x7B, - 0x1D, 0x2D, 0x5A, 0xAF, 0x43, 0x59, 0xFA, 0xE2, - 0x86, 0x12, 0x96, 0x27, 0x19, 0xFD, 0xDE, 0x4D, - 0xDA, 0xF6, 0x9E, 0x78, 0x20, 0xF3, 0x3F, 0x61 - }, - { - 0x1A, 0x7A, 0x9D, 0x0F, 0x44, 0xDD, 0xFA, 0x7F, - 0xC2, 0xF4, 0x77, 0x0C, 0xAD, 0x74, 0x22, 0xFA, - 0x6C, 0x4E, 0x37, 0xE6, 0xCB, 0x03, 0x6D, 0x89, - 0x9E, 0x10, 0x27, 0x50, 0xE5, 0x94, 0xFF, 0xCD - }, - { - 0xDC, 0x69, 0xF6, 0x14, 0x1C, 0x8E, 0x10, 0x3F, - 0xF6, 0x1F, 0x62, 0x98, 0xA2, 0xC4, 0x4F, 0x52, - 0xD1, 0x47, 0x36, 0x6D, 0xDB, 0xD9, 0xC7, 0x9C, - 0xC3, 0x08, 0xFE, 0x84, 0x33, 0x6A, 0x95, 0x64 - }, - { - 0xE3, 0x4E, 0xD4, 0x17, 0xB0, 0x79, 0x1D, 0x9A, - 0x77, 0xEE, 0x1E, 0x50, 0xCC, 0x2C, 0x20, 0x7E, - 0x54, 0x0C, 0x77, 0x14, 0x04, 0x21, 0xC4, 0x6C, - 0xE0, 0x86, 0x28, 0x78, 0xAA, 0xEB, 0x27, 0x09 - }, - { - 0x21, 0x74, 0x42, 0x5C, 0x8C, 0xCA, 0xE3, 0x98, - 0xC4, 0xFF, 0x06, 0xF8, 0x48, 0x99, 0x1C, 0x5E, - 0x9B, 0xC0, 0xF3, 0x46, 0x11, 0x11, 0x70, 0x6F, - 0xB9, 0x5D, 0x0B, 0xE1, 0xC6, 0x8E, 0x47, 0x60 - }, - { - 0x18, 0x94, 0x58, 0x2A, 0x8A, 0x25, 0xFE, 0x8F, - 0x84, 0x7A, 0x4A, 0x03, 0x25, 0x74, 0xB7, 0x7B, - 0x8B, 0x36, 0xBF, 0x19, 0x99, 0x75, 0x26, 0xBB, - 0x4B, 0xC8, 0x5F, 0x38, 0x24, 0x53, 0x7F, 0xEB - }, - { - 0x17, 0xED, 0x18, 0x8A, 0xE3, 0xC9, 0x53, 0xD6, - 0x55, 0x44, 0x59, 0x83, 0xB8, 0x32, 0x5B, 0xAF, - 0xFF, 0x32, 0xE2, 0x22, 0xB2, 0xDF, 0xEB, 0x16, - 0xE8, 0x61, 0x7A, 0xBF, 0x86, 0xEE, 0x7C, 0xC5 - }, - { - 0xF1, 0x48, 0x9A, 0xD1, 0xC3, 0x54, 0xCD, 0xE9, - 0x78, 0x92, 0x37, 0xEA, 0x6D, 0xBF, 0x67, 0xFC, - 0x1E, 0x44, 0xD1, 0xAC, 0xC8, 0xDC, 0x66, 0xAD, - 0x83, 0x87, 0x27, 0xF4, 0x7D, 0x9A, 0x91, 0xFE - }, - { - 0x36, 0x7F, 0x22, 0x16, 0x5B, 0x8B, 0x66, 0xE9, - 0x7F, 0x66, 0x70, 0xF3, 0x4E, 0xBA, 0x27, 0x49, - 0xD2, 0x64, 0x3B, 0x21, 0xBE, 0xAD, 0xAD, 0xFE, - 0xFE, 0xA2, 0x57, 0x4B, 0x7C, 0x9B, 0x21, 0x96 - }, - { - 0x3D, 0x8D, 0xFE, 0xA1, 0x7E, 0xEA, 0x5D, 0x64, - 0x5A, 0xC1, 0xD4, 0x1A, 0x5B, 0x59, 0x22, 0x6C, - 0x48, 0x6C, 0x36, 0xBD, 0x77, 0xED, 0x44, 0xBB, - 0x34, 0x91, 0x70, 0xD0, 0x80, 0xE3, 0x0E, 0x68 - }, - { - 0x41, 0x15, 0xF8, 0x9E, 0x0B, 0x3B, 0x5C, 0x8F, - 0x61, 0x22, 0xC0, 0x25, 0x00, 0x17, 0x1D, 0xCF, - 0xFB, 0xCE, 0xA4, 0x66, 0x2A, 0x8C, 0x5F, 0x8C, - 0x1C, 0x01, 0xA9, 0xCA, 0x7B, 0x10, 0x27, 0xBB - }, - { - 0xED, 0x6E, 0x91, 0x0B, 0x96, 0x02, 0x55, 0xD7, - 0xD7, 0x92, 0xEB, 0xE6, 0x7F, 0x26, 0x0A, 0x14, - 0x3C, 0xFA, 0xC1, 0x05, 0x1D, 0xFC, 0x05, 0x90, - 0x25, 0xEE, 0x0C, 0x1B, 0xFC, 0xBC, 0x56, 0x81 - }, - { - 0x55, 0x8F, 0xA8, 0xAF, 0xA1, 0x2B, 0xBE, 0xE5, - 0x4A, 0xF7, 0x8F, 0x6B, 0x74, 0x45, 0xF9, 0x96, - 0x65, 0xD4, 0xE3, 0x56, 0xBC, 0x07, 0xD3, 0xEF, - 0xFD, 0x8F, 0xD6, 0x5A, 0xB9, 0xC7, 0x47, 0x16 - }, - { - 0x5B, 0x60, 0x12, 0x76, 0x20, 0x53, 0xB8, 0x73, - 0x4A, 0xF0, 0xE5, 0x55, 0xE6, 0xA2, 0xBB, 0x4F, - 0xD4, 0x84, 0x0A, 0xF3, 0xB0, 0x4F, 0xCF, 0x63, - 0x50, 0xA2, 0xB8, 0xA5, 0x1B, 0x67, 0x96, 0xAD - }, - { - 0xAB, 0x7A, 0xCC, 0xA5, 0xD7, 0x77, 0x10, 0xBA, - 0xD3, 0x7B, 0xA0, 0xFF, 0x4C, 0xEA, 0xE2, 0x7E, - 0x84, 0x71, 0x79, 0xF7, 0xFD, 0x7A, 0xEC, 0x88, - 0x69, 0xC6, 0x49, 0xB3, 0x3F, 0x8D, 0x25, 0x77 - }, - { - 0xFF, 0x77, 0x30, 0xB4, 0x74, 0xEC, 0x21, 0x45, - 0xA9, 0x2D, 0xD1, 0xCF, 0xFE, 0x45, 0xC3, 0x42, - 0xC6, 0xFD, 0x6B, 0xAC, 0x58, 0x0F, 0xF9, 0x5A, - 0x75, 0xED, 0xA3, 0xBF, 0x90, 0xEB, 0x4F, 0x01 - }, - { - 0xD1, 0x0F, 0x06, 0x1D, 0x5B, 0x9C, 0xB4, 0x4E, - 0xE0, 0x78, 0xA9, 0x6B, 0x33, 0x18, 0x57, 0x9E, - 0x5E, 0xF5, 0x0A, 0xEF, 0x3E, 0xD9, 0x6E, 0x4F, - 0x62, 0x14, 0x9B, 0x2E, 0x9F, 0x7C, 0x66, 0x0C - }, - { - 0x67, 0xD2, 0x2B, 0x8E, 0xDF, 0x20, 0x01, 0xD8, - 0x64, 0x22, 0x13, 0x6A, 0xC6, 0x51, 0x6C, 0xF3, - 0x9F, 0x7F, 0xC6, 0xA7, 0x02, 0x98, 0x92, 0xFD, - 0x75, 0xC9, 0x87, 0x90, 0x96, 0x4A, 0x72, 0x0B - }, - { - 0x7A, 0x5E, 0xC5, 0xBA, 0x76, 0x25, 0x9B, 0x07, - 0xB4, 0xDA, 0x03, 0xF3, 0x81, 0xFE, 0x7B, 0xEA, - 0x48, 0x65, 0xC8, 0x6C, 0x42, 0x4A, 0xBA, 0xA0, - 0xDD, 0x1E, 0xCF, 0x74, 0xF8, 0x7D, 0x2A, 0xC0 - }, - { - 0xE0, 0xFF, 0x60, 0xD6, 0x90, 0x29, 0xE6, 0xBD, - 0x1C, 0x15, 0x95, 0x3E, 0x91, 0x50, 0x9C, 0x0C, - 0x59, 0xED, 0x5D, 0xA5, 0x00, 0x01, 0x99, 0xF2, - 0x16, 0xD2, 0x9F, 0x96, 0x07, 0x9C, 0x2F, 0xEF - }, - { - 0xFC, 0x13, 0xEA, 0xD8, 0x41, 0x01, 0x8F, 0x59, - 0x90, 0x3B, 0x40, 0xF2, 0x02, 0x0C, 0x66, 0x38, - 0xA6, 0x6A, 0x54, 0xC3, 0xA3, 0x38, 0x41, 0x4D, - 0x97, 0xA5, 0xC3, 0x94, 0xF3, 0x26, 0x6F, 0x33 - }, - { - 0x0C, 0x2F, 0x62, 0xB8, 0x98, 0xFB, 0x2F, 0x63, - 0x61, 0x7E, 0x78, 0x73, 0x45, 0x26, 0x3C, 0xB9, - 0xCF, 0x60, 0x65, 0x4B, 0x55, 0x3B, 0x20, 0x3E, - 0xE4, 0x9D, 0xCB, 0xB8, 0xF2, 0xA6, 0xAF, 0xAC - }, - { - 0xD7, 0xD6, 0xCB, 0x55, 0x2A, 0xEB, 0x36, 0xEB, - 0x96, 0xB1, 0xD5, 0xE0, 0x52, 0xF8, 0xD9, 0x21, - 0xC3, 0x24, 0x5A, 0x97, 0x0D, 0x0B, 0xC8, 0x41, - 0x0C, 0xD6, 0x5E, 0xA1, 0x04, 0xC8, 0xE7, 0x79 - }, - { - 0xB7, 0x14, 0x1F, 0x30, 0x5E, 0xFD, 0xFE, 0xE5, - 0x56, 0xBD, 0x13, 0xE0, 0x40, 0x0D, 0x1E, 0x8C, - 0xFD, 0x65, 0x48, 0xBF, 0x81, 0xEE, 0x5D, 0x15, - 0x32, 0x7E, 0x49, 0x95, 0xCA, 0x8A, 0xD6, 0xFD - }, - { - 0xB6, 0xB6, 0x38, 0xD2, 0x2B, 0x7A, 0x12, 0x82, - 0x53, 0x74, 0xF7, 0x03, 0x48, 0xD7, 0x44, 0x8D, - 0x4E, 0x7D, 0x90, 0x8C, 0xF6, 0xE7, 0xBB, 0xEF, - 0x8C, 0x93, 0xEF, 0x67, 0x9B, 0x2A, 0x54, 0x78 - }, - { - 0x0D, 0xF4, 0x58, 0x56, 0x41, 0xFA, 0x09, 0xF6, - 0xCB, 0xA4, 0xCC, 0x16, 0x5A, 0x10, 0xAD, 0xDE, - 0x34, 0xF8, 0x0D, 0x42, 0x5A, 0x70, 0xDB, 0x67, - 0xE2, 0xFD, 0x23, 0x7B, 0x62, 0x7F, 0x43, 0x8A - }, - { - 0x10, 0x6B, 0x2B, 0x35, 0x4D, 0x95, 0xAC, 0xEC, - 0xD0, 0xD9, 0x58, 0x8F, 0xBC, 0x23, 0x1F, 0x8B, - 0xEA, 0x2E, 0x94, 0xEA, 0x66, 0x2D, 0xDD, 0x3F, - 0x13, 0x9E, 0x1B, 0x67, 0x87, 0x46, 0x1E, 0xED - }, - { - 0xAE, 0x5C, 0x69, 0xEE, 0xFE, 0x90, 0x89, 0xB2, - 0x9C, 0x6C, 0x1A, 0x23, 0x70, 0xD2, 0x05, 0x52, - 0xBA, 0x40, 0xC3, 0xD5, 0xE3, 0x71, 0x3C, 0x12, - 0xDE, 0xFC, 0xAE, 0x99, 0x7F, 0x43, 0x3E, 0xCD - }, - { - 0x1A, 0xAE, 0xF5, 0x5D, 0x4F, 0xA8, 0x92, 0xB6, - 0x35, 0xFB, 0x2A, 0x7A, 0x25, 0xF9, 0xA8, 0xE0, - 0x3B, 0x9F, 0xFB, 0x08, 0x2A, 0xE9, 0xC0, 0x7C, - 0x20, 0x42, 0xA0, 0x49, 0xC6, 0x51, 0x5E, 0x45 - }, - { - 0x29, 0x7D, 0xAA, 0xC4, 0xD5, 0x4D, 0xC4, 0x1C, - 0x83, 0xE3, 0x23, 0x94, 0x59, 0x9F, 0x17, 0x1C, - 0xDA, 0xA9, 0xDD, 0xB7, 0x17, 0x26, 0xDA, 0x4E, - 0xCE, 0x3C, 0xCF, 0x95, 0xC1, 0x1F, 0x56, 0xDF - }, - { - 0x2C, 0x45, 0xAC, 0xF4, 0x91, 0xEC, 0x2F, 0x4B, - 0x7E, 0x30, 0x9E, 0x7E, 0xDD, 0x81, 0x5B, 0xE5, - 0xA5, 0x4C, 0x44, 0x58, 0xD1, 0xA5, 0x7C, 0x4F, - 0x9B, 0x76, 0x3B, 0x0C, 0x67, 0x18, 0xD4, 0x3E - }, - { - 0x2F, 0x92, 0xF9, 0x01, 0x70, 0xD3, 0xAE, 0x95, - 0xAB, 0xFA, 0xC3, 0xA6, 0x98, 0x9A, 0x2A, 0x60, - 0xCB, 0x28, 0xB8, 0x58, 0x78, 0x2B, 0xE7, 0xEA, - 0x17, 0x9B, 0x48, 0xA7, 0x27, 0x6D, 0xD8, 0x60 - }, - { - 0xB4, 0x01, 0xE8, 0x4B, 0x15, 0xAC, 0xC4, 0x70, - 0x93, 0x6D, 0x6E, 0x37, 0xF7, 0x88, 0x83, 0x33, - 0x09, 0x27, 0x31, 0x13, 0x3B, 0x25, 0x1B, 0xEA, - 0x22, 0x16, 0x58, 0xCA, 0x19, 0xA7, 0x56, 0x69 - }, - { - 0xF8, 0xB3, 0x40, 0xD2, 0xB9, 0xB3, 0x3D, 0x43, - 0xA0, 0xA6, 0x6F, 0x34, 0x97, 0x82, 0x0A, 0xFA, - 0xAE, 0xE4, 0x34, 0xC4, 0xE3, 0xC0, 0xC1, 0x7E, - 0x89, 0x8B, 0x83, 0x01, 0xC5, 0x7A, 0x26, 0xBD - }, - { - 0x56, 0x6D, 0xA2, 0x83, 0x99, 0x03, 0x89, 0x13, - 0x8A, 0xA6, 0xF2, 0xAA, 0xA3, 0xB9, 0xE4, 0x0C, - 0xBF, 0x90, 0x84, 0x0E, 0xC7, 0x62, 0xBD, 0x96, - 0xB7, 0xE3, 0x3A, 0x31, 0x13, 0xB1, 0x01, 0x08 - }, - { - 0x34, 0x06, 0x72, 0xB7, 0x04, 0x67, 0x60, 0x42, - 0xC9, 0xBF, 0x3F, 0x33, 0x7B, 0xA7, 0x9F, 0x11, - 0x33, 0x6A, 0xEB, 0xB5, 0xEC, 0x5D, 0x31, 0xDF, - 0x54, 0xEB, 0x6A, 0xD3, 0xB0, 0x43, 0x04, 0x42 - }, - { - 0x50, 0x50, 0xB7, 0x3B, 0x93, 0x16, 0xEE, 0xA2, - 0xF1, 0x49, 0xBF, 0xFD, 0x22, 0xAE, 0xE3, 0x84, - 0xDC, 0x54, 0x03, 0xB1, 0x8E, 0x16, 0xFA, 0x88, - 0x82, 0x5E, 0x18, 0x16, 0x09, 0x49, 0x6F, 0xD2 - }, - { - 0x13, 0x65, 0xCC, 0x6F, 0xB9, 0x26, 0x0E, 0x86, - 0x88, 0x9B, 0x3A, 0xFB, 0xD1, 0xC8, 0xBC, 0x12, - 0x92, 0x31, 0x97, 0x71, 0x5D, 0xB2, 0x66, 0xCC, - 0x7A, 0x01, 0xCA, 0x57, 0x15, 0x9F, 0x75, 0x96 - }, - { - 0x29, 0x46, 0x6F, 0x51, 0xC0, 0x11, 0xFD, 0x10, - 0x18, 0x14, 0x94, 0xA9, 0x37, 0x9B, 0x61, 0x59, - 0xB8, 0x08, 0xAE, 0x0F, 0xCB, 0x01, 0x61, 0xF8, - 0xF0, 0x79, 0x09, 0xFF, 0x04, 0x1B, 0x19, 0x65 - }, - { - 0x65, 0x91, 0xA3, 0xC3, 0xC7, 0x67, 0xB3, 0x8D, - 0x80, 0x5E, 0xD3, 0xF7, 0xEB, 0x67, 0x63, 0xE8, - 0xB3, 0xD2, 0xD6, 0x42, 0xE7, 0x30, 0x77, 0x45, - 0xCD, 0x34, 0x18, 0xEF, 0xF6, 0x9A, 0x19, 0xED - }, - { - 0x1D, 0x84, 0xB0, 0x4B, 0x13, 0x38, 0xB0, 0xD2, - 0xE3, 0xC9, 0x8F, 0x7A, 0xEA, 0x3E, 0x98, 0xEF, - 0xFC, 0x53, 0x0A, 0x50, 0x44, 0xB9, 0x3B, 0x96, - 0xC6, 0x7E, 0xE3, 0x79, 0xD6, 0x2E, 0x81, 0x5F - }, - { - 0x6F, 0xA2, 0x95, 0x27, 0x25, 0x32, 0xE9, 0x83, - 0xE1, 0x66, 0xB1, 0x2E, 0x49, 0x99, 0xC0, 0x52, - 0xF8, 0x9D, 0x9F, 0x30, 0xAE, 0x14, 0x81, 0xF3, - 0xD6, 0x0E, 0xAE, 0x85, 0xF8, 0xEE, 0x17, 0x8A - }, - { - 0x4E, 0xD8, 0xCA, 0xA9, 0x8E, 0xC3, 0x9F, 0x6A, - 0x62, 0x9F, 0x9A, 0x65, 0x4A, 0x44, 0x7E, 0x7E, - 0x3E, 0x4F, 0xAE, 0xEC, 0xF3, 0x4D, 0xCF, 0x65, - 0x8D, 0x2D, 0x4B, 0x98, 0xB7, 0xA2, 0xEC, 0x1A - }, - { - 0xCF, 0xAB, 0x82, 0x99, 0xA0, 0xDA, 0x0C, 0x2A, - 0x7E, 0x8F, 0xF5, 0x4D, 0x0A, 0x67, 0x6D, 0x14, - 0x1A, 0xB2, 0x6B, 0xC0, 0x01, 0x2E, 0x5F, 0x66, - 0x8E, 0x85, 0xD8, 0x14, 0xBC, 0x98, 0x88, 0xB0 - }, - { - 0xA6, 0x26, 0x54, 0x3C, 0x27, 0x1F, 0xCC, 0xC3, - 0xE4, 0x45, 0x0B, 0x48, 0xD6, 0x6B, 0xC9, 0xCB, - 0xDE, 0xB2, 0x5E, 0x5D, 0x07, 0x7A, 0x62, 0x13, - 0xCD, 0x90, 0xCB, 0xBD, 0x0F, 0xD2, 0x20, 0x76 - }, - { - 0x05, 0xCF, 0x3A, 0x90, 0x04, 0x91, 0x16, 0xDC, - 0x60, 0xEF, 0xC3, 0x15, 0x36, 0xAA, 0xA3, 0xD1, - 0x67, 0x76, 0x29, 0x94, 0x89, 0x28, 0x76, 0xDC, - 0xB7, 0xEF, 0x3F, 0xBE, 0xCD, 0x74, 0x49, 0xC0 - }, - { - 0xCC, 0xD6, 0x1C, 0x92, 0x6C, 0xC1, 0xE5, 0xE9, - 0x12, 0x8C, 0x02, 0x1C, 0x0C, 0x6E, 0x92, 0xAE, - 0xFC, 0x4F, 0xFB, 0xDE, 0x39, 0x4D, 0xD6, 0xF3, - 0xB7, 0xD8, 0x7A, 0x8C, 0xED, 0x89, 0x60, 0x14 - }, - { - 0x3F, 0xFA, 0x4F, 0x6D, 0xAF, 0xA5, 0x7F, 0x1C, - 0x50, 0xF1, 0xAF, 0xA4, 0xF8, 0x12, 0x92, 0xAE, - 0x71, 0xA0, 0x6F, 0xE4, 0xF8, 0xFF, 0x46, 0xC5, - 0x1D, 0x32, 0xFF, 0x26, 0x13, 0x48, 0x9F, 0x2B - }, - { - 0x19, 0xD3, 0x92, 0x1C, 0xFC, 0x0F, 0x1A, 0x2B, - 0xB8, 0x13, 0xB3, 0xDF, 0xA9, 0x6D, 0xF9, 0x0E, - 0x2C, 0x6B, 0x87, 0xD7, 0x8E, 0x92, 0x38, 0xF8, - 0x5B, 0xBC, 0x77, 0xAE, 0x9A, 0x73, 0xF9, 0x8F - }, - { - 0xF5, 0xC9, 0x16, 0xFF, 0x2B, 0xAD, 0xDE, 0x3E, - 0x29, 0xA5, 0xF9, 0x40, 0x23, 0x3E, 0xA3, 0x40, - 0x07, 0xD8, 0xF1, 0x82, 0xA4, 0x8A, 0x80, 0x8B, - 0x46, 0xBB, 0x80, 0x58, 0x00, 0x3F, 0x19, 0x03 - }, - { - 0x6B, 0xA0, 0x7A, 0x1A, 0xF7, 0x58, 0xE6, 0x82, - 0xD3, 0xE0, 0x9A, 0xDD, 0x2D, 0x3D, 0xCD, 0xF3, - 0x5D, 0x95, 0x53, 0xF6, 0x79, 0x98, 0x54, 0xA2, - 0x7E, 0x53, 0x60, 0x63, 0xC5, 0x7F, 0x81, 0xA5 - }, - { - 0xB7, 0x83, 0x78, 0xFB, 0x44, 0x6C, 0x54, 0x4B, - 0x04, 0xD4, 0xA1, 0x52, 0xAC, 0x49, 0x57, 0x31, - 0x61, 0xB3, 0xDD, 0xEB, 0xF6, 0x93, 0x86, 0x77, - 0x0A, 0x55, 0xA7, 0xD4, 0x7B, 0x88, 0x0E, 0x5D - }, - { - 0xB5, 0x19, 0x53, 0x8F, 0xE1, 0x62, 0x6F, 0x0C, - 0x59, 0x59, 0x45, 0xAD, 0xA5, 0x8A, 0x34, 0x4F, - 0xAA, 0xC0, 0x06, 0x17, 0x61, 0xCC, 0x9D, 0x4A, - 0x84, 0x14, 0x19, 0xBD, 0x32, 0xEE, 0xC0, 0xD9 - }, - { - 0x96, 0xE4, 0x88, 0xB0, 0x27, 0x89, 0x64, 0x13, - 0xF4, 0x03, 0x4B, 0x03, 0x54, 0xF4, 0x84, 0x84, - 0xF6, 0xCF, 0xC1, 0x0F, 0x8E, 0xC5, 0x7B, 0x02, - 0x6F, 0xD2, 0x1A, 0x3B, 0x88, 0x36, 0x1A, 0x74 - }, - { - 0x77, 0x0C, 0x8A, 0x5F, 0x47, 0xBF, 0xD7, 0x69, - 0xCE, 0xD3, 0x5A, 0x71, 0xAF, 0xC3, 0xCA, 0x1F, - 0xF4, 0xC1, 0xF1, 0xE7, 0xCC, 0x3D, 0x23, 0x56, - 0xDE, 0x94, 0x50, 0x04, 0x36, 0x8D, 0x81, 0x45 - }, - { - 0x6D, 0xF9, 0xD8, 0xD0, 0xD3, 0xA8, 0xD9, 0x8C, - 0x83, 0x50, 0xD7, 0x16, 0x2B, 0xD1, 0x55, 0x79, - 0xD5, 0x70, 0x7A, 0xDD, 0x76, 0x11, 0xA0, 0x0E, - 0xEB, 0x6C, 0xA5, 0x74, 0x3E, 0xD7, 0x8C, 0xB7 - }, - { - 0x4F, 0x0F, 0xE8, 0xFC, 0x17, 0x90, 0x15, 0x91, - 0xCF, 0x34, 0x87, 0x30, 0xE1, 0x87, 0xDE, 0x52, - 0x3D, 0x6D, 0x75, 0x68, 0xC1, 0xFB, 0xD8, 0x24, - 0x85, 0x91, 0x39, 0x85, 0xEB, 0x67, 0x97, 0x1C - }, - { - 0x0E, 0xF3, 0xBB, 0x35, 0xCF, 0x37, 0x2B, 0xD9, - 0x4E, 0x3F, 0x80, 0xEE, 0xCE, 0xBD, 0x50, 0xEF, - 0x0D, 0x03, 0x08, 0xE0, 0x1E, 0x0E, 0xD6, 0xDE, - 0x0F, 0x5A, 0x8A, 0x8C, 0x81, 0x8A, 0x00, 0x74 - }, - { - 0xC0, 0x38, 0xD3, 0xE8, 0x09, 0xA5, 0xE3, 0xA5, - 0x8D, 0xB2, 0xF9, 0x1C, 0x15, 0xAE, 0x12, 0x43, - 0x95, 0x78, 0xF7, 0x54, 0x85, 0xCD, 0x84, 0xF5, - 0x56, 0xC6, 0x97, 0x1E, 0x8E, 0x25, 0x06, 0x20 - }, - { - 0xCE, 0x39, 0x9A, 0x0F, 0x08, 0x27, 0x7D, 0x8D, - 0x48, 0x16, 0x09, 0x50, 0x60, 0xEB, 0xBF, 0x33, - 0xDA, 0x01, 0x6F, 0xB4, 0x3A, 0x6C, 0x35, 0x6D, - 0x5A, 0x3F, 0xE4, 0xBB, 0x57, 0x4C, 0x5E, 0x7B - }, - { - 0x86, 0x9F, 0x7E, 0x31, 0x6B, 0x19, 0x4F, 0x95, - 0x31, 0xBC, 0xAF, 0x33, 0xF7, 0x91, 0x3F, 0x1B, - 0x9C, 0xFC, 0x6B, 0xB5, 0xDC, 0xF8, 0x6B, 0x69, - 0x2B, 0xF8, 0xCA, 0xB2, 0x9B, 0x8A, 0xA9, 0x6F - }, - { - 0x32, 0x7D, 0xFA, 0x46, 0x44, 0x59, 0xD9, 0xE4, - 0x8F, 0x5E, 0x55, 0xC7, 0xF5, 0xBA, 0xA6, 0x8F, - 0xC4, 0xA2, 0x5A, 0xD6, 0x22, 0xBC, 0x7B, 0xF0, - 0x1A, 0xCA, 0x82, 0xFD, 0x5E, 0x72, 0x31, 0x4C - }, - { - 0xE0, 0x0D, 0xAD, 0x31, 0x51, 0xB9, 0x08, 0x5E, - 0xAE, 0x78, 0x69, 0x84, 0xFE, 0x20, 0x73, 0x52, - 0x32, 0xB7, 0xFF, 0x7F, 0x1B, 0x1D, 0xB7, 0x96, - 0x1F, 0xD0, 0xD0, 0xE0, 0xF6, 0x05, 0xDB, 0x9A - }, - { - 0x07, 0x6F, 0x64, 0x45, 0x20, 0xD0, 0xB4, 0x73, - 0x2D, 0x6C, 0x53, 0x1C, 0x93, 0x49, 0x08, 0x90, - 0x26, 0x93, 0x6D, 0x99, 0x82, 0x04, 0x61, 0xDA, - 0x87, 0x74, 0x9A, 0x52, 0x0F, 0xBE, 0x90, 0xCE - }, - { - 0xB4, 0x41, 0x4C, 0xA1, 0x37, 0x3B, 0xE4, 0x6F, - 0x15, 0xCE, 0xA6, 0xB1, 0x25, 0x5A, 0x7D, 0x18, - 0x86, 0xC6, 0xFD, 0xB0, 0x8E, 0xD5, 0xAF, 0x96, - 0x57, 0xD5, 0xAA, 0xC3, 0x17, 0xDE, 0x3A, 0x29 - }, - { - 0x8D, 0x1A, 0xB0, 0x26, 0x3D, 0xAB, 0x7B, 0x86, - 0xEC, 0xEE, 0x21, 0x91, 0x62, 0xD9, 0x99, 0xA0, - 0x12, 0x45, 0x57, 0x22, 0x69, 0xDE, 0x31, 0x10, - 0x0E, 0x5D, 0x88, 0xFC, 0x1B, 0x1E, 0xAA, 0x69 - }, - { - 0xB4, 0x8D, 0x1C, 0x1F, 0x83, 0x92, 0x4A, 0x02, - 0xA2, 0x3E, 0x5E, 0x0F, 0x97, 0x1E, 0x16, 0xE8, - 0x7F, 0xC4, 0x88, 0x48, 0x53, 0x83, 0x34, 0x85, - 0x19, 0x1A, 0x2B, 0x60, 0x72, 0x2F, 0xE2, 0x69 - }, - { - 0xF2, 0xED, 0xD5, 0xF7, 0x50, 0xA2, 0x0A, 0x54, - 0x1D, 0x3F, 0x6B, 0xD5, 0xDF, 0x80, 0x83, 0x8F, - 0x11, 0x82, 0x5B, 0x25, 0xA9, 0x8F, 0x3D, 0xA5, - 0xE1, 0x52, 0x3B, 0xFF, 0x81, 0x3B, 0xB5, 0x60 - }, - { - 0x07, 0x16, 0x60, 0x04, 0xEF, 0x88, 0xE1, 0x61, - 0x4E, 0xBD, 0xC8, 0x87, 0xDF, 0xC7, 0xDA, 0x42, - 0xEB, 0xCD, 0xA0, 0x2D, 0x92, 0xC1, 0x2F, 0x18, - 0xD1, 0x18, 0x6C, 0xE3, 0xC9, 0x87, 0x10, 0xE4 - }, - { - 0x69, 0xF8, 0x3A, 0xA1, 0x01, 0xD6, 0x9B, 0x8F, - 0x12, 0x20, 0xDC, 0x1C, 0x53, 0x8D, 0x89, 0x34, - 0x45, 0x84, 0x20, 0xBE, 0x33, 0x5F, 0xEB, 0x46, - 0xFF, 0xC4, 0x7A, 0x2C, 0x8E, 0x2E, 0x6A, 0x8A - }, - { - 0xE1, 0x46, 0x9F, 0x16, 0xC6, 0xFC, 0xA1, 0x51, - 0x19, 0xA2, 0x72, 0xE5, 0x85, 0xC7, 0xF5, 0x04, - 0x21, 0xBC, 0x8A, 0x41, 0x4C, 0x86, 0x4F, 0xC7, - 0x6B, 0x01, 0x04, 0x8D, 0x4C, 0x6F, 0xC5, 0xD2 - }, - { - 0x67, 0x63, 0x34, 0x3A, 0x1C, 0x80, 0xF1, 0x92, - 0x83, 0xA8, 0x0A, 0xF8, 0x54, 0xE7, 0xE9, 0x06, - 0x5C, 0x2A, 0x83, 0x49, 0xEF, 0x11, 0xF1, 0x1B, - 0xFB, 0x76, 0xBA, 0x9F, 0x97, 0x04, 0x85, 0x39 - }, - { - 0x1A, 0xE3, 0xA0, 0xB8, 0xB2, 0xC7, 0x88, 0x5B, - 0xA3, 0x18, 0xAD, 0x6F, 0xD4, 0x49, 0xFC, 0x4D, - 0x7F, 0x84, 0x04, 0xB5, 0x9C, 0xF3, 0x27, 0x5F, - 0xCD, 0xEA, 0x13, 0x56, 0x34, 0x25, 0x77, 0x2D - }, - { - 0x3A, 0x71, 0x18, 0x4C, 0xBE, 0x8E, 0xB5, 0x8E, - 0x68, 0x12, 0xBA, 0x7A, 0x7A, 0x1D, 0xCA, 0x0C, - 0xA2, 0x8E, 0xEC, 0x63, 0x78, 0x2F, 0x2E, 0x6E, - 0x3C, 0x0B, 0x87, 0x07, 0x3F, 0x53, 0x3F, 0xFD - }, - { - 0x18, 0x4C, 0xCF, 0x2A, 0x52, 0xF3, 0x88, 0xC9, - 0xF8, 0x97, 0xA8, 0x57, 0xFE, 0x7C, 0xCE, 0xC2, - 0x95, 0x99, 0x11, 0xA8, 0xD1, 0xE0, 0x9E, 0xE8, - 0x80, 0x4D, 0x8D, 0x5D, 0x50, 0x8D, 0xD9, 0x18 - }, - { - 0xA6, 0x6D, 0x40, 0x9A, 0xF7, 0xAF, 0xD7, 0x5B, - 0xE8, 0x31, 0xDD, 0x49, 0x8C, 0x19, 0x6E, 0xF1, - 0x2C, 0x73, 0xC3, 0x11, 0x29, 0xEC, 0x02, 0xD5, - 0xF1, 0x2A, 0xB0, 0x2A, 0x2C, 0x63, 0xA2, 0x5E - }, - { - 0x58, 0xB3, 0x74, 0x97, 0xFC, 0xF0, 0xBE, 0x0E, - 0x0C, 0xF1, 0x73, 0x40, 0x45, 0xC2, 0x95, 0xB2, - 0x86, 0xC7, 0x6A, 0x7C, 0x04, 0x8E, 0x87, 0xC5, - 0x40, 0x28, 0xED, 0x36, 0x91, 0x5B, 0x5D, 0xF3 - }, - { - 0x2C, 0x73, 0x33, 0x54, 0x0A, 0x83, 0x2D, 0x64, - 0x45, 0x6E, 0x43, 0x05, 0x8C, 0x50, 0xD9, 0x3C, - 0x93, 0x2A, 0xD9, 0xB1, 0x8B, 0x3F, 0xC3, 0xA0, - 0x59, 0x92, 0x07, 0xCD, 0xA3, 0xB3, 0xC7, 0xA6 - }, - { - 0x3D, 0xC0, 0x62, 0xFF, 0xB5, 0x7D, 0x83, 0x5F, - 0xE3, 0xAA, 0x40, 0x94, 0x66, 0x82, 0x2F, 0x91, - 0x86, 0x91, 0x84, 0x23, 0x94, 0x75, 0x05, 0x16, - 0x5F, 0xDC, 0xDF, 0xB7, 0x30, 0x6F, 0x72, 0x59 - }, - { - 0x89, 0x20, 0x48, 0x44, 0xAC, 0xB9, 0x2F, 0x35, - 0x3B, 0xFC, 0x89, 0xA3, 0xCE, 0x8A, 0x98, 0x17, - 0x21, 0x9C, 0x10, 0x13, 0x85, 0xC5, 0x93, 0xCF, - 0x60, 0xE0, 0xBE, 0xFA, 0x96, 0x38, 0xE1, 0x4E - }, - { - 0x78, 0x2B, 0xA9, 0x02, 0xE9, 0x12, 0x32, 0x94, - 0x1C, 0x78, 0xC4, 0x9C, 0xD9, 0x77, 0x1A, 0x5D, - 0x99, 0x92, 0xF9, 0xB0, 0x7D, 0x9C, 0x0A, 0x2D, - 0xF8, 0x2D, 0x38, 0x5D, 0x15, 0xC4, 0x2B, 0xB3 - }, - { - 0x0D, 0xC3, 0xFF, 0x7D, 0xF0, 0xDF, 0xC0, 0x23, - 0x76, 0x3D, 0x76, 0x34, 0xE1, 0x8D, 0xA2, 0x73, - 0x93, 0xFC, 0x9F, 0xDB, 0x1C, 0x15, 0x46, 0x46, - 0x86, 0x10, 0x75, 0xF0, 0xA8, 0x7D, 0x0E, 0x90 - }, - { - 0xB9, 0x5C, 0x65, 0xFB, 0x6F, 0x25, 0x4E, 0xDB, - 0xDE, 0x8C, 0x03, 0x7D, 0x5C, 0x8B, 0x20, 0x39, - 0x34, 0x0F, 0x4A, 0xC2, 0xB0, 0x23, 0xA6, 0xAA, - 0x28, 0xA8, 0xFC, 0xD2, 0xD2, 0x68, 0x9C, 0xF4 - }, - { - 0x87, 0xE8, 0xF5, 0x15, 0x72, 0xA5, 0xD6, 0xA2, - 0x39, 0xF8, 0x5B, 0xC5, 0x3E, 0x11, 0x74, 0xE1, - 0x5B, 0xE1, 0x2F, 0xCD, 0xF1, 0x51, 0xA0, 0xB9, - 0xA2, 0xB4, 0x36, 0x40, 0xCA, 0xF7, 0x4C, 0x1D - }, - { - 0x2A, 0x6F, 0x3E, 0x46, 0x2C, 0x40, 0x5C, 0x35, - 0x4F, 0xE8, 0x0F, 0xCC, 0xCE, 0xD1, 0xC9, 0xBE, - 0x44, 0x32, 0x5D, 0x29, 0xE0, 0x7D, 0xA3, 0x09, - 0x60, 0xB6, 0x25, 0xA7, 0x6E, 0xA4, 0x2F, 0x83 - }, - { - 0x20, 0xB4, 0x6C, 0x8F, 0xBF, 0xCA, 0x97, 0x45, - 0x32, 0x62, 0x46, 0x0F, 0x84, 0x98, 0xA7, 0xE2, - 0xAF, 0x15, 0xAC, 0x79, 0xB5, 0x9D, 0xDF, 0xB0, - 0x27, 0xBB, 0x52, 0xF2, 0xD6, 0x8E, 0x8F, 0x51 - }, - { - 0x31, 0xB0, 0x76, 0x3C, 0xB9, 0xBA, 0x92, 0x40, - 0x3D, 0xCA, 0x1A, 0xBD, 0xD7, 0x34, 0x2D, 0x7D, - 0xE9, 0x4C, 0x58, 0x1E, 0x76, 0xF7, 0xC9, 0xA6, - 0x1E, 0x51, 0x59, 0x28, 0xE1, 0x0B, 0x4E, 0x77 - }, - { - 0xE1, 0x91, 0xE1, 0x17, 0x06, 0x3C, 0xFA, 0xC9, - 0x64, 0x2C, 0xD9, 0x3C, 0xB4, 0x2B, 0x39, 0xED, - 0xDD, 0x9E, 0x4A, 0xB6, 0x5F, 0x1D, 0x03, 0x97, - 0xE3, 0xE1, 0x7D, 0xD0, 0x4C, 0xAB, 0x11, 0x80 - }, - { - 0x22, 0x5A, 0x20, 0x21, 0x07, 0xA7, 0x47, 0x03, - 0xE0, 0x41, 0xC6, 0xCC, 0xA4, 0xEA, 0xCF, 0x4F, - 0x21, 0xEE, 0xA6, 0xF2, 0x2A, 0x14, 0x6D, 0x8D, - 0xA2, 0xAB, 0x8C, 0xF6, 0x19, 0x72, 0x29, 0xA5 - }, - { - 0xEF, 0xC4, 0x83, 0x6B, 0xE4, 0xAC, 0x3E, 0x97, - 0x91, 0xD2, 0xEC, 0x62, 0x22, 0x6E, 0x7D, 0xF6, - 0x41, 0x18, 0xF4, 0x56, 0x5C, 0x19, 0xE6, 0xC9, - 0xE8, 0x40, 0x63, 0xF5, 0x66, 0x1C, 0x7B, 0x2F - }, - { - 0x3A, 0x76, 0xB0, 0x15, 0x2C, 0x0E, 0x1D, 0x1F, - 0xD7, 0xAC, 0x9D, 0x91, 0xA2, 0x8A, 0x18, 0xE1, - 0xA4, 0xC0, 0x60, 0x80, 0xF2, 0xB7, 0xEC, 0xEF, - 0xB6, 0xEF, 0xFE, 0x28, 0xB8, 0xCF, 0xC7, 0x65 - }, - { - 0x0D, 0x46, 0xAD, 0x03, 0x90, 0x70, 0x11, 0x58, - 0x28, 0xF9, 0x4E, 0xB6, 0xB7, 0x29, 0x63, 0xE6, - 0x0A, 0x7D, 0x2D, 0xB7, 0xCA, 0x89, 0x91, 0xD2, - 0x25, 0xC3, 0x87, 0x7B, 0x14, 0x9B, 0x0A, 0x8A - }, - { - 0xE4, 0x4C, 0xFC, 0x42, 0x11, 0x8F, 0x09, 0x6B, - 0xFC, 0x51, 0x52, 0x1C, 0xB1, 0x8D, 0x5D, 0x65, - 0x25, 0x58, 0x6B, 0x98, 0x9F, 0x4E, 0xE2, 0xB8, - 0x28, 0xC5, 0x19, 0x9F, 0xEA, 0xB9, 0x4B, 0x82 - }, - { - 0x6D, 0x4B, 0xD2, 0xE0, 0x73, 0xEC, 0x49, 0x66, - 0x84, 0x7F, 0x5C, 0xBE, 0x88, 0xDD, 0xFA, 0xBA, - 0x2B, 0xE4, 0xCA, 0xF2, 0xF3, 0x33, 0x55, 0x2B, - 0x85, 0x53, 0xDA, 0x53, 0x34, 0x87, 0xC2, 0x5B - }, - { - 0xBB, 0xC4, 0x6D, 0xB4, 0x37, 0xD1, 0x07, 0xC9, - 0x67, 0xCA, 0x6D, 0x91, 0x45, 0x5B, 0xBD, 0xFE, - 0x05, 0x21, 0x18, 0xAB, 0xD1, 0xD0, 0x69, 0xF0, - 0x43, 0x59, 0x48, 0x7E, 0x13, 0xAE, 0xA0, 0xE1 - }, - { - 0xB9, 0x74, 0xC1, 0x4D, 0xB7, 0xD3, 0x17, 0x4D, - 0xD0, 0x60, 0x84, 0xBB, 0x30, 0x31, 0x08, 0xB2, - 0xF0, 0xDA, 0xF5, 0x0E, 0xCC, 0xC3, 0x29, 0x35, - 0x43, 0x79, 0x5C, 0x96, 0x36, 0xC6, 0x24, 0x82 - }, - { - 0x0E, 0xEE, 0x23, 0x5B, 0x06, 0x93, 0x6A, 0xED, - 0x71, 0x73, 0xC8, 0xC1, 0x9A, 0xA7, 0xC2, 0x17, - 0xB9, 0xEE, 0xDA, 0xEB, 0x1A, 0x88, 0xF3, 0x05, - 0x52, 0xE9, 0x22, 0x51, 0x45, 0x14, 0x9E, 0x82 - }, - { - 0x36, 0xD0, 0x89, 0xE0, 0x25, 0xB5, 0x68, 0x69, - 0x37, 0x74, 0x28, 0x25, 0xE6, 0xEE, 0x3D, 0x83, - 0xE7, 0xD7, 0xA5, 0x0C, 0x82, 0x3C, 0x82, 0x88, - 0x34, 0x60, 0xF3, 0x85, 0x14, 0x7D, 0xC1, 0x7B - }, - { - 0x77, 0xEE, 0x4F, 0xFC, 0x9F, 0x5D, 0xD6, 0x05, - 0x47, 0x0D, 0xC0, 0xE7, 0x4D, 0x6B, 0x17, 0xC5, - 0x13, 0x0D, 0x8B, 0x73, 0x91, 0x3F, 0x36, 0xD5, - 0xF8, 0x78, 0x7E, 0x61, 0x9A, 0x94, 0x7C, 0xA0 - }, - { - 0x0F, 0xE6, 0xC2, 0xAB, 0x75, 0x42, 0x33, 0x36, - 0x0D, 0x68, 0xB9, 0xAC, 0x80, 0xCD, 0x61, 0x18, - 0x4B, 0xFA, 0xA7, 0xD3, 0x56, 0x29, 0x41, 0x80, - 0x02, 0x5F, 0xE4, 0x06, 0x39, 0xC7, 0x6C, 0x36 - }, - { - 0x99, 0x60, 0x88, 0xC7, 0x94, 0x56, 0xEC, 0xDD, - 0xA1, 0xFB, 0xC0, 0x2E, 0xE1, 0xBA, 0x42, 0xD9, - 0x1D, 0x85, 0x8C, 0x31, 0x0A, 0x5A, 0x8B, 0x46, - 0x74, 0xFE, 0x6A, 0x7C, 0x14, 0x44, 0x14, 0xA1 - }, - { - 0x9E, 0x33, 0x8A, 0xED, 0x0B, 0xC7, 0x1C, 0x0C, - 0x97, 0xF1, 0x98, 0x55, 0xBF, 0x49, 0x17, 0x4F, - 0x70, 0xA9, 0xD7, 0x70, 0x14, 0x87, 0x36, 0x63, - 0x21, 0x34, 0x27, 0x50, 0x2B, 0xD8, 0x5D, 0x9F - }, - { - 0x4A, 0x84, 0x3D, 0x26, 0xAD, 0xEC, 0x52, 0x0E, - 0x4B, 0x5D, 0xBF, 0x01, 0x45, 0xCC, 0x4F, 0x50, - 0x24, 0xFA, 0xFC, 0xDC, 0x20, 0x25, 0x82, 0x4A, - 0x8C, 0x64, 0x65, 0x06, 0x17, 0x68, 0x7E, 0xE7 - }, - { - 0xC9, 0x16, 0x78, 0xC4, 0xA6, 0x4E, 0x2F, 0xA4, - 0xB7, 0x4D, 0xE6, 0x1A, 0xD0, 0xC0, 0x6F, 0xF0, - 0x6B, 0x5D, 0x67, 0x2F, 0xA7, 0xC6, 0x87, 0x7A, - 0x40, 0x14, 0xCE, 0x9E, 0x91, 0xBE, 0x38, 0xD7 - }, - { - 0xFF, 0x77, 0x77, 0x40, 0x5D, 0x32, 0x7A, 0xDB, - 0x58, 0x30, 0x1C, 0x71, 0x1E, 0xCD, 0xC2, 0xBC, - 0xE1, 0xBF, 0xA8, 0x29, 0xFF, 0xC9, 0xB1, 0x17, - 0xF2, 0x1A, 0x2B, 0x19, 0x8D, 0x0D, 0x68, 0x84 - }, - { - 0x0A, 0x8D, 0xDA, 0xF1, 0x72, 0x8C, 0x5C, 0xD9, - 0x3A, 0x25, 0x5D, 0x56, 0x23, 0xC3, 0xDA, 0xDA, - 0x2D, 0x3D, 0x05, 0x71, 0xBF, 0x14, 0x38, 0xAD, - 0xC8, 0xC9, 0x64, 0xA9, 0xAA, 0xD1, 0x18, 0xCB - }, - { - 0xC1, 0x33, 0xAB, 0xBD, 0x0D, 0x2D, 0x80, 0x8A, - 0x67, 0xB6, 0x74, 0x5B, 0x4B, 0x36, 0x50, 0xB4, - 0xA6, 0x4D, 0xC2, 0x76, 0xCF, 0x98, 0xE3, 0x03, - 0x57, 0xB6, 0xAB, 0xD5, 0xC1, 0xD2, 0x2A, 0x9B - }, - { - 0xC5, 0x9E, 0xE5, 0xC1, 0x96, 0xBA, 0x3C, 0xFE, - 0xF9, 0x40, 0x87, 0x79, 0x82, 0x07, 0xBD, 0xCE, - 0xF1, 0x39, 0xCE, 0x2C, 0xF7, 0x8D, 0xCE, 0xD6, - 0x19, 0x8F, 0x0F, 0xA3, 0xA4, 0x09, 0x13, 0x1C - }, - { - 0xC7, 0xFD, 0xAD, 0xE5, 0x9C, 0x46, 0x99, 0x38, - 0x5E, 0xBA, 0x59, 0xE7, 0x56, 0xC2, 0xB1, 0x71, - 0xB0, 0x23, 0xDE, 0xAE, 0x08, 0x2E, 0x5A, 0x6E, - 0x3B, 0xFB, 0xDC, 0x10, 0x73, 0xA3, 0x20, 0x03 - }, - { - 0x97, 0x53, 0x27, 0xC5, 0xF4, 0xDE, 0xC6, 0x41, - 0x4B, 0x6E, 0x00, 0xCB, 0x04, 0x23, 0x37, 0xB8, - 0xD2, 0xA6, 0x56, 0x46, 0x37, 0xA7, 0x44, 0x2A, - 0xEC, 0x7B, 0xE8, 0xF8, 0xC8, 0x9A, 0x2F, 0x1C - }, - { - 0xA2, 0xF7, 0x24, 0x6D, 0xF4, 0xA2, 0x4E, 0xFB, - 0xAC, 0xD3, 0xFD, 0x60, 0x68, 0x3A, 0xBC, 0x86, - 0x8B, 0xEF, 0x25, 0x32, 0x70, 0x52, 0xCF, 0x2F, - 0x1D, 0x93, 0xEC, 0xE4, 0xFF, 0xCD, 0x73, 0xC6 - }, - { - 0x49, 0x7F, 0xB2, 0xAC, 0xAC, 0xF1, 0x23, 0xF3, - 0x59, 0x5E, 0x40, 0xFC, 0x51, 0xA7, 0xBD, 0x24, - 0x45, 0x8B, 0xBC, 0xBA, 0x4A, 0x29, 0x40, 0xA5, - 0xCB, 0x03, 0xD6, 0x08, 0xFB, 0xDF, 0x28, 0x25 - }, - { - 0x0E, 0x97, 0xD2, 0x27, 0x93, 0xCE, 0x6F, 0x28, - 0x3D, 0x5C, 0x74, 0x0D, 0x30, 0x8A, 0x27, 0xAD, - 0x7C, 0x3B, 0x0D, 0x9A, 0xFC, 0xD3, 0xD9, 0xE9, - 0xB9, 0xCA, 0xC5, 0x6B, 0x10, 0x29, 0x0C, 0x8F - }, - { - 0x66, 0x30, 0xB3, 0x56, 0x18, 0xE7, 0x00, 0xD9, - 0x10, 0x68, 0x38, 0x93, 0x79, 0x5E, 0xF7, 0x0B, - 0xF0, 0x7E, 0xB1, 0x56, 0xF5, 0x5F, 0xFE, 0x3B, - 0x69, 0xAD, 0x88, 0xA4, 0xB8, 0xB0, 0xBF, 0xA1 - }, - { - 0x02, 0xF7, 0x42, 0xC6, 0xE9, 0x52, 0x78, 0x12, - 0x1A, 0x05, 0xE4, 0x42, 0x05, 0x44, 0x4F, 0xC5, - 0xEA, 0x6A, 0xF5, 0xE7, 0x41, 0xC5, 0x35, 0xBC, - 0x2C, 0xBC, 0x3B, 0x23, 0x5A, 0x2E, 0xA2, 0xB0 - }, - { - 0x46, 0x22, 0xF3, 0x6E, 0xB8, 0x98, 0x38, 0x3F, - 0x60, 0xD5, 0xBE, 0xD8, 0x09, 0xAC, 0x5C, 0x47, - 0x45, 0xC5, 0xD6, 0xAB, 0x84, 0xBC, 0xAD, 0xF7, - 0x9C, 0xF2, 0xA9, 0x6D, 0x4E, 0xC8, 0x88, 0x18 - }, - { - 0xCC, 0xD1, 0x1F, 0xAA, 0xA0, 0x58, 0x1E, 0xC3, - 0x2C, 0x3A, 0x40, 0x3F, 0x92, 0xEF, 0x43, 0xD5, - 0xDC, 0xF1, 0x95, 0xC1, 0xA1, 0x01, 0xDB, 0xFD, - 0x49, 0x5D, 0xBB, 0x4D, 0xCE, 0x80, 0x69, 0xE0 - }, - { - 0x06, 0x02, 0x4D, 0x6B, 0x07, 0xE0, 0x00, 0xBC, - 0xE6, 0x13, 0x47, 0x0A, 0x28, 0x80, 0x51, 0x9B, - 0x8B, 0xE4, 0xA3, 0x6B, 0xF3, 0x3C, 0x99, 0xC9, - 0x17, 0x89, 0x3E, 0xC7, 0x5D, 0xD9, 0x0F, 0xE3 - }, - { - 0xD9, 0x3A, 0xF9, 0x47, 0xB1, 0x46, 0x3A, 0x81, - 0x7D, 0xB4, 0x41, 0xA4, 0x74, 0x58, 0x8D, 0x6F, - 0x99, 0x6D, 0x24, 0x39, 0x83, 0xE8, 0x3C, 0x7E, - 0xEE, 0x90, 0xE1, 0xEF, 0xA4, 0x40, 0xD9, 0xBA - }, - { - 0x94, 0x89, 0x89, 0x45, 0xA7, 0xDB, 0x25, 0x9E, - 0x1B, 0x2E, 0x7C, 0xBE, 0xA4, 0x8A, 0xA0, 0xC6, - 0xD6, 0x57, 0x0D, 0x18, 0x17, 0x9F, 0x06, 0x18, - 0x47, 0x1C, 0x88, 0xF3, 0xEC, 0x3B, 0x0F, 0xC3 - }, - { - 0x4C, 0x2D, 0x93, 0x52, 0x56, 0x39, 0x2A, 0xA2, - 0xBE, 0x6E, 0x10, 0x78, 0xC0, 0x59, 0x38, 0x15, - 0xAB, 0xEF, 0x46, 0x9D, 0xE9, 0x69, 0xB5, 0x7B, - 0x88, 0x1B, 0x93, 0xAF, 0x55, 0x84, 0x65, 0xFA - }, - { - 0xAA, 0xC7, 0xBE, 0x16, 0xE5, 0x2F, 0x79, 0x0E, - 0x4F, 0xF7, 0x0B, 0x24, 0x01, 0x5C, 0xB1, 0x1B, - 0x40, 0x61, 0x6E, 0x94, 0xDB, 0x13, 0x88, 0x2B, - 0x41, 0xD3, 0xDD, 0x8C, 0x8C, 0x19, 0x52, 0xB7 - }, - { - 0x04, 0x34, 0xB4, 0x7C, 0x0E, 0xE7, 0xE6, 0xF5, - 0x39, 0x06, 0x79, 0x9A, 0x43, 0x20, 0x9D, 0x3F, - 0xC3, 0x7D, 0x3F, 0xD1, 0xF7, 0x45, 0x55, 0xDE, - 0x67, 0xAB, 0xAC, 0xB9, 0x51, 0xB0, 0x06, 0xF4 - }, - { - 0x04, 0x42, 0xFB, 0xDD, 0x5B, 0x58, 0x49, 0x6E, - 0xC7, 0x81, 0x59, 0xCC, 0xAA, 0x88, 0x7C, 0x88, - 0xA8, 0x61, 0xFC, 0xCA, 0x70, 0xE7, 0xAB, 0xC9, - 0x76, 0xF2, 0x4C, 0x11, 0x58, 0x8B, 0xE6, 0xEE - }, - { - 0xA7, 0x3E, 0x68, 0xBB, 0x18, 0xB0, 0x07, 0x64, - 0x8E, 0x76, 0xB5, 0x52, 0x8D, 0x1E, 0x50, 0xE7, - 0xFA, 0x65, 0x4D, 0xA3, 0x97, 0x0E, 0xC3, 0x49, - 0xBF, 0x59, 0x1A, 0x30, 0xD9, 0x32, 0xC8, 0xF6 - }, - { - 0x84, 0x9C, 0xF8, 0x73, 0x16, 0x2B, 0xA7, 0x2C, - 0x4B, 0x80, 0x08, 0xE6, 0x8F, 0x93, 0x2F, 0xB3, - 0xA0, 0x15, 0xA7, 0x4F, 0xCF, 0x95, 0x71, 0x98, - 0xD5, 0x6A, 0x0D, 0xC4, 0x62, 0x5A, 0x74, 0xF5 - }, - { - 0xA6, 0xDE, 0xC6, 0xFC, 0x89, 0x49, 0x34, 0x9C, - 0x4E, 0x9A, 0x9C, 0x62, 0x36, 0x87, 0xFB, 0xA4, - 0xC9, 0xB2, 0x75, 0xBD, 0xB2, 0x30, 0x50, 0x9B, - 0x72, 0xE3, 0xD6, 0x71, 0x19, 0x14, 0xE2, 0xD8 - }, - { - 0x58, 0xAF, 0xC2, 0xB2, 0x4A, 0x19, 0xFD, 0xBF, - 0x76, 0xA0, 0x9B, 0x70, 0xB1, 0xE3, 0xB7, 0x7F, - 0xCB, 0xD4, 0x06, 0x50, 0x01, 0xD9, 0x63, 0x66, - 0x40, 0xEB, 0x5A, 0x26, 0x28, 0xF4, 0x42, 0xCC - }, - { - 0x47, 0x3A, 0x43, 0xAA, 0x1D, 0x6A, 0x02, 0x87, - 0x67, 0x43, 0x2A, 0x83, 0x0A, 0xD1, 0x22, 0x1E, - 0x02, 0x9C, 0x58, 0x9A, 0xF9, 0xFD, 0x4D, 0x68, - 0xD5, 0x6C, 0x4F, 0xB8, 0x20, 0x25, 0x93, 0x52 - }, - { - 0xA0, 0xAE, 0xB4, 0xA5, 0xAD, 0x89, 0x9A, 0xF2, - 0xE2, 0x91, 0xB2, 0xE7, 0x9D, 0xBB, 0x6B, 0x0B, - 0xF5, 0x6B, 0x58, 0x44, 0x67, 0x6B, 0x95, 0x5D, - 0x94, 0x5B, 0x6C, 0x4A, 0xE1, 0xC0, 0x1E, 0xED - }, - { - 0xCF, 0xC3, 0x02, 0x9A, 0x9E, 0xEB, 0x15, 0x22, - 0x22, 0xD9, 0x66, 0x53, 0x49, 0x2E, 0x46, 0xCA, - 0x64, 0xCA, 0x4F, 0x0D, 0x64, 0x68, 0x30, 0x28, - 0xD3, 0xAE, 0xE5, 0xA4, 0x9C, 0xB4, 0x71, 0x63 - }, - { - 0x74, 0x67, 0xCF, 0x77, 0x61, 0xCD, 0x9F, 0x55, - 0x61, 0x8D, 0x30, 0xC9, 0xD8, 0xC5, 0xB4, 0x1E, - 0x47, 0x01, 0x51, 0x0C, 0x7D, 0x16, 0xAB, 0x4E, - 0x5D, 0x89, 0xA5, 0xD7, 0x71, 0x46, 0xB0, 0x92 - }, - { - 0xC0, 0x16, 0xD8, 0x42, 0x4E, 0x53, 0x1E, 0xFC, - 0x57, 0x37, 0xC0, 0x3F, 0xC9, 0x0A, 0x5E, 0xFC, - 0x9F, 0x90, 0x22, 0xE4, 0xD5, 0xBA, 0x3B, 0x06, - 0x95, 0xF7, 0xAE, 0x53, 0x82, 0x60, 0xC2, 0xEE - }, - { - 0x5D, 0x38, 0x11, 0x89, 0xE6, 0x00, 0x0F, 0xC1, - 0x17, 0xC7, 0x1F, 0x59, 0xF7, 0x86, 0xFB, 0x4B, - 0x79, 0xFD, 0xD4, 0xEC, 0x5D, 0x4C, 0xD3, 0x0A, - 0xAC, 0x21, 0x57, 0xF7, 0x5D, 0xEA, 0xD7, 0x78 - }, - { - 0x7C, 0x9C, 0xDD, 0x15, 0xC4, 0xC9, 0xAB, 0xCA, - 0xCB, 0xFE, 0x6F, 0x66, 0x4A, 0x7F, 0x5F, 0x8B, - 0x2E, 0x25, 0x91, 0x83, 0x29, 0x1A, 0xE5, 0xCC, - 0x91, 0x30, 0xA0, 0xB2, 0x41, 0xE5, 0x73, 0x7F - }, - { - 0xB8, 0x81, 0x31, 0x72, 0xF5, 0x21, 0x8A, 0xC3, - 0xEB, 0x68, 0x7B, 0xC4, 0xAF, 0xAF, 0xF8, 0x3F, - 0xBC, 0xA4, 0xE9, 0xC1, 0xA4, 0x62, 0x96, 0x33, - 0x01, 0xDD, 0x44, 0x59, 0x85, 0x01, 0x50, 0xA2 - }, - { - 0xE3, 0xD1, 0x30, 0xE3, 0x6A, 0x02, 0x8E, 0xA8, - 0x0C, 0x57, 0xA2, 0xAA, 0x48, 0x19, 0xFD, 0x34, - 0xE4, 0xDB, 0xBE, 0xB1, 0x4A, 0x49, 0x58, 0x94, - 0xB1, 0x5A, 0x87, 0x87, 0xDB, 0x1A, 0x9F, 0x9C - }, - { - 0xFF, 0xF1, 0xB4, 0x40, 0x0F, 0x48, 0x9E, 0x07, - 0xD2, 0x23, 0x51, 0xC1, 0xF0, 0x95, 0x65, 0xE2, - 0x65, 0xB6, 0x8A, 0xD2, 0x9F, 0x63, 0x29, 0x87, - 0x9E, 0x6B, 0x5F, 0x7F, 0x6B, 0x41, 0x93, 0x50 - }, - { - 0x55, 0x9E, 0xD5, 0xBB, 0x3E, 0x5F, 0x39, 0x85, - 0xFB, 0x57, 0x82, 0x28, 0xBF, 0x8C, 0x0F, 0x0B, - 0x17, 0x3F, 0x8D, 0x11, 0x53, 0xFA, 0xEB, 0x9F, - 0xEC, 0x75, 0x6F, 0xFD, 0x18, 0xA8, 0x72, 0x38 - }, - { - 0x88, 0x13, 0x12, 0x53, 0x01, 0x4D, 0x23, 0xC5, - 0xE3, 0x8E, 0x78, 0xBD, 0xA1, 0x94, 0x55, 0xD8, - 0xA0, 0x23, 0xBD, 0x7A, 0x7E, 0x72, 0x74, 0x57, - 0xA1, 0x52, 0xA8, 0x1D, 0x0B, 0x17, 0x18, 0xA7 - }, - { - 0xF4, 0xD3, 0xFA, 0xE7, 0xCD, 0xE6, 0xBB, 0x66, - 0x71, 0x5A, 0x19, 0x8F, 0xA4, 0x8D, 0x21, 0x0C, - 0x10, 0xF8, 0xDF, 0x32, 0x04, 0xAE, 0x5E, 0x33, - 0xA6, 0x02, 0x46, 0x7F, 0x1B, 0x62, 0x26, 0x85 - }, - { - 0xE6, 0x2B, 0x62, 0x2A, 0xC8, 0xA2, 0x13, 0x66, - 0xBF, 0x2D, 0xED, 0x30, 0xF4, 0x08, 0x2A, 0x53, - 0xE7, 0x7A, 0x9A, 0xA6, 0x96, 0xB1, 0xF3, 0xEE, - 0x8C, 0xFE, 0x99, 0xC5, 0x93, 0x12, 0xD9, 0xC7 - }, - { - 0x3D, 0x39, 0xFF, 0xA8, 0x55, 0x12, 0xC3, 0xC8, - 0x89, 0x0D, 0x4B, 0xDF, 0x31, 0x88, 0x9C, 0xA6, - 0x6E, 0x5C, 0xEC, 0xB6, 0x3C, 0xFE, 0xED, 0x57, - 0xB9, 0x26, 0x37, 0x08, 0xE7, 0x4C, 0x55, 0x0B - }, - { - 0xB1, 0x70, 0x3B, 0x8A, 0x00, 0xE2, 0x61, 0x24, - 0x97, 0xD1, 0x1C, 0x64, 0x9D, 0x15, 0x0A, 0x6C, - 0x96, 0x3B, 0xF4, 0xFD, 0x38, 0xFE, 0xB1, 0xC3, - 0x81, 0xFE, 0x0D, 0x9B, 0x04, 0xC0, 0x2B, 0x22 - }, - { - 0x12, 0xFB, 0xAD, 0x9D, 0x37, 0x82, 0x81, 0x2D, - 0x71, 0x17, 0x9A, 0x50, 0xFB, 0xD9, 0xB4, 0x56, - 0x6C, 0x7B, 0x06, 0xF5, 0xD7, 0x7C, 0x6F, 0x32, - 0x97, 0x17, 0xFB, 0x4A, 0xE2, 0xC5, 0xB4, 0xEC - }, - { - 0x76, 0x8B, 0x65, 0x9A, 0x82, 0x4B, 0x43, 0xF9, - 0xCA, 0x56, 0x60, 0xB9, 0xDD, 0xF0, 0x5F, 0x8B, - 0xA2, 0xBC, 0x49, 0x93, 0x86, 0x6B, 0x7C, 0x9B, - 0xE6, 0x87, 0x91, 0xF5, 0xB2, 0x46, 0x44, 0xB3 - }, - { - 0xC0, 0x20, 0x4E, 0x23, 0xCA, 0x86, 0xBE, 0x20, - 0x5E, 0xED, 0x0C, 0xC3, 0xDD, 0x72, 0x25, 0xCE, - 0x5F, 0xFE, 0x1E, 0xE1, 0x2D, 0xAC, 0xB9, 0x3C, - 0x5D, 0x06, 0x29, 0xB7, 0x69, 0x9C, 0xD7, 0x33 - }, - { - 0xF4, 0x32, 0x96, 0x96, 0x1F, 0x8E, 0xAE, 0xCC, - 0xD8, 0x54, 0x41, 0x3D, 0xC5, 0xAD, 0xDA, 0x62, - 0x39, 0x3A, 0x34, 0x46, 0x27, 0xE8, 0x6C, 0x06, - 0x6E, 0x79, 0x07, 0x55, 0x00, 0x40, 0x74, 0x4F - }, - { - 0x82, 0xF4, 0x46, 0x9E, 0x80, 0x78, 0x90, 0x21, - 0xC6, 0x1D, 0xB7, 0xE3, 0x2F, 0x36, 0xAC, 0xBE, - 0x59, 0x1A, 0x64, 0xF2, 0x60, 0x59, 0x26, 0x57, - 0x70, 0xAE, 0x65, 0x8D, 0x62, 0xBD, 0xE7, 0xEF - }, - { - 0x2A, 0x85, 0x67, 0x1A, 0x55, 0xC8, 0x9F, 0xA1, - 0x56, 0xE2, 0x96, 0xF7, 0x5D, 0xF1, 0xC7, 0xDB, - 0xAB, 0x17, 0x8E, 0xBB, 0xA6, 0x52, 0x04, 0xA7, - 0xE8, 0x17, 0x8C, 0x91, 0x6A, 0xD0, 0x87, 0xF8 - }, - { - 0x33, 0xE2, 0x45, 0x00, 0x28, 0x08, 0xF6, 0x93, - 0x4B, 0x9B, 0xE3, 0xA6, 0xFA, 0x8E, 0x86, 0x70, - 0xC9, 0x0B, 0xAA, 0x62, 0x57, 0x17, 0xB9, 0x20, - 0x1E, 0xB9, 0xB9, 0xDD, 0x91, 0x2F, 0x5C, 0xE2 - }, - { - 0x58, 0xEE, 0x5E, 0x79, 0x91, 0x84, 0xAD, 0x9D, - 0xA9, 0xA1, 0x7C, 0x5B, 0x46, 0xA4, 0x81, 0x0E, - 0x28, 0xBD, 0xD0, 0x8C, 0x35, 0x81, 0x63, 0x4C, - 0x83, 0x50, 0x30, 0x53, 0x9B, 0x79, 0x54, 0x4D - }, - { - 0x26, 0xD8, 0xFA, 0x08, 0xDB, 0x30, 0x8E, 0xDF, - 0x2F, 0x96, 0xF8, 0x2A, 0xF6, 0xB6, 0x0C, 0x17, - 0xD8, 0xF1, 0xFF, 0x85, 0x8C, 0x52, 0xF2, 0xD0, - 0xF3, 0x83, 0x10, 0x78, 0x12, 0x75, 0x26, 0xA3 - }, - { - 0x25, 0xA5, 0x8D, 0xF4, 0x03, 0x92, 0x47, 0xA2, - 0x2F, 0x68, 0xFF, 0x2B, 0x71, 0x76, 0x6B, 0x7B, - 0x56, 0x00, 0xDD, 0xF4, 0x01, 0xD9, 0x9F, 0xF2, - 0xC1, 0x95, 0x5A, 0xE7, 0xBB, 0x43, 0xE5, 0x6A - }, - { - 0xBE, 0x43, 0xE8, 0x68, 0x61, 0x60, 0xE9, 0x07, - 0xBA, 0x54, 0x7D, 0x5A, 0x87, 0x9D, 0x10, 0xF7, - 0x88, 0xAF, 0xC8, 0x42, 0xB8, 0xEB, 0xB9, 0xF3, - 0xF7, 0x88, 0x53, 0x25, 0x15, 0x91, 0x2A, 0xE4 - }, - { - 0xAA, 0x4A, 0xCB, 0x95, 0xD8, 0x79, 0x19, 0x2A, - 0x69, 0x08, 0xE8, 0x8A, 0xE3, 0xD6, 0x58, 0x9F, - 0x4E, 0x3E, 0xB3, 0xD4, 0xE0, 0x3A, 0x80, 0x6C, - 0xCD, 0xB9, 0xB5, 0xD6, 0xA9, 0x58, 0x6F, 0xDF - }, - { - 0x84, 0x66, 0xD5, 0xE4, 0x4C, 0xE9, 0x5B, 0x4F, - 0xA1, 0x79, 0x99, 0x24, 0x44, 0xB8, 0xC2, 0x48, - 0x5B, 0x88, 0x64, 0x48, 0xA6, 0xDC, 0xCF, 0xCF, - 0x0B, 0xC3, 0x0B, 0xC5, 0xF0, 0xF5, 0x6B, 0x01 - }, - { - 0x00, 0x56, 0xD7, 0xE0, 0xAC, 0x33, 0x35, 0x57, - 0x83, 0x65, 0x9B, 0x38, 0xEC, 0x8B, 0xEC, 0xCB, - 0xF7, 0x83, 0x93, 0x99, 0x67, 0xFE, 0x37, 0xAE, - 0xAC, 0xF3, 0x69, 0xDD, 0xB6, 0x70, 0xAD, 0xA0 - }, - { - 0x90, 0x4F, 0x42, 0xF3, 0x45, 0x53, 0x0A, 0xC8, - 0xA3, 0x52, 0xD0, 0x9B, 0x68, 0x72, 0xC5, 0xBC, - 0xA3, 0x66, 0x1A, 0xBC, 0xA6, 0xCA, 0x64, 0xC8, - 0x09, 0x9F, 0x2F, 0xB6, 0x86, 0x7C, 0x30, 0xFE - }, - { - 0xA8, 0xC3, 0xBF, 0x46, 0xF0, 0xB8, 0x8B, 0xBD, - 0x16, 0xFD, 0xA4, 0xA8, 0xB5, 0xCA, 0x81, 0xF5, - 0x24, 0x35, 0x20, 0xC3, 0x85, 0xD3, 0x8C, 0x0B, - 0x4D, 0x23, 0x52, 0xAB, 0x34, 0xEA, 0x35, 0xE6 - }, - { - 0x8D, 0x33, 0x17, 0xFC, 0x60, 0x6E, 0x56, 0x6D, - 0x30, 0x2E, 0xDA, 0xB5, 0x5E, 0x80, 0x16, 0x11, - 0xD8, 0xC1, 0x3F, 0x4A, 0x9A, 0x19, 0xD1, 0x85, - 0x97, 0x8D, 0xEF, 0x72, 0x83, 0x9C, 0xDA, 0xA3 - }, - { - 0x97, 0x38, 0x80, 0x11, 0xF5, 0x7A, 0x49, 0x86, - 0x90, 0xEC, 0x79, 0x88, 0xEF, 0xF9, 0x03, 0xFF, - 0x9B, 0x23, 0x58, 0xF5, 0xB6, 0x1B, 0xAA, 0x20, - 0xF7, 0x32, 0x90, 0xD6, 0x29, 0x6C, 0x1C, 0x0B - }, - { - 0xCF, 0xB8, 0x0C, 0xAB, 0x89, 0x90, 0x95, 0x08, - 0x09, 0x12, 0x3F, 0xBF, 0x85, 0xE9, 0x76, 0x45, - 0x47, 0x08, 0xE0, 0xAF, 0xED, 0x69, 0x8E, 0x33, - 0x52, 0xA3, 0x16, 0x35, 0x90, 0x9D, 0xB3, 0xE5 - }, - { - 0x0D, 0xAA, 0xCA, 0x55, 0x13, 0x2A, 0x23, 0x5B, - 0x83, 0x1A, 0x5E, 0xFF, 0x4E, 0xA4, 0x67, 0xCD, - 0x10, 0xAF, 0x44, 0x20, 0x08, 0x47, 0x73, 0x5A, - 0x1F, 0xFD, 0x51, 0xFA, 0x37, 0xEA, 0xA2, 0xA2 - }, - { - 0x69, 0xB2, 0x14, 0x97, 0xEB, 0xB8, 0x24, 0xBA, - 0x66, 0x53, 0x68, 0x18, 0x88, 0x25, 0xE6, 0xF6, - 0xF1, 0x4C, 0xF2, 0xC3, 0xF7, 0xB5, 0x53, 0x0B, - 0xB3, 0x4F, 0xA6, 0x58, 0xEE, 0xD9, 0xA7, 0x39 - }, - { - 0xB9, 0xA1, 0x9F, 0x50, 0x9B, 0xE0, 0x3F, 0xBC, - 0x40, 0xE2, 0x43, 0xA5, 0x8A, 0x3D, 0xED, 0x11, - 0xF0, 0xD5, 0x1F, 0x80, 0xE3, 0xE2, 0x9A, 0x50, - 0x56, 0x44, 0xCC, 0x05, 0x74, 0x38, 0x14, 0xEC - }, - { - 0xC4, 0xBC, 0xB2, 0x00, 0x25, 0x55, 0xD5, 0x44, - 0xFD, 0x0B, 0x02, 0x77, 0x06, 0x23, 0x89, 0x1E, - 0x70, 0xEE, 0xEC, 0x77, 0x44, 0x86, 0x5D, 0xD6, - 0x45, 0x5A, 0xD6, 0x65, 0xCC, 0x82, 0xE8, 0x61 - }, - { - 0x91, 0x2D, 0x24, 0xDC, 0x3D, 0x69, 0x23, 0xA4, - 0x83, 0xC2, 0x63, 0xEB, 0xA8, 0x1B, 0x7A, 0x87, - 0x97, 0xF2, 0x3C, 0xBF, 0x2F, 0x78, 0xB5, 0x1E, - 0x22, 0x26, 0x63, 0x9F, 0x84, 0xA5, 0x90, 0x47 - }, - { - 0x56, 0x82, 0x7A, 0x18, 0x88, 0x3A, 0xFD, 0xF9, - 0xCE, 0xEC, 0x56, 0x2B, 0x20, 0x66, 0xD8, 0xAC, - 0xB2, 0xC1, 0x95, 0x05, 0xEC, 0xE6, 0xF7, 0xA8, - 0x3E, 0x9F, 0x33, 0x46, 0xCB, 0xB8, 0x28, 0xC9 - }, - { - 0x25, 0x1D, 0x8D, 0x09, 0xFC, 0x48, 0xDD, 0x1D, - 0x6A, 0xF8, 0xFF, 0xDF, 0x39, 0x50, 0x91, 0xA4, - 0x6E, 0x05, 0xB8, 0xB7, 0xC5, 0xEC, 0x0C, 0x79, - 0xB6, 0x8A, 0x89, 0x04, 0xC8, 0x27, 0xBD, 0xEA - }, - { - 0xC2, 0xD1, 0x4D, 0x69, 0xFD, 0x0B, 0xBD, 0x1C, - 0x0F, 0xE8, 0xC8, 0x45, 0xD5, 0xFD, 0x6A, 0x8F, - 0x74, 0x01, 0x51, 0xB1, 0xD8, 0xEB, 0x4D, 0x26, - 0x36, 0x4B, 0xB0, 0x2D, 0xAE, 0x0C, 0x13, 0xBC - }, - { - 0x2E, 0x5F, 0xE2, 0x1F, 0x8F, 0x1B, 0x63, 0x97, - 0xA3, 0x8A, 0x60, 0x3D, 0x60, 0xB6, 0xF5, 0x3C, - 0x3B, 0x5D, 0xB2, 0x0A, 0xA5, 0x6C, 0x6D, 0x44, - 0xBE, 0xBD, 0x48, 0x28, 0xCE, 0x28, 0xF9, 0x0F - }, - { - 0x25, 0x05, 0x9F, 0x10, 0x60, 0x5E, 0x67, 0xAD, - 0xFE, 0x68, 0x13, 0x50, 0x66, 0x6E, 0x15, 0xAE, - 0x97, 0x6A, 0x5A, 0x57, 0x1C, 0x13, 0xCF, 0x5B, - 0xC8, 0x05, 0x3F, 0x43, 0x0E, 0x12, 0x0A, 0x52 - }, -}; - - - - -static const uint8_t blake2sp_keyed_kat[KAT_LENGTH][BLAKE2S_OUTBYTES] = -{ - { - 0x71, 0x5C, 0xB1, 0x38, 0x95, 0xAE, 0xB6, 0x78, - 0xF6, 0x12, 0x41, 0x60, 0xBF, 0xF2, 0x14, 0x65, - 0xB3, 0x0F, 0x4F, 0x68, 0x74, 0x19, 0x3F, 0xC8, - 0x51, 0xB4, 0x62, 0x10, 0x43, 0xF0, 0x9C, 0xC6 - }, - { - 0x40, 0x57, 0x8F, 0xFA, 0x52, 0xBF, 0x51, 0xAE, - 0x18, 0x66, 0xF4, 0x28, 0x4D, 0x3A, 0x15, 0x7F, - 0xC1, 0xBC, 0xD3, 0x6A, 0xC1, 0x3C, 0xBD, 0xCB, - 0x03, 0x77, 0xE4, 0xD0, 0xCD, 0x0B, 0x66, 0x03 - }, - { - 0x67, 0xE3, 0x09, 0x75, 0x45, 0xBA, 0xD7, 0xE8, - 0x52, 0xD7, 0x4D, 0x4E, 0xB5, 0x48, 0xEC, 0xA7, - 0xC2, 0x19, 0xC2, 0x02, 0xA7, 0xD0, 0x88, 0xDB, - 0x0E, 0xFE, 0xAC, 0x0E, 0xAC, 0x30, 0x42, 0x49 - }, - { - 0x8D, 0xBC, 0xC0, 0x58, 0x9A, 0x3D, 0x17, 0x29, - 0x6A, 0x7A, 0x58, 0xE2, 0xF1, 0xEF, 0xF0, 0xE2, - 0xAA, 0x42, 0x10, 0xB5, 0x8D, 0x1F, 0x88, 0xB8, - 0x6D, 0x7B, 0xA5, 0xF2, 0x9D, 0xD3, 0xB5, 0x83 - }, - { - 0xA9, 0xA9, 0x65, 0x2C, 0x8C, 0x67, 0x75, 0x94, - 0xC8, 0x72, 0x12, 0xD8, 0x9D, 0x5A, 0x75, 0xFB, - 0x31, 0xEF, 0x4F, 0x47, 0xC6, 0x58, 0x2C, 0xDE, - 0x5F, 0x1E, 0xF6, 0x6B, 0xD4, 0x94, 0x53, 0x3A - }, - { - 0x05, 0xA7, 0x18, 0x0E, 0x59, 0x50, 0x54, 0x73, - 0x99, 0x48, 0xC5, 0xE3, 0x38, 0xC9, 0x5F, 0xE0, - 0xB7, 0xFC, 0x61, 0xAC, 0x58, 0xA7, 0x35, 0x74, - 0x74, 0x56, 0x33, 0xBB, 0xC1, 0xF7, 0x70, 0x31 - }, - { - 0x81, 0x4D, 0xE8, 0x31, 0x53, 0xB8, 0xD7, 0x5D, - 0xFA, 0xDE, 0x29, 0xFD, 0x39, 0xAC, 0x72, 0xDD, - 0x09, 0xCA, 0x0F, 0x9B, 0xC8, 0xB7, 0xAB, 0x6A, - 0x06, 0xBA, 0xEE, 0x7D, 0xD0, 0xF9, 0xF0, 0x83 - }, - { - 0xDF, 0xD4, 0x19, 0x44, 0x91, 0x29, 0xFF, 0x60, - 0x4F, 0x0A, 0x14, 0x8B, 0x4C, 0x7D, 0x68, 0xF1, - 0x17, 0x4F, 0x7D, 0x0F, 0x8C, 0x8D, 0x2C, 0xE7, - 0x7F, 0x44, 0x8F, 0xD3, 0x41, 0x9C, 0x6F, 0xB0 - }, - { - 0xB9, 0xED, 0x22, 0xE7, 0xDD, 0x8D, 0xD1, 0x4E, - 0xE8, 0xC9, 0x5B, 0x20, 0xE7, 0x63, 0x2E, 0x85, - 0x53, 0xA2, 0x68, 0xD9, 0xFF, 0x86, 0x33, 0xED, - 0x3C, 0x21, 0xD1, 0xB8, 0xC9, 0xA7, 0x0B, 0xE1 - }, - { - 0x95, 0xF0, 0x31, 0x67, 0x1A, 0x4E, 0x3C, 0x54, - 0x44, 0x1C, 0xEE, 0x9D, 0xBE, 0xF4, 0xB7, 0xAC, - 0xA4, 0x46, 0x18, 0xA3, 0xA3, 0x33, 0xAD, 0x74, - 0x06, 0xD1, 0x97, 0xAC, 0x5B, 0xA0, 0x79, 0x1A - }, - { - 0xE2, 0x92, 0x5B, 0x9D, 0x5C, 0xA0, 0xFF, 0x62, - 0x88, 0xC5, 0xEA, 0x1A, 0xF2, 0xD2, 0x2B, 0x0A, - 0x6B, 0x79, 0xE2, 0xDA, 0xE0, 0x8B, 0xFD, 0x36, - 0xC3, 0xBE, 0x10, 0xBB, 0x8D, 0x71, 0xD8, 0x39 - }, - { - 0x16, 0x24, 0x9C, 0x74, 0x4E, 0x49, 0x51, 0x45, - 0x1D, 0x4C, 0x89, 0x4F, 0xB5, 0x9A, 0x3E, 0xCB, - 0x3F, 0xBF, 0xB7, 0xA4, 0x5F, 0x96, 0xF8, 0x5D, - 0x15, 0x80, 0xAC, 0x0B, 0x84, 0x2D, 0x96, 0xDA - }, - { - 0x43, 0x2B, 0xC9, 0x1C, 0x52, 0xAC, 0xEB, 0x9D, - 0xAE, 0xD8, 0x83, 0x28, 0x81, 0x64, 0x86, 0x50, - 0xC1, 0xB8, 0x1D, 0x11, 0x7A, 0xBD, 0x68, 0xE0, - 0x84, 0x51, 0x50, 0x8A, 0x63, 0xBE, 0x00, 0x81 - }, - { - 0xCD, 0xE8, 0x20, 0x2B, 0xCF, 0xA3, 0xF3, 0xE9, - 0x5D, 0x79, 0xBA, 0xCC, 0x16, 0x5D, 0x52, 0x70, - 0x0E, 0xF7, 0x1D, 0x87, 0x4A, 0x3C, 0x63, 0x7E, - 0x63, 0x4F, 0x64, 0x44, 0x73, 0x72, 0x0D, 0x6B - }, - { - 0x16, 0x21, 0x62, 0x1F, 0x5C, 0x3E, 0xE4, 0x46, - 0x89, 0x9D, 0x3C, 0x8A, 0xAE, 0x49, 0x17, 0xB1, - 0xE6, 0xDB, 0x4A, 0x0E, 0xD0, 0x42, 0x31, 0x5F, - 0xB2, 0xC1, 0x74, 0x82, 0x5E, 0x0A, 0x18, 0x19 - }, - { - 0x33, 0x6E, 0x8E, 0xBC, 0x71, 0xE2, 0x09, 0x5C, - 0x27, 0xF8, 0x64, 0xA3, 0x12, 0x1E, 0xFD, 0x0F, - 0xAA, 0x7A, 0x41, 0x28, 0x57, 0x25, 0xA5, 0x92, - 0xF6, 0x1B, 0xED, 0xED, 0x9D, 0xDE, 0x86, 0xED - }, - { - 0x07, 0x9B, 0xE0, 0x41, 0x0E, 0x78, 0x9B, 0x36, - 0xEE, 0x7F, 0x55, 0xC1, 0x9F, 0xAA, 0xC6, 0x91, - 0x65, 0x6E, 0xB0, 0x52, 0x1F, 0x42, 0x94, 0x9B, - 0x84, 0xEE, 0x29, 0xFE, 0x2A, 0x0E, 0x7F, 0x36 - }, - { - 0x17, 0x27, 0x0C, 0x4F, 0x34, 0x88, 0x08, 0x2D, - 0x9F, 0xF9, 0x93, 0x7E, 0xAB, 0x3C, 0xA9, 0x9C, - 0x97, 0xC5, 0xB4, 0x59, 0x61, 0x47, 0x37, 0x2D, - 0xD4, 0xE9, 0x8A, 0xCF, 0x13, 0xDB, 0x28, 0x10 - }, - { - 0x18, 0x3C, 0x38, 0x75, 0x4D, 0x03, 0x41, 0xCE, - 0x07, 0xC1, 0x7A, 0x6C, 0xB6, 0xC2, 0xFD, 0x8B, - 0xBC, 0xC1, 0x40, 0x4F, 0xDD, 0x01, 0x41, 0x99, - 0xC7, 0x8B, 0xE1, 0xA9, 0x75, 0x59, 0xA9, 0x28 - }, - { - 0x6E, 0x52, 0xD7, 0x28, 0xA4, 0x05, 0xA6, 0xE1, - 0xF8, 0x75, 0x87, 0xBB, 0xC2, 0xAC, 0x91, 0xC5, - 0xC0, 0x9B, 0x2D, 0x82, 0x8A, 0xC8, 0x1E, 0x5C, - 0x4A, 0x81, 0xD0, 0x3D, 0xD4, 0xAA, 0x8D, 0x5C - }, - { - 0xF4, 0xE0, 0x8E, 0x05, 0x9B, 0x74, 0x14, 0x4B, - 0xF9, 0x48, 0x14, 0x6D, 0x14, 0xA2, 0xC8, 0x1E, - 0x46, 0xDC, 0x15, 0xFF, 0x26, 0xEB, 0x52, 0x34, - 0x4C, 0xDD, 0x47, 0x4A, 0xBE, 0xA1, 0x4B, 0xC0 - }, - { - 0x0F, 0x2E, 0x0A, 0x10, 0x0E, 0xD8, 0xA1, 0x17, - 0x85, 0x96, 0x2A, 0xD4, 0x59, 0x6A, 0xF9, 0x55, - 0xE3, 0x0B, 0x9A, 0xEF, 0x93, 0x0A, 0x24, 0x8D, - 0xA9, 0x32, 0x2B, 0x70, 0x2D, 0x4B, 0x68, 0x72 - }, - { - 0x51, 0x90, 0xFC, 0xC7, 0x32, 0xF4, 0x04, 0xAA, - 0xD4, 0x36, 0x4A, 0xC7, 0x96, 0x0C, 0xFD, 0x5B, - 0x4E, 0x34, 0x86, 0x29, 0xC3, 0x72, 0xEE, 0xB3, - 0x25, 0xB5, 0xC6, 0xC7, 0xCB, 0xCE, 0x59, 0xAB - }, - { - 0xC0, 0xC4, 0xCB, 0x86, 0xEA, 0x25, 0xEA, 0x95, - 0x7E, 0xEC, 0x5B, 0x22, 0xD2, 0x55, 0x0A, 0x16, - 0x49, 0xE6, 0xDF, 0xFA, 0x31, 0x6B, 0xB8, 0xF4, - 0xC9, 0x1B, 0x8F, 0xF7, 0xA2, 0x4B, 0x25, 0x31 - }, - { - 0x2C, 0x9E, 0xDA, 0x13, 0x5A, 0x30, 0xAE, 0xCA, - 0xF3, 0xAC, 0xB3, 0xD2, 0x3A, 0x30, 0x35, 0xFB, - 0xAB, 0xBA, 0x98, 0x33, 0x31, 0x65, 0xD8, 0x7F, - 0xCB, 0xF8, 0xFE, 0x10, 0x33, 0x6E, 0xCF, 0x20 - }, - { - 0x3C, 0xD6, 0x69, 0xE8, 0xD5, 0x62, 0x62, 0xA2, - 0x37, 0x13, 0x67, 0x22, 0x4D, 0xAE, 0x6D, 0x75, - 0x9E, 0xE1, 0x52, 0xC3, 0x15, 0x33, 0xB2, 0x63, - 0xFA, 0x2E, 0x64, 0x92, 0x08, 0x77, 0xB2, 0xA7 - }, - { - 0x18, 0xA9, 0xA0, 0xC2, 0xD0, 0xEA, 0x6C, 0x3B, - 0xB3, 0x32, 0x83, 0x0F, 0x89, 0x18, 0xB0, 0x68, - 0x4F, 0x5D, 0x39, 0x94, 0xDF, 0x48, 0x67, 0x46, - 0x2D, 0xD0, 0x6E, 0xF0, 0x86, 0x24, 0x24, 0xCC - }, - { - 0x73, 0x90, 0xEA, 0x41, 0x04, 0xA9, 0xF4, 0xEE, - 0xA9, 0x0F, 0x81, 0xE2, 0x6A, 0x12, 0x9D, 0xCF, - 0x9F, 0x4A, 0xF3, 0x83, 0x52, 0xD9, 0xCB, 0x6A, - 0x81, 0x2C, 0xC8, 0x05, 0x69, 0x09, 0x05, 0x0E - }, - { - 0xE4, 0x9E, 0x01, 0x14, 0xC6, 0x29, 0xB4, 0x94, - 0xB1, 0x1E, 0xA9, 0x8E, 0xCD, 0x40, 0x32, 0x73, - 0x1F, 0x15, 0x3B, 0x46, 0x50, 0xAC, 0xAC, 0xD7, - 0xE0, 0xF6, 0xE7, 0xDE, 0x3D, 0xF0, 0x19, 0x77 - }, - { - 0x27, 0xC5, 0x70, 0x2B, 0xE1, 0x04, 0xB3, 0xA9, - 0x4F, 0xC4, 0x34, 0x23, 0xAE, 0xEE, 0x83, 0xAC, - 0x3C, 0xA7, 0x3B, 0x7F, 0x87, 0x83, 0x9A, 0x6B, - 0x2E, 0x29, 0x60, 0x79, 0x03, 0xB7, 0xF2, 0x87 - }, - { - 0x81, 0xD2, 0xE1, 0x2E, 0xB2, 0xF4, 0x27, 0x60, - 0xC6, 0xE3, 0xBA, 0xA7, 0x8F, 0x84, 0x07, 0x3A, - 0xE6, 0xF5, 0x61, 0x60, 0x70, 0xFE, 0x25, 0xBE, - 0xDE, 0x7C, 0x7C, 0x82, 0x48, 0xAB, 0x1F, 0xBA - }, - { - 0xFA, 0xB2, 0x35, 0xD5, 0x93, 0x48, 0xAB, 0x8C, - 0xE4, 0x9B, 0xEC, 0x77, 0xC0, 0xF1, 0x93, 0x28, - 0xFD, 0x04, 0x5D, 0xFD, 0x60, 0x8A, 0x53, 0x03, - 0x36, 0xDF, 0x4F, 0x94, 0xE1, 0x72, 0xA5, 0xC8 - }, - { - 0x8A, 0xAA, 0x8D, 0x80, 0x5C, 0x58, 0x88, 0x1F, - 0xF3, 0x79, 0xFB, 0xD4, 0x2C, 0x6B, 0xF6, 0xF1, - 0x4C, 0x6C, 0x73, 0xDF, 0x80, 0x71, 0xB3, 0xB2, - 0x28, 0x98, 0x11, 0x09, 0xCC, 0xC0, 0x15, 0xF9 - }, - { - 0x91, 0xFD, 0xD2, 0x62, 0x20, 0x39, 0x16, 0x39, - 0x47, 0x40, 0x95, 0x2B, 0xCE, 0x72, 0xB6, 0x4B, - 0xAB, 0xB6, 0xF7, 0x21, 0x34, 0x4D, 0xEE, 0x82, - 0x50, 0xBF, 0x0E, 0x46, 0xF1, 0xBA, 0x18, 0x8F - }, - { - 0xF7, 0xE5, 0x7B, 0x8F, 0x85, 0xF4, 0x7D, 0x59, - 0x03, 0xAD, 0x4C, 0xCB, 0x8A, 0xF6, 0x2A, 0x3E, - 0x85, 0x8A, 0xAB, 0x2B, 0x8C, 0xC2, 0x26, 0x49, - 0x4F, 0x7B, 0x00, 0xBE, 0xDB, 0xF5, 0xB0, 0xD0 - }, - { - 0xF7, 0x6F, 0x21, 0xAD, 0xDA, 0xE9, 0x6A, 0x96, - 0x46, 0xFC, 0x06, 0xF9, 0xBF, 0x52, 0xAE, 0x08, - 0x48, 0xF1, 0x8C, 0x35, 0x26, 0xB1, 0x29, 0xE1, - 0x5B, 0x2C, 0x35, 0x5E, 0x2E, 0x79, 0xE5, 0xDA - }, - { - 0x8A, 0xEB, 0x1C, 0x79, 0x5F, 0x34, 0x90, 0x01, - 0x5E, 0xF4, 0xCD, 0x61, 0xA2, 0x80, 0x7B, 0x23, - 0x0E, 0xFD, 0xC8, 0x46, 0x01, 0x73, 0xDA, 0xD0, - 0x26, 0xA4, 0xA0, 0xFC, 0xC2, 0xFB, 0xF2, 0x2A - }, - { - 0xC5, 0x64, 0xFF, 0xC6, 0x23, 0x07, 0x77, 0x65, - 0xBB, 0x97, 0x87, 0x58, 0x56, 0x54, 0xCE, 0x74, - 0x5D, 0xBD, 0x10, 0x8C, 0xEF, 0x24, 0x8A, 0xB0, - 0x0A, 0xD1, 0xA2, 0x64, 0x7D, 0x99, 0x03, 0x87 - }, - { - 0xFE, 0x89, 0x42, 0xA3, 0xE5, 0xF5, 0xE8, 0xCD, - 0x70, 0x51, 0x04, 0xF8, 0x82, 0x10, 0x72, 0x6E, - 0x53, 0xDD, 0x7E, 0xB3, 0xF9, 0xA2, 0x02, 0xBF, - 0x93, 0x14, 0xB3, 0xB9, 0x06, 0x5E, 0xB7, 0x12 - }, - { - 0xDC, 0x29, 0x53, 0x59, 0xD4, 0x36, 0xEE, 0xA7, - 0x80, 0x84, 0xE7, 0xB0, 0x77, 0xFE, 0x09, 0xB1, - 0x9C, 0x5B, 0xF3, 0xD2, 0xA7, 0x96, 0xDA, 0xB0, - 0x19, 0xE4, 0x20, 0x05, 0x99, 0xFD, 0x82, 0x02 - }, - { - 0x70, 0xB3, 0xF7, 0x2F, 0x74, 0x90, 0x32, 0xE2, - 0x5E, 0x38, 0x3B, 0x96, 0x43, 0x78, 0xEA, 0x1C, - 0x54, 0x3E, 0x9C, 0x15, 0xDE, 0x3A, 0x27, 0xD8, - 0x6D, 0x2A, 0x9D, 0x22, 0x31, 0xEF, 0xF4, 0x8A - }, - { - 0x79, 0x82, 0xB5, 0x4C, 0x08, 0xDB, 0x2B, 0xFB, - 0x6F, 0x45, 0xF3, 0x5B, 0xC3, 0x23, 0xBC, 0x09, - 0x37, 0x79, 0xB6, 0xBB, 0x0E, 0x3E, 0xEA, 0x3E, - 0x8C, 0x98, 0xB1, 0xDE, 0x99, 0xD3, 0xC5, 0x5E - }, - { - 0x75, 0xE4, 0x16, 0x22, 0x57, 0x01, 0x4B, 0xED, - 0xCC, 0x05, 0xC2, 0x94, 0x4D, 0xCE, 0x0D, 0xF0, - 0xC3, 0x5E, 0xBA, 0x13, 0x19, 0x54, 0x06, 0x4F, - 0x6E, 0x4E, 0x09, 0x5F, 0xD0, 0x84, 0x45, 0xEE - }, - { - 0x4A, 0x12, 0x9E, 0xA6, 0xCD, 0xBA, 0xBC, 0x2D, - 0x39, 0x24, 0x79, 0x37, 0x2F, 0x97, 0x5B, 0x9C, - 0xF5, 0xA1, 0xB7, 0xDE, 0xB6, 0x9A, 0x32, 0x66, - 0xF0, 0x3E, 0xBC, 0x6D, 0x11, 0x13, 0x93, 0xC4 - }, - { - 0x8F, 0xED, 0x70, 0xF2, 0x79, 0x55, 0xDC, 0x8A, - 0xD9, 0xF1, 0xB7, 0xB3, 0xF6, 0xF5, 0xDF, 0xBD, - 0x96, 0x2A, 0x33, 0x59, 0x2B, 0x42, 0xDE, 0x85, - 0x6D, 0x42, 0x1E, 0x29, 0x12, 0xBA, 0xB8, 0x6B - }, - { - 0xE2, 0xF2, 0x06, 0x60, 0x37, 0x6F, 0x2B, 0x18, - 0x39, 0x66, 0x7C, 0xBF, 0xE5, 0xE1, 0x6E, 0xF0, - 0x75, 0xAC, 0x39, 0x43, 0x64, 0x4F, 0x35, 0x32, - 0x28, 0x2F, 0x8B, 0xB0, 0x72, 0x3B, 0x99, 0x86 - }, - { - 0xAB, 0xF8, 0x4C, 0x91, 0x3A, 0x83, 0xDF, 0x98, - 0xC7, 0x00, 0x29, 0x81, 0x9C, 0x06, 0x5F, 0x6D, - 0x6D, 0xE4, 0xF6, 0xD4, 0x3A, 0xBF, 0x60, 0x0D, - 0xAD, 0xE0, 0x35, 0xB2, 0x3B, 0xED, 0x7B, 0xAA - }, - { - 0x45, 0x9C, 0x15, 0xD4, 0x85, 0x6C, 0x7E, 0xCF, - 0x82, 0x62, 0x03, 0x51, 0xC3, 0xC1, 0xC7, 0x6C, - 0x40, 0x3F, 0x3E, 0x97, 0x07, 0x74, 0x13, 0x87, - 0xE2, 0x99, 0x07, 0x3F, 0xB1, 0x70, 0x4B, 0x2B - }, - { - 0x9A, 0xB9, 0x12, 0xED, 0xA0, 0x76, 0x8A, 0xBD, - 0xF8, 0x26, 0xB6, 0xE0, 0x5D, 0x0D, 0x73, 0x58, - 0x39, 0xE6, 0xA5, 0xF0, 0x2E, 0x04, 0xC4, 0xCC, - 0x75, 0x65, 0x0B, 0x2C, 0x8C, 0xAB, 0x67, 0x49 - }, - { - 0x47, 0x40, 0xEB, 0xEC, 0xAC, 0x90, 0x03, 0x1B, - 0xB7, 0xE6, 0x8E, 0x51, 0xC5, 0x53, 0x91, 0xAF, - 0xB1, 0x89, 0xB3, 0x17, 0xF2, 0xDE, 0x55, 0x87, - 0x66, 0xF7, 0x8F, 0x5C, 0xB7, 0x1F, 0x81, 0xB6 - }, - { - 0x3C, 0xC4, 0x7F, 0x0E, 0xF6, 0x48, 0x21, 0x58, - 0x7C, 0x93, 0x7C, 0xDD, 0xBA, 0x85, 0xC9, 0x93, - 0xD3, 0xCE, 0x2D, 0xD0, 0xCE, 0xD4, 0x0D, 0x3B, - 0xE3, 0x3C, 0xB7, 0xDC, 0x7E, 0xDA, 0xBC, 0xF1 - }, - { - 0x9F, 0x47, 0x6A, 0x22, 0xDB, 0x54, 0xD6, 0xBB, - 0x9B, 0xEF, 0xDB, 0x26, 0x0C, 0x66, 0x57, 0x8A, - 0xE1, 0xD8, 0xA5, 0xF8, 0x7D, 0x3D, 0x8C, 0x01, - 0x7F, 0xDB, 0x74, 0x75, 0x08, 0x0F, 0xA8, 0xE1 - }, - { - 0x8B, 0x68, 0xC6, 0xFB, 0x07, 0x06, 0xA7, 0x95, - 0xF3, 0xA8, 0x39, 0xD6, 0xFE, 0x25, 0xFD, 0x4A, - 0xA7, 0xF9, 0x2E, 0x66, 0x4F, 0x76, 0x2D, 0x61, - 0x53, 0x81, 0xBC, 0x85, 0x9A, 0xFA, 0x29, 0x2C - }, - { - 0xF6, 0x40, 0xD2, 0x25, 0xA6, 0xBC, 0xD2, 0xFC, - 0x8A, 0xCC, 0xAF, 0xBE, 0xD5, 0xA8, 0x4B, 0x5B, - 0xBB, 0x5D, 0x8A, 0xE5, 0xDB, 0x06, 0xA1, 0x0B, - 0x6D, 0x9D, 0x93, 0x16, 0x0B, 0x39, 0x2E, 0xE0 - }, - { - 0x70, 0x48, 0x60, 0xA7, 0xF5, 0xBA, 0x68, 0xDB, - 0x27, 0x03, 0x1C, 0x15, 0xF2, 0x25, 0x50, 0x0D, - 0x69, 0x2A, 0xB2, 0x47, 0x53, 0x42, 0x81, 0xC4, - 0xF6, 0x84, 0xF6, 0xC6, 0xC8, 0xCD, 0x88, 0xC7 - }, - { - 0xC1, 0xA7, 0x5B, 0xDD, 0xA1, 0x2B, 0x8B, 0x2A, - 0xB1, 0xB9, 0x24, 0x84, 0x38, 0x58, 0x18, 0x3A, - 0x09, 0xD2, 0x02, 0x42, 0x1F, 0xDB, 0xCD, 0xF0, - 0xE6, 0x3E, 0xAE, 0x46, 0xF3, 0x7D, 0x91, 0xED - }, - { - 0x9A, 0x8C, 0xAB, 0x7A, 0x5F, 0x2E, 0x57, 0x62, - 0x21, 0xA6, 0xA8, 0x5E, 0x5F, 0xDD, 0xEE, 0x75, - 0x67, 0x8E, 0x06, 0x53, 0x24, 0xA6, 0x1D, 0xB0, - 0x3A, 0x39, 0x26, 0x1D, 0xDF, 0x75, 0xE3, 0xF4 - }, - { - 0x05, 0xC2, 0xB2, 0x6B, 0x03, 0xCE, 0x6C, 0xA5, - 0x87, 0x1B, 0xE0, 0xDE, 0x84, 0xEE, 0x27, 0x86, - 0xA7, 0x9B, 0xCD, 0x9F, 0x30, 0x03, 0x3E, 0x81, - 0x9B, 0x4A, 0x87, 0xCC, 0xA2, 0x7A, 0xFC, 0x6A - }, - { - 0xB0, 0xB0, 0x99, 0x3C, 0x6D, 0x0C, 0x6E, 0xD5, - 0xC3, 0x59, 0x04, 0x80, 0xF8, 0x65, 0xF4, 0x67, - 0xF4, 0x33, 0x1A, 0x58, 0xDD, 0x8E, 0x47, 0xBD, - 0x98, 0xEB, 0xBC, 0xDB, 0x8E, 0xB4, 0xF9, 0x4D - }, - { - 0xE5, 0x7C, 0x10, 0x3C, 0xF7, 0xB6, 0xBB, 0xEB, - 0x8A, 0x0D, 0xC8, 0xF0, 0x48, 0x62, 0x5C, 0x3F, - 0x4C, 0xE4, 0xF1, 0xA5, 0xAD, 0x4D, 0x07, 0x9C, - 0x11, 0x87, 0xBF, 0xE9, 0xEE, 0x3B, 0x8A, 0x5F - }, - { - 0xF1, 0x00, 0x23, 0xE1, 0x5F, 0x3B, 0x72, 0xB7, - 0x38, 0xAD, 0x61, 0xAE, 0x65, 0xAB, 0x9A, 0x07, - 0xE7, 0x77, 0x4E, 0x2D, 0x7A, 0xB0, 0x2D, 0xBA, - 0x4E, 0x0C, 0xAF, 0x56, 0x02, 0xC8, 0x01, 0x78 - }, - { - 0x9A, 0x8F, 0xB3, 0xB5, 0x38, 0xC1, 0xD6, 0xC4, - 0x50, 0x51, 0xFA, 0x9E, 0xD9, 0xB0, 0x7D, 0x3E, - 0x89, 0xB4, 0x43, 0x03, 0x30, 0x01, 0x4A, 0x1E, - 0xFA, 0x28, 0x23, 0xC0, 0x82, 0x3C, 0xF2, 0x37 - }, - { - 0x30, 0x75, 0xC5, 0xBC, 0x7C, 0x3A, 0xD7, 0xE3, - 0x92, 0x01, 0x01, 0xBC, 0x68, 0x99, 0xC5, 0x8E, - 0xA7, 0x01, 0x67, 0xA7, 0x77, 0x2C, 0xA2, 0x8E, - 0x38, 0xE2, 0xC1, 0xB0, 0xD3, 0x25, 0xE5, 0xA0 - }, - { - 0xE8, 0x55, 0x94, 0x70, 0x0E, 0x39, 0x22, 0xA1, - 0xE8, 0xE4, 0x1E, 0xB8, 0xB0, 0x64, 0xE7, 0xAC, - 0x6D, 0x94, 0x9D, 0x13, 0xB5, 0xA3, 0x45, 0x23, - 0xE5, 0xA6, 0xBE, 0xAC, 0x03, 0xC8, 0xAB, 0x29 - }, - { - 0x1D, 0x37, 0x01, 0xA5, 0x66, 0x1B, 0xD3, 0x1A, - 0xB2, 0x05, 0x62, 0xBD, 0x07, 0xB7, 0x4D, 0xD1, - 0x9A, 0xC8, 0xF3, 0x52, 0x4B, 0x73, 0xCE, 0x7B, - 0xC9, 0x96, 0xB7, 0x88, 0xAF, 0xD2, 0xF3, 0x17 - }, - { - 0x87, 0x4E, 0x19, 0x38, 0x03, 0x3D, 0x7D, 0x38, - 0x35, 0x97, 0xA2, 0xA6, 0x5F, 0x58, 0xB5, 0x54, - 0xE4, 0x11, 0x06, 0xF6, 0xD1, 0xD5, 0x0E, 0x9B, - 0xA0, 0xEB, 0x68, 0x5F, 0x6B, 0x6D, 0xA0, 0x71 - }, - { - 0x93, 0xF2, 0xF3, 0xD6, 0x9B, 0x2D, 0x36, 0x52, - 0x95, 0x56, 0xEC, 0xCA, 0xF9, 0xF9, 0x9A, 0xDB, - 0xE8, 0x95, 0xE1, 0x57, 0x22, 0x31, 0xE6, 0x49, - 0xB5, 0x05, 0x84, 0xB5, 0xD7, 0xD0, 0x8A, 0xF8 - }, - { - 0x06, 0xE0, 0x6D, 0x61, 0x0F, 0x2E, 0xEB, 0xBA, - 0x36, 0x76, 0x82, 0x3E, 0x77, 0x44, 0xD7, 0x51, - 0xAF, 0xF7, 0x30, 0x76, 0xED, 0x65, 0xF3, 0xCF, - 0xF5, 0xE7, 0x2F, 0xD2, 0x27, 0x99, 0x9C, 0x77 - }, - { - 0x8D, 0xF7, 0x57, 0xB3, 0xA1, 0xE0, 0xF4, 0x80, - 0xFA, 0x76, 0xC7, 0xF3, 0x58, 0xED, 0x03, 0x98, - 0xBE, 0x3F, 0x2A, 0x8F, 0x7B, 0x90, 0xEA, 0x8C, - 0x80, 0x75, 0x99, 0xDE, 0xDA, 0x1D, 0x05, 0x34 - }, - { - 0xEE, 0xC9, 0xC5, 0xC6, 0x3C, 0xC5, 0x16, 0x9D, - 0x96, 0x7B, 0xB1, 0x62, 0x4E, 0x9E, 0xE5, 0xCE, - 0xD9, 0x28, 0x97, 0x73, 0x6E, 0xFB, 0xD1, 0x57, - 0x54, 0x8D, 0x82, 0xE8, 0x7C, 0xC7, 0x2F, 0x25 - }, - { - 0xCC, 0x2B, 0x58, 0x32, 0xAD, 0x27, 0x2C, 0xC5, - 0x5C, 0x10, 0xD4, 0xF8, 0xC7, 0xF8, 0xBB, 0x38, - 0xE6, 0xE4, 0xEB, 0x92, 0x2F, 0x93, 0x86, 0x83, - 0x0F, 0x90, 0xB1, 0xE3, 0xDA, 0x39, 0x37, 0xD5 - }, - { - 0x36, 0x89, 0x85, 0xD5, 0x38, 0x7C, 0x0B, 0xFC, - 0x92, 0x8A, 0xC2, 0x54, 0xFA, 0x6D, 0x16, 0x67, - 0x3E, 0x70, 0x94, 0x75, 0x66, 0x96, 0x1B, 0x5F, - 0xB3, 0x32, 0x5A, 0x58, 0x8A, 0xB3, 0x17, 0x3A - }, - { - 0xF1, 0xE4, 0x42, 0xAF, 0xB8, 0x72, 0x15, 0x1F, - 0x81, 0x34, 0x95, 0x6C, 0x54, 0x8A, 0xE3, 0x24, - 0x0D, 0x07, 0xE6, 0xE3, 0x38, 0xD4, 0xA7, 0xA6, - 0xAF, 0x8D, 0xA4, 0x11, 0x9A, 0xB0, 0xE2, 0xB0 - }, - { - 0xB0, 0x12, 0xC7, 0x54, 0x6A, 0x39, 0xC4, 0x0C, - 0xAD, 0xEC, 0xE4, 0xE0, 0x4E, 0x7F, 0x33, 0xC5, - 0x93, 0xAD, 0x18, 0x2E, 0xBC, 0x5A, 0x46, 0xD2, - 0xDB, 0xF4, 0xAD, 0x1A, 0x92, 0xF5, 0x9E, 0x7B - }, - { - 0x6C, 0x60, 0x97, 0xCD, 0x20, 0x33, 0x09, 0x6B, - 0x4D, 0xF3, 0x17, 0xDE, 0x8A, 0x90, 0x8B, 0x7D, - 0x0C, 0x72, 0x94, 0x39, 0x0C, 0x5A, 0x39, 0x9C, - 0x30, 0x1B, 0xF2, 0xA2, 0x65, 0x2E, 0x82, 0x62 - }, - { - 0xBA, 0x83, 0xFE, 0xB5, 0x10, 0xB4, 0x9A, 0xDE, - 0x4F, 0xAE, 0xFB, 0xE9, 0x42, 0x78, 0x1E, 0xAF, - 0xD4, 0x1A, 0xD5, 0xD4, 0x36, 0x88, 0x85, 0x31, - 0xB6, 0x88, 0x59, 0xF2, 0x2C, 0x2D, 0x16, 0x4A - }, - { - 0x5A, 0x06, 0x9E, 0x43, 0x92, 0x19, 0x5A, 0xC9, - 0xD2, 0x84, 0xA4, 0x7F, 0x3B, 0xD8, 0x54, 0xAF, - 0x8F, 0xD0, 0xD7, 0xFD, 0xC3, 0x48, 0x3D, 0x2C, - 0x5F, 0x34, 0x24, 0xCC, 0xFD, 0xA1, 0x5C, 0x8E - }, - { - 0x7E, 0x88, 0xD6, 0x4B, 0xBB, 0xE2, 0x02, 0x4F, - 0x44, 0x54, 0xBA, 0x13, 0x98, 0xB3, 0xD8, 0x65, - 0x2D, 0xCE, 0xC8, 0x20, 0xB1, 0x4C, 0x3B, 0x0A, - 0xBF, 0xBF, 0x0F, 0x4F, 0x33, 0x06, 0xBB, 0x5E - }, - { - 0xF8, 0x74, 0x2F, 0xF4, 0x6D, 0xFD, 0xF3, 0xEC, - 0x82, 0x64, 0xF9, 0x94, 0x5B, 0x20, 0x41, 0x94, - 0x62, 0xF0, 0x69, 0xE8, 0x33, 0xC5, 0x94, 0xEC, - 0x80, 0xFF, 0xAC, 0x5E, 0x7E, 0x51, 0x34, 0xF9 - }, - { - 0xD3, 0xE0, 0xB7, 0x38, 0xD2, 0xE9, 0x2F, 0x3C, - 0x47, 0xC7, 0x94, 0x66, 0x66, 0x09, 0xC0, 0xF5, - 0x50, 0x4F, 0x67, 0xEC, 0x4E, 0x76, 0x0E, 0xEE, - 0xCC, 0xF8, 0x64, 0x4E, 0x68, 0x33, 0x34, 0x11 - }, - { - 0x0C, 0x90, 0xCE, 0x10, 0xED, 0xF0, 0xCE, 0x1D, - 0x47, 0xEE, 0xB5, 0x0B, 0x5B, 0x7A, 0xFF, 0x8E, - 0xE8, 0xA4, 0x3B, 0x64, 0xA8, 0x89, 0xC1, 0xC6, - 0xC6, 0xB8, 0xE3, 0x1A, 0x3C, 0xFC, 0x45, 0xEE - }, - { - 0x83, 0x91, 0x7A, 0xC1, 0xCD, 0xAD, 0xE8, 0xF0, - 0xE3, 0xBF, 0x42, 0x6F, 0xEA, 0xC1, 0x38, 0x8B, - 0x3F, 0xCB, 0xE3, 0xE1, 0xBF, 0x98, 0x79, 0x8C, - 0x81, 0x58, 0xBF, 0x75, 0x8E, 0x8D, 0x5D, 0x4E - }, - { - 0xDC, 0x8E, 0xB0, 0xC0, 0x13, 0xFA, 0x9D, 0x06, - 0x4E, 0xE3, 0x76, 0x23, 0x36, 0x9F, 0xB3, 0x94, - 0xAF, 0x97, 0x4B, 0x1A, 0xAC, 0x82, 0x40, 0x5B, - 0x88, 0x97, 0x6C, 0xD8, 0xFC, 0xA1, 0x25, 0x30 - }, - { - 0x9A, 0xF4, 0xFC, 0x92, 0xEA, 0x8D, 0x6B, 0x5F, - 0xE7, 0x99, 0x0E, 0x3A, 0x02, 0x70, 0x1E, 0xC2, - 0x2B, 0x2D, 0xFD, 0x71, 0x00, 0xB9, 0x0D, 0x05, - 0x51, 0x86, 0x94, 0x17, 0x95, 0x5E, 0x44, 0xC8 - }, - { - 0xC7, 0x22, 0xCE, 0xC1, 0x31, 0xBA, 0xA1, 0x63, - 0xF4, 0x7E, 0x4B, 0x33, 0x9E, 0x1F, 0xB9, 0xB4, - 0xAC, 0xA2, 0x48, 0xC4, 0x75, 0x93, 0x45, 0xEA, - 0xDB, 0xD6, 0xC6, 0xA7, 0xDD, 0xB5, 0x04, 0x77 - }, - { - 0x18, 0x37, 0xB1, 0x20, 0xD4, 0xE4, 0x04, 0x6C, - 0x6D, 0xE8, 0xCC, 0xAF, 0x09, 0xF1, 0xCA, 0xF3, - 0x02, 0xAD, 0x56, 0x23, 0x4E, 0x6B, 0x42, 0x2C, - 0xE9, 0x0A, 0x61, 0xBF, 0x06, 0xAE, 0xE4, 0x3D - }, - { - 0x87, 0xAC, 0x9D, 0x0F, 0x8A, 0x0B, 0x11, 0xBF, - 0xED, 0xD6, 0x99, 0x1A, 0x6D, 0xAF, 0x34, 0xC8, - 0xAA, 0x5D, 0x7E, 0x8A, 0xE1, 0xB9, 0xDF, 0x4A, - 0xF7, 0x38, 0x00, 0x5F, 0xE7, 0x8C, 0xE9, 0x3C - }, - { - 0xE2, 0x1F, 0xB6, 0x68, 0xEB, 0xB8, 0xBF, 0x2D, - 0x82, 0x08, 0x6D, 0xED, 0xCB, 0x3A, 0x53, 0x71, - 0xC2, 0xC4, 0x6F, 0xA1, 0xAC, 0x11, 0xD2, 0xE2, - 0xC5, 0x66, 0xD1, 0x4A, 0xD3, 0xC3, 0x65, 0x3F - }, - { - 0x5A, 0x9A, 0x69, 0x81, 0x5E, 0x4D, 0x3E, 0xB7, - 0x72, 0xED, 0x90, 0x8F, 0xE6, 0x58, 0xCE, 0x50, - 0x87, 0x31, 0x0E, 0xC1, 0xD5, 0x0C, 0xB9, 0x4F, - 0x56, 0x28, 0x33, 0x9A, 0x61, 0xDC, 0xD9, 0xEE - }, - { - 0xAA, 0xC2, 0x85, 0xF1, 0x20, 0x8F, 0x70, 0xA6, - 0x47, 0x97, 0xD0, 0xA9, 0x40, 0x0D, 0xA6, 0x46, - 0x53, 0x30, 0x18, 0x38, 0xFE, 0xF6, 0x69, 0x0B, - 0x87, 0xCD, 0xA9, 0x15, 0x9E, 0xE0, 0x7E, 0xF4 - }, - { - 0x05, 0x64, 0x3C, 0x1C, 0x6F, 0x26, 0x59, 0x25, - 0xA6, 0x50, 0x93, 0xF9, 0xDE, 0x8A, 0x19, 0x1C, - 0x4F, 0x6F, 0xD1, 0x41, 0x8F, 0xBF, 0x66, 0xBE, - 0x80, 0x59, 0xA9, 0x1B, 0xA8, 0xDC, 0xDA, 0x61 - }, - { - 0x1C, 0x6C, 0xDE, 0x5B, 0x78, 0x10, 0x3C, 0x9E, - 0x6F, 0x04, 0x6D, 0xFE, 0x30, 0xF5, 0x12, 0x1C, - 0xF9, 0xD4, 0x03, 0x9E, 0xFE, 0x22, 0x25, 0x40, - 0xA4, 0x1B, 0xBC, 0x06, 0xE4, 0x69, 0xFE, 0xB6 - }, - { - 0xB4, 0x9B, 0xB4, 0x6D, 0x1B, 0x19, 0x3B, 0x04, - 0x5E, 0x74, 0x12, 0x05, 0x9F, 0xE7, 0x2D, 0x55, - 0x25, 0x52, 0xA8, 0xFB, 0x6C, 0x36, 0x41, 0x07, - 0x23, 0xDC, 0x7D, 0x05, 0xFC, 0xCE, 0xDE, 0xD3 - }, - { - 0xB6, 0x12, 0xD3, 0xD2, 0x1F, 0xC4, 0xDE, 0x3C, - 0x79, 0x1A, 0xF7, 0x35, 0xE5, 0x9F, 0xB7, 0x17, - 0xD8, 0x39, 0x72, 0x3B, 0x42, 0x50, 0x8E, 0x9E, - 0xBF, 0x78, 0x06, 0xD9, 0x3E, 0x9C, 0x83, 0x7F - }, - { - 0x7C, 0x33, 0x90, 0xA3, 0xE5, 0xCB, 0x27, 0xD1, - 0x86, 0x8B, 0xA4, 0x55, 0xCF, 0xEB, 0x32, 0x22, - 0xFD, 0xE2, 0x7B, 0xCD, 0xA4, 0xBF, 0x24, 0x8E, - 0x3D, 0x29, 0xCF, 0x1F, 0x34, 0x32, 0x9F, 0x25 - }, - { - 0xBD, 0x42, 0xEE, 0xA7, 0xB3, 0x54, 0x86, 0xCD, - 0xD0, 0x90, 0x7C, 0xB4, 0x71, 0x2E, 0xDE, 0x2F, - 0x4D, 0xEE, 0xCC, 0xBC, 0xA1, 0x91, 0x60, 0x38, - 0x65, 0xA1, 0xCC, 0x80, 0x9F, 0x12, 0xB4, 0x46 - }, - { - 0xD1, 0xDD, 0x62, 0x01, 0x74, 0x0C, 0xFA, 0xAD, - 0x53, 0xCE, 0xCC, 0xB7, 0x56, 0xB1, 0x10, 0xF3, - 0xD5, 0x0F, 0x81, 0x7B, 0x43, 0xD7, 0x55, 0x95, - 0x57, 0xE5, 0x7A, 0xAD, 0x14, 0x3A, 0x85, 0xD9 - }, - { - 0x58, 0x29, 0x64, 0x3C, 0x1B, 0x10, 0xE1, 0xC8, - 0xCC, 0xF2, 0x0C, 0x9B, 0x4A, 0xF8, 0x21, 0xEA, - 0x05, 0x2D, 0x7F, 0x0F, 0x7C, 0x22, 0xF7, 0x38, - 0x0B, 0xBB, 0xCF, 0xAF, 0xB9, 0x77, 0xE2, 0x1F - }, - { - 0xFC, 0x4C, 0xF2, 0xA7, 0xFB, 0xE0, 0xB1, 0xE8, - 0xAE, 0xFB, 0xE4, 0xB4, 0xB7, 0x9E, 0xD8, 0x4E, - 0xC9, 0x7B, 0x03, 0x4F, 0x51, 0xB4, 0xE9, 0x7F, - 0x76, 0x0B, 0x20, 0x63, 0x97, 0x65, 0xB9, 0x33 - }, - { - 0x4D, 0x7C, 0x3B, 0x34, 0x38, 0xA0, 0xBD, 0xA2, - 0x8E, 0x7A, 0x96, 0xE4, 0x20, 0x27, 0xD8, 0x13, - 0xE8, 0x8A, 0xE6, 0x28, 0x85, 0x49, 0x98, 0x33, - 0xD3, 0xC5, 0xF6, 0x35, 0x9E, 0xF7, 0xED, 0xBC - }, - { - 0x34, 0xCB, 0xD3, 0x20, 0x68, 0xEF, 0x7E, 0x82, - 0x09, 0x9E, 0x58, 0x0B, 0xF9, 0xE2, 0x64, 0x23, - 0xE9, 0x81, 0xE3, 0x1B, 0x1B, 0xBC, 0xE6, 0x1A, - 0xEA, 0xB1, 0x4C, 0x32, 0xA2, 0x73, 0xE4, 0xCB - }, - { - 0xA0, 0x5D, 0xDA, 0x7D, 0x0D, 0xA9, 0xE0, 0x94, - 0xAE, 0x22, 0x53, 0x3F, 0x79, 0xE7, 0xDC, 0xCD, - 0x26, 0xB1, 0x75, 0x7C, 0xEF, 0xB9, 0x5B, 0xCF, - 0x62, 0xC4, 0xFF, 0x9C, 0x26, 0x92, 0xE1, 0xC0 - }, - { - 0x22, 0x4C, 0xCF, 0xFA, 0x7C, 0xCA, 0x4C, 0xE3, - 0x4A, 0xFD, 0x47, 0xF6, 0x2A, 0xDE, 0x53, 0xC5, - 0xE8, 0x48, 0x9B, 0x04, 0xAC, 0x9C, 0x41, 0xF7, - 0xFA, 0xD0, 0xC8, 0xED, 0xEB, 0x89, 0xE9, 0x41 - }, - { - 0x6B, 0xC6, 0x07, 0x64, 0x83, 0xAA, 0x11, 0xC0, - 0x7F, 0xBA, 0x55, 0xC0, 0xF9, 0xA1, 0xB5, 0xDA, - 0x87, 0xEC, 0xBF, 0xFE, 0xA7, 0x55, 0x98, 0xCC, - 0x31, 0x8A, 0x51, 0x4C, 0xEC, 0x7B, 0x3B, 0x6A - }, - { - 0x9A, 0x03, 0x60, 0xE2, 0x3A, 0x22, 0xF4, 0xF7, - 0x6C, 0x0E, 0x95, 0x28, 0xDA, 0xFD, 0x12, 0x9B, - 0xB4, 0x67, 0x5F, 0xB8, 0x8D, 0x44, 0xEA, 0xF8, - 0x57, 0x77, 0x30, 0x0C, 0xEC, 0x9B, 0xCC, 0x79 - }, - { - 0x79, 0x01, 0x99, 0xB4, 0xCA, 0x90, 0xDE, 0xDC, - 0xCF, 0xE3, 0x24, 0x74, 0xE8, 0x5B, 0x17, 0x4F, - 0x06, 0x9E, 0x35, 0x42, 0xBE, 0x31, 0x04, 0xC1, - 0x12, 0x5C, 0x2F, 0xDB, 0xD6, 0x9D, 0x32, 0xC7 - }, - { - 0x55, 0x83, 0x99, 0x25, 0x83, 0x4C, 0xA3, 0xE8, - 0x25, 0xE9, 0x92, 0x41, 0x87, 0x4D, 0x16, 0xD6, - 0xC2, 0x62, 0x36, 0x29, 0xC4, 0xC2, 0xAD, 0xDD, - 0xF0, 0xDB, 0xA0, 0x1E, 0x6C, 0xE8, 0xA0, 0xDC - }, - { - 0x61, 0x5F, 0xF8, 0x46, 0xD9, 0x93, 0x00, 0x7D, - 0x38, 0xDE, 0x1A, 0xEC, 0xB3, 0x17, 0x82, 0x89, - 0xDE, 0xD0, 0x9E, 0x6B, 0xB5, 0xCB, 0xD6, 0x0F, - 0x69, 0xC6, 0xAA, 0x36, 0x38, 0x30, 0x20, 0xF7 - }, - { - 0xF0, 0xE4, 0x0B, 0x4E, 0xD4, 0x0D, 0x34, 0x85, - 0x1E, 0x72, 0xB4, 0xEE, 0x4D, 0x00, 0xEA, 0x6A, - 0x40, 0xEA, 0x1C, 0x1B, 0xF9, 0xE5, 0xC2, 0x69, - 0x71, 0x0C, 0x9D, 0x51, 0xCB, 0xB8, 0xA3, 0xC9 - }, - { - 0x0B, 0x07, 0xB2, 0x33, 0x3B, 0x08, 0xD0, 0x8C, - 0x11, 0xCA, 0x34, 0xAB, 0x44, 0x9B, 0x71, 0xD2, - 0x9A, 0x0F, 0x43, 0xE1, 0xF7, 0x78, 0xE0, 0x73, - 0xE7, 0x90, 0x06, 0xCC, 0xB7, 0x30, 0xED, 0x62 - }, - { - 0xD1, 0xF4, 0xC2, 0x9D, 0x9F, 0x23, 0xEA, 0x35, - 0xEC, 0x40, 0x35, 0xB3, 0x77, 0xD5, 0x06, 0x53, - 0x8E, 0x72, 0x8B, 0xC7, 0x39, 0xC1, 0x45, 0x96, - 0x80, 0xCF, 0x1C, 0xC6, 0x94, 0x24, 0x92, 0x4D - }, - { - 0x12, 0x79, 0xCF, 0x6F, 0x66, 0x9F, 0x92, 0xF6, - 0xBF, 0xC2, 0x5D, 0x60, 0x5B, 0x94, 0x40, 0xC7, - 0xDC, 0xCB, 0xD2, 0x5D, 0xF2, 0x8D, 0xC7, 0x35, - 0x3A, 0xBC, 0x1C, 0x05, 0x30, 0x40, 0x5D, 0xC4 - }, - { - 0x1F, 0xA0, 0xAF, 0x00, 0x77, 0x5D, 0xC2, 0xCE, - 0x76, 0x50, 0x6D, 0x32, 0x80, 0xF4, 0x72, 0xD2, - 0xF6, 0xFF, 0x97, 0xA2, 0x15, 0x1F, 0xAA, 0x82, - 0x79, 0x42, 0xFE, 0xA4, 0x4A, 0xD0, 0xBA, 0x1F - }, - { - 0x3E, 0x1A, 0xD5, 0x4A, 0x5F, 0x83, 0x5B, 0x98, - 0x3B, 0xD2, 0xAA, 0xB0, 0xED, 0x2A, 0x4C, 0x0B, - 0xDD, 0x72, 0x16, 0x20, 0x9C, 0x36, 0xA7, 0x9E, - 0x9E, 0x2A, 0xAB, 0xB9, 0x9F, 0xAF, 0x35, 0x12 - }, - { - 0xC6, 0xED, 0x39, 0xE2, 0xD8, 0xB6, 0x36, 0xEC, - 0xCB, 0xA2, 0x45, 0xEF, 0x4E, 0x88, 0x64, 0xF4, - 0xCD, 0x94, 0x6B, 0xE2, 0x16, 0xB9, 0xBE, 0x48, - 0x30, 0x3E, 0x08, 0xB9, 0x2D, 0xD0, 0x94, 0x34 - }, - { - 0xE2, 0x47, 0x36, 0xC1, 0x3E, 0xCB, 0x9F, 0x36, - 0xA0, 0xD8, 0x29, 0xD4, 0x79, 0x8D, 0x76, 0x99, - 0xC1, 0x4C, 0xC6, 0x5B, 0x6D, 0xC4, 0x4E, 0xD6, - 0xF1, 0x0C, 0xD4, 0x85, 0x3D, 0x6E, 0x07, 0x57 - }, - { - 0x38, 0x9B, 0xE8, 0x80, 0x52, 0xA3, 0x81, 0x27, - 0x2C, 0x6D, 0xF7, 0x41, 0xA8, 0x8A, 0xD3, 0x49, - 0xB7, 0x12, 0x71, 0x84, 0x35, 0x48, 0x0A, 0x81, - 0x90, 0xB7, 0x04, 0x77, 0x1D, 0x2D, 0xE6, 0x37 - }, - { - 0x88, 0x9F, 0x2D, 0x57, 0x8A, 0x5D, 0xAE, 0xFD, - 0x34, 0x1C, 0x21, 0x09, 0x84, 0xE1, 0x26, 0xD1, - 0xD9, 0x6D, 0xA2, 0xDE, 0xE3, 0xC8, 0x1F, 0x7A, - 0x60, 0x80, 0xBF, 0x84, 0x56, 0x9B, 0x31, 0x14 - }, - { - 0xE9, 0x36, 0x09, 0x5B, 0x9B, 0x98, 0x2F, 0xFC, - 0x85, 0x6D, 0x2F, 0x52, 0x76, 0xA4, 0xE5, 0x29, - 0xEC, 0x73, 0x95, 0xDA, 0x31, 0x6D, 0x62, 0x87, - 0x02, 0xFB, 0x28, 0x1A, 0xDA, 0x6F, 0x38, 0x99 - }, - { - 0xEF, 0x89, 0xCE, 0x1D, 0x6F, 0x8B, 0x48, 0xEA, - 0x5C, 0xD6, 0xAE, 0xAB, 0x6A, 0x83, 0xD0, 0xCC, - 0x98, 0xC9, 0xA3, 0xA2, 0x07, 0xA1, 0x08, 0x57, - 0x32, 0xF0, 0x47, 0xD9, 0x40, 0x38, 0xC2, 0x88 - }, - { - 0xF9, 0x25, 0x01, 0x6D, 0x79, 0xF2, 0xAC, 0xA8, - 0xC4, 0x9E, 0xDF, 0xCD, 0x66, 0x21, 0xD5, 0xBE, - 0x3C, 0x8C, 0xEC, 0x61, 0xBD, 0x58, 0x71, 0xD8, - 0xC1, 0xD3, 0xA5, 0x65, 0xF3, 0x5E, 0x0C, 0x9F - }, - { - 0x63, 0xE8, 0x63, 0x4B, 0x75, 0x7A, 0x38, 0xF9, - 0x2B, 0x92, 0xFD, 0x23, 0x89, 0x3B, 0xA2, 0x99, - 0x85, 0x3A, 0x86, 0x13, 0x67, 0x9F, 0xDF, 0x7E, - 0x05, 0x11, 0x09, 0x5C, 0x0F, 0x04, 0x7B, 0xCA - }, - { - 0xCF, 0x2C, 0xCA, 0x07, 0x72, 0xB7, 0x05, 0xEB, - 0x57, 0xD2, 0x89, 0x43, 0xF8, 0x3D, 0x35, 0x3F, - 0xE2, 0x91, 0xE5, 0xB3, 0x77, 0x78, 0x0B, 0x37, - 0x4C, 0x8B, 0xA4, 0x66, 0x58, 0x30, 0xBE, 0x87 - }, - { - 0x46, 0xDF, 0x5B, 0x87, 0xC8, 0x0E, 0x7E, 0x40, - 0x74, 0xAE, 0xE6, 0x85, 0x59, 0x42, 0x47, 0x42, - 0x84, 0x5B, 0x9B, 0x35, 0x0F, 0x51, 0xBA, 0x55, - 0xB0, 0x74, 0xBB, 0xAE, 0x4C, 0x62, 0x6A, 0xAB - }, - { - 0x65, 0x8A, 0xA4, 0xF9, 0xD2, 0xBC, 0xBD, 0x4F, - 0x7F, 0x8E, 0xB6, 0x3E, 0x68, 0xF5, 0x36, 0x7E, - 0xDB, 0xC5, 0x00, 0xA0, 0xB1, 0xFB, 0xB4, 0x1E, - 0x9D, 0xF1, 0x41, 0xBC, 0xBA, 0x8F, 0xCD, 0x53 - }, - { - 0xEE, 0x80, 0x55, 0x50, 0x08, 0xA7, 0x16, 0x55, - 0xE0, 0x81, 0x09, 0x2B, 0xBA, 0x6F, 0x67, 0x0E, - 0xD9, 0x8A, 0xF9, 0xA0, 0x9F, 0xB5, 0xAF, 0xB9, - 0x4C, 0xBC, 0x5C, 0x75, 0x48, 0x14, 0xDB, 0x4F - }, - { - 0x2C, 0x5F, 0x9D, 0x04, 0x82, 0x20, 0xB0, 0x41, - 0xB6, 0xD4, 0x52, 0x4B, 0x44, 0x90, 0xCF, 0x8C, - 0x66, 0xFC, 0xB8, 0xE1, 0x4B, 0x0D, 0x64, 0x88, - 0x7A, 0xA1, 0xE4, 0x76, 0x1A, 0x60, 0x2B, 0x39 - }, - { - 0x44, 0xCB, 0x63, 0x11, 0xD0, 0x75, 0x0B, 0x7E, - 0x33, 0xF7, 0x33, 0x3A, 0xA7, 0x8A, 0xAC, 0xA9, - 0xC3, 0x4A, 0xD5, 0xF7, 0x9C, 0x1B, 0x15, 0x91, - 0xEC, 0x33, 0x95, 0x1E, 0x69, 0xC4, 0xC4, 0x61 - }, - { - 0x0C, 0x6C, 0xE3, 0x2A, 0x3E, 0xA0, 0x56, 0x12, - 0xC5, 0xF8, 0x09, 0x0F, 0x6A, 0x7E, 0x87, 0xF5, - 0xAB, 0x30, 0xE4, 0x1B, 0x70, 0x7D, 0xCB, 0xE5, - 0x41, 0x55, 0x62, 0x0A, 0xD7, 0x70, 0xA3, 0x40 - }, - { - 0xC6, 0x59, 0x38, 0xDD, 0x3A, 0x05, 0x3C, 0x72, - 0x9C, 0xF5, 0xB7, 0xC8, 0x9F, 0x39, 0x0B, 0xFE, - 0xBB, 0x51, 0x12, 0x76, 0x6B, 0xB0, 0x0A, 0xA5, - 0xFA, 0x31, 0x64, 0xDF, 0xDF, 0x3B, 0x56, 0x47 - }, - { - 0x7D, 0xE7, 0xF0, 0xD5, 0x9A, 0x90, 0x39, 0xAF, - 0xF3, 0xAA, 0xF3, 0x2C, 0x3E, 0xE5, 0x2E, 0x79, - 0x17, 0x53, 0x57, 0x29, 0x06, 0x21, 0x68, 0xD2, - 0x49, 0x0B, 0x6B, 0x6C, 0xE2, 0x44, 0xB3, 0x80 - }, - { - 0x89, 0x58, 0x98, 0xF5, 0x3A, 0x8F, 0x39, 0xE4, - 0x24, 0x10, 0xDA, 0x77, 0xB6, 0xC4, 0x81, 0x5B, - 0x0B, 0xB2, 0x39, 0x5E, 0x39, 0x22, 0xF5, 0xBE, - 0xD0, 0xE1, 0xFB, 0xF2, 0xA4, 0xC6, 0xDF, 0xEB - }, - { - 0xC9, 0x05, 0xA8, 0x49, 0x84, 0x34, 0x8A, 0x64, - 0xDB, 0x1F, 0x54, 0x20, 0x83, 0x74, 0x8A, 0xD9, - 0x0A, 0x4B, 0xAD, 0x98, 0x33, 0xCB, 0x6D, 0xA3, - 0x87, 0x29, 0x34, 0x31, 0xF1, 0x9E, 0x7C, 0x9C - }, - { - 0xED, 0x37, 0xD1, 0xA4, 0xD0, 0x6C, 0x90, 0xD1, - 0x95, 0x78, 0x48, 0x66, 0x7E, 0x95, 0x48, 0xFE, - 0xBB, 0x5D, 0x42, 0x3E, 0xAB, 0x4F, 0x56, 0x78, - 0x5C, 0xC4, 0xB5, 0x41, 0x6B, 0x78, 0x00, 0x08 - }, - { - 0x0B, 0xC6, 0x5D, 0x99, 0x97, 0xFB, 0x73, 0x4A, - 0x56, 0x1F, 0xB1, 0xE9, 0xF8, 0xC0, 0x95, 0x8A, - 0x02, 0xC7, 0xA4, 0xDB, 0xD0, 0x96, 0xEB, 0xEF, - 0x1A, 0x17, 0x51, 0xAE, 0xD9, 0x59, 0xEE, 0xD7 - }, - { - 0x7C, 0x5F, 0x43, 0x2E, 0xB8, 0xB7, 0x35, 0x2A, - 0x94, 0x94, 0xDE, 0xA4, 0xD5, 0x3C, 0x21, 0x38, - 0x70, 0x31, 0xCE, 0x70, 0xE8, 0x5D, 0x94, 0x08, - 0xFC, 0x6F, 0x8C, 0xD9, 0x8A, 0x6A, 0xAA, 0x1E - }, - { - 0xB8, 0xBF, 0x8E, 0x2C, 0x34, 0xE0, 0x33, 0x98, - 0x36, 0x39, 0x90, 0x9E, 0xAA, 0x37, 0x64, 0x0D, - 0x87, 0x7B, 0x04, 0x8F, 0xE2, 0x99, 0xB4, 0x70, - 0xAF, 0x2D, 0x0B, 0xA8, 0x2A, 0x5F, 0x14, 0xC0 - }, - { - 0x88, 0xA9, 0xDD, 0x13, 0xD5, 0xDA, 0xDB, 0xDE, - 0xE6, 0xBF, 0xF7, 0xEE, 0x1E, 0xF8, 0xC7, 0x1C, - 0xC1, 0x93, 0xAA, 0x4B, 0xF3, 0xE8, 0x4F, 0x8F, - 0xE8, 0x0C, 0xB0, 0x75, 0x68, 0x3C, 0x07, 0x79 - }, - { - 0x9A, 0xED, 0xB8, 0x87, 0x6D, 0xD2, 0x1C, 0x8C, - 0x84, 0xD2, 0xE7, 0x02, 0xA1, 0x36, 0x25, 0x98, - 0x04, 0x62, 0xF6, 0x8B, 0xF0, 0xA1, 0xB7, 0x25, - 0x4A, 0xD8, 0x06, 0xC3, 0x84, 0x03, 0xC9, 0xDE - }, - { - 0xD0, 0x97, 0x57, 0x3D, 0xF2, 0xD6, 0xB2, 0x48, - 0x9A, 0x47, 0x94, 0x84, 0x86, 0x98, 0x00, 0xA1, - 0xF8, 0x33, 0xEA, 0x16, 0x9E, 0xFF, 0x32, 0xAE, - 0x3C, 0xE6, 0x3A, 0x20, 0x79, 0x54, 0x8D, 0x78 - }, - { - 0xD1, 0x8F, 0x27, 0xA3, 0xE5, 0x55, 0xD7, 0xF9, - 0x1A, 0x00, 0x7C, 0x67, 0xAC, 0xEE, 0xDE, 0x39, - 0x1F, 0x75, 0xA6, 0x1F, 0xA4, 0x2A, 0x0B, 0x45, - 0x66, 0xEB, 0x58, 0x2C, 0xA0, 0x5E, 0xBC, 0xE7 - }, - { - 0xDF, 0x1D, 0xAA, 0x90, 0xB1, 0x70, 0x23, 0x13, - 0xE6, 0xA5, 0x90, 0x1C, 0x7A, 0xFC, 0x5E, 0xD9, - 0x65, 0x77, 0x17, 0xA7, 0x15, 0xFA, 0x53, 0xA4, - 0x18, 0x9E, 0xC1, 0xE5, 0xDF, 0x29, 0x3A, 0x68 - }, - { - 0x04, 0xE3, 0xA4, 0x96, 0xB6, 0x69, 0x96, 0xC6, - 0x6E, 0x32, 0x91, 0x9E, 0xD1, 0xF9, 0x4C, 0x36, - 0xEE, 0xBB, 0xF2, 0x40, 0x63, 0x3A, 0x2F, 0x73, - 0x98, 0x45, 0xF0, 0x29, 0x5D, 0x34, 0xAF, 0xBA - }, - { - 0x8C, 0x45, 0xD8, 0x8C, 0x4E, 0x9C, 0x9D, 0x0C, - 0x8C, 0x67, 0x7F, 0xE4, 0x8F, 0xA5, 0x44, 0x9B, - 0xA3, 0x01, 0x78, 0xD4, 0x0A, 0xF0, 0xF0, 0x21, - 0x79, 0x21, 0xC6, 0x2E, 0x4B, 0x60, 0xCD, 0xD3 - }, - { - 0xE1, 0x49, 0xA6, 0xB1, 0x3B, 0xDE, 0xDE, 0xA2, - 0xEE, 0xEE, 0x00, 0x9C, 0xE9, 0x44, 0x5E, 0x8D, - 0xCF, 0x76, 0xB7, 0x6E, 0x55, 0xA5, 0x01, 0xD8, - 0xF5, 0xB4, 0x3F, 0xF8, 0x96, 0x79, 0x6A, 0xD1 - }, - { - 0xA8, 0x37, 0xC4, 0xC7, 0xC6, 0xF5, 0xCF, 0xB9, - 0x9E, 0x10, 0x85, 0xFD, 0x43, 0x28, 0x7A, 0x41, - 0x05, 0xCB, 0x28, 0xB7, 0x6F, 0xC3, 0x8B, 0x60, - 0x55, 0xC5, 0xDC, 0xFF, 0x78, 0xB8, 0x25, 0x65 - }, - { - 0x42, 0x41, 0x1F, 0x28, 0x78, 0x0B, 0x4F, 0x16, - 0x38, 0x54, 0x0B, 0x87, 0x05, 0x21, 0xEC, 0x45, - 0xBC, 0xEB, 0x1E, 0x0C, 0x71, 0x31, 0xF7, 0xE1, - 0xC4, 0x67, 0x2E, 0x43, 0x6C, 0x88, 0xC8, 0xE9 - }, - { - 0x34, 0xB4, 0xE8, 0x76, 0x76, 0x94, 0x71, 0xDF, - 0x55, 0x2E, 0x55, 0x22, 0xCE, 0xA7, 0x84, 0xFA, - 0x53, 0xAC, 0x61, 0xBE, 0xDE, 0x8C, 0xFE, 0x29, - 0x14, 0x09, 0xE6, 0x8B, 0x69, 0xE8, 0x77, 0x6F - }, - { - 0x8F, 0x31, 0xD6, 0x37, 0xA9, 0x1D, 0xBD, 0x0E, - 0xCB, 0x0B, 0xA0, 0xE6, 0x94, 0xBE, 0xC1, 0x44, - 0x76, 0x58, 0xCE, 0x6C, 0x27, 0xEA, 0x9B, 0x95, - 0xFF, 0x36, 0x70, 0x1C, 0xAF, 0x36, 0xF0, 0x01 - }, - { - 0xB5, 0xC8, 0x95, 0xEB, 0x07, 0x1E, 0x3D, 0x38, - 0x52, 0x8D, 0x47, 0x5D, 0x3B, 0xB0, 0xBA, 0x88, - 0xB7, 0x17, 0x95, 0xE4, 0x0A, 0x98, 0x2E, 0x2A, - 0xC2, 0xD8, 0x44, 0x22, 0xA0, 0xF2, 0x68, 0x5D - }, - { - 0xE9, 0x06, 0x25, 0x7C, 0x41, 0x9D, 0x94, 0x1E, - 0xD2, 0xB8, 0xA9, 0xC1, 0x27, 0x81, 0xDB, 0x97, - 0x59, 0xA3, 0xFC, 0xF3, 0xDC, 0x7C, 0xDB, 0x03, - 0x15, 0x99, 0xE1, 0x08, 0x6B, 0x67, 0x2F, 0x10 - }, - { - 0x98, 0xAD, 0x24, 0x39, 0x7C, 0x6E, 0xAE, 0x4C, - 0xF7, 0x3E, 0xA8, 0xBB, 0xEF, 0x5A, 0x0B, 0x74, - 0xD2, 0x1A, 0xD1, 0x5F, 0x33, 0x92, 0x0F, 0x44, - 0x07, 0x0A, 0x98, 0xBD, 0xF5, 0x3D, 0x0B, 0x3A - }, - { - 0xDD, 0x51, 0x0C, 0xA5, 0x5B, 0x11, 0x70, 0xF9, - 0xCE, 0xFD, 0xBB, 0x16, 0xFC, 0x14, 0x52, 0x62, - 0xAA, 0x36, 0x3A, 0x87, 0x0A, 0x01, 0xE1, 0xBC, - 0x4F, 0xBE, 0x40, 0x23, 0x4B, 0x4B, 0x6F, 0x2F - }, - { - 0xF2, 0xD8, 0xD9, 0x31, 0xB9, 0x2E, 0x1C, 0xB6, - 0x98, 0xE5, 0x6E, 0xD0, 0x28, 0x19, 0xEA, 0x11, - 0xD2, 0x66, 0x19, 0xB8, 0x3A, 0x62, 0x09, 0xAD, - 0x67, 0x22, 0x53, 0x68, 0xFE, 0x11, 0x95, 0x71 - }, - { - 0xE4, 0x63, 0x70, 0x55, 0xDB, 0x91, 0xF9, 0x43, - 0x7C, 0xF4, 0x60, 0xEF, 0x40, 0xB5, 0x14, 0x5F, - 0x69, 0x98, 0x26, 0x6A, 0x5E, 0x74, 0xE9, 0x6A, - 0x00, 0x78, 0x2C, 0x62, 0xCF, 0x30, 0xCF, 0x1C - }, - { - 0x35, 0x63, 0x53, 0x0A, 0x89, 0xD3, 0x2B, 0x75, - 0xF7, 0x8D, 0x83, 0xE9, 0x87, 0x2A, 0xD4, 0xC5, - 0x75, 0xF5, 0x20, 0x39, 0x9D, 0x65, 0x03, 0x5D, - 0xED, 0x99, 0xE5, 0xEE, 0xC5, 0x80, 0x71, 0x50 - }, - { - 0x8E, 0x79, 0xF9, 0x2C, 0x86, 0x5B, 0xEB, 0x3E, - 0x1C, 0xDB, 0xF0, 0x8F, 0x75, 0x4A, 0x26, 0x06, - 0xE8, 0x53, 0x49, 0x05, 0x3D, 0x66, 0xD6, 0x16, - 0x02, 0x4A, 0x81, 0x3F, 0xCA, 0x54, 0x1A, 0x4D - }, - { - 0x86, 0x42, 0x26, 0xF2, 0x83, 0x9C, 0x76, 0xB1, - 0xD5, 0xF7, 0xC1, 0x3D, 0x98, 0xC2, 0xA5, 0x15, - 0x8C, 0x2A, 0xBB, 0x71, 0xD9, 0xD8, 0xF0, 0xFA, - 0x1F, 0x7C, 0x3F, 0x74, 0x68, 0x00, 0x16, 0x03 - }, - { - 0xD3, 0xE3, 0xF5, 0xB8, 0xCE, 0xEB, 0xB1, 0x11, - 0x84, 0x80, 0x35, 0x35, 0x90, 0x0B, 0x6E, 0xED, - 0xDA, 0x60, 0x6E, 0xEB, 0x36, 0x97, 0x51, 0xA7, - 0xCD, 0xA3, 0x6C, 0xA3, 0x02, 0x29, 0xFB, 0x02 - }, - { - 0x8C, 0x7D, 0x6B, 0x98, 0x72, 0x69, 0x16, 0x90, - 0x31, 0xF7, 0x1F, 0xD7, 0xE4, 0xC4, 0x45, 0x01, - 0x2D, 0x3E, 0x6A, 0x3C, 0x88, 0x09, 0xF6, 0x47, - 0x9B, 0xD6, 0x67, 0xCF, 0x31, 0x1E, 0x27, 0x6E - }, - { - 0xB9, 0x04, 0xB5, 0x71, 0x1B, 0xF1, 0x9E, 0x85, - 0x32, 0xF7, 0xAD, 0x64, 0x27, 0x41, 0x0A, 0x62, - 0xA1, 0xF7, 0x7F, 0x77, 0xB9, 0xB6, 0xD7, 0x1D, - 0x2F, 0xC4, 0x3B, 0xC9, 0x0F, 0x73, 0x23, 0x5A - }, - { - 0x45, 0x36, 0x63, 0x43, 0x15, 0xC8, 0x67, 0x28, - 0xF5, 0xAB, 0x74, 0x49, 0xEB, 0x2D, 0x04, 0x02, - 0x0E, 0x9E, 0xAE, 0x8D, 0xD6, 0x79, 0x55, 0x00, - 0xE9, 0xEC, 0x9A, 0x00, 0x66, 0x38, 0x6E, 0x69 - }, - { - 0xFD, 0x5E, 0x49, 0xFE, 0xD4, 0x9D, 0xC4, 0x4B, - 0xDE, 0x89, 0xF4, 0x60, 0xA9, 0x50, 0x19, 0x1E, - 0xBB, 0x06, 0x7C, 0x69, 0x8A, 0x3F, 0x21, 0xEA, - 0x14, 0x30, 0x8C, 0x74, 0x13, 0xB9, 0x16, 0x81 - }, - { - 0x31, 0xF0, 0x1D, 0x03, 0x0B, 0x9B, 0x22, 0xD0, - 0x0A, 0x0F, 0x71, 0xED, 0x2C, 0xEB, 0x5D, 0x2D, - 0xC8, 0x1A, 0xF2, 0xC2, 0x4B, 0xF5, 0x67, 0x0F, - 0xDE, 0x19, 0xA6, 0x85, 0xE8, 0xD1, 0x39, 0x2E - }, - { - 0x5F, 0x84, 0xD9, 0xDE, 0x28, 0x4B, 0x1E, 0x4F, - 0x67, 0x8E, 0x31, 0xAB, 0x6A, 0x76, 0xF5, 0x66, - 0x1B, 0x5A, 0xEA, 0xA7, 0x68, 0x53, 0x93, 0x84, - 0xAA, 0x38, 0xF9, 0xE4, 0x9C, 0xCE, 0x6E, 0x6E - }, - { - 0xB2, 0x07, 0x9E, 0x59, 0x97, 0xA4, 0xEA, 0xD3, - 0xA7, 0x1F, 0xEF, 0xC0, 0x2F, 0x90, 0xA7, 0x48, - 0x3A, 0x10, 0xFD, 0x2E, 0x6F, 0x31, 0xBD, 0xA9, - 0xD2, 0x08, 0x44, 0x85, 0xCC, 0x01, 0x6B, 0xBD - }, - { - 0xE0, 0xF8, 0x4D, 0x7F, 0x52, 0x5B, 0x6F, 0xED, - 0x79, 0x1F, 0x77, 0x28, 0x9A, 0xE5, 0x8F, 0x7D, - 0x50, 0xA2, 0x94, 0x32, 0xD4, 0x2C, 0x25, 0xC1, - 0xE8, 0x39, 0x29, 0xB8, 0x38, 0x89, 0x1D, 0x79 - }, - { - 0x70, 0x46, 0x96, 0x90, 0x95, 0x6D, 0x79, 0x18, - 0xAC, 0xE7, 0xBA, 0x5F, 0x41, 0x30, 0x2D, 0xA1, - 0x38, 0xC9, 0xB5, 0x6E, 0xCD, 0x41, 0x55, 0x44, - 0xFA, 0xCE, 0x8D, 0x99, 0x8C, 0x21, 0xAB, 0xEB - }, - { - 0x45, 0xC9, 0x1A, 0x62, 0x24, 0x9B, 0x39, 0xCD, - 0xA9, 0x4E, 0x50, 0x82, 0x95, 0xBE, 0xC7, 0x66, - 0x71, 0x19, 0x44, 0x77, 0x65, 0xEF, 0x80, 0xEF, - 0xA8, 0x2D, 0x1E, 0x92, 0xD5, 0x70, 0x67, 0xD8 - }, - { - 0x1D, 0x9E, 0x00, 0x73, 0xEE, 0xD0, 0x73, 0x15, - 0x54, 0xC3, 0xBE, 0xAA, 0x47, 0x46, 0x0D, 0x51, - 0x1A, 0xD2, 0x61, 0xDD, 0x4D, 0x4A, 0x3B, 0xED, - 0x9D, 0x8D, 0x20, 0x2F, 0x22, 0xF2, 0x15, 0x89 - }, - { - 0x40, 0x82, 0x62, 0x73, 0x6D, 0x8A, 0xEC, 0x0B, - 0x84, 0x7D, 0xBA, 0x25, 0x02, 0x58, 0x60, 0x8A, - 0x43, 0x45, 0xA6, 0x3A, 0x1E, 0xB1, 0x95, 0xE5, - 0xC7, 0xAE, 0x2E, 0xE8, 0x74, 0xC3, 0x4D, 0xA8 - }, - { - 0x23, 0xD2, 0xB7, 0x04, 0x39, 0x46, 0x99, 0x49, - 0x98, 0x23, 0x90, 0x53, 0x8D, 0x7E, 0x5A, 0xDE, - 0x9F, 0x18, 0xC8, 0xE3, 0xBB, 0xF6, 0x60, 0x5A, - 0xFC, 0xF4, 0x9B, 0x00, 0xC0, 0x61, 0xE8, 0x37 - }, - { - 0x23, 0x2F, 0xB1, 0x87, 0xD2, 0x71, 0xBE, 0xA9, - 0x12, 0xEF, 0xD4, 0x07, 0xFF, 0xE0, 0x80, 0x56, - 0xD6, 0xA4, 0x2E, 0x53, 0x21, 0xEC, 0x79, 0x2D, - 0xF3, 0xD5, 0x84, 0xA9, 0x4F, 0x63, 0x0A, 0xB2 - }, - { - 0x13, 0x8E, 0x19, 0x44, 0xE4, 0xB5, 0x4D, 0xE8, - 0x68, 0x1D, 0x7E, 0x48, 0xC4, 0xF0, 0x81, 0x48, - 0xE4, 0x0A, 0x56, 0x7E, 0x5C, 0xAD, 0x94, 0x6A, - 0x6A, 0xF4, 0xE8, 0xD5, 0xD2, 0x6F, 0x75, 0xC7 - }, - { - 0x80, 0xC1, 0x51, 0x32, 0x5F, 0xBF, 0xC6, 0x78, - 0xB7, 0xBE, 0x4E, 0x40, 0xB3, 0x0F, 0x29, 0xFE, - 0x31, 0xCD, 0xBE, 0x1C, 0x84, 0x12, 0x6E, 0x00, - 0x6D, 0xF3, 0xC1, 0x85, 0x24, 0xBD, 0x2D, 0x6C - }, - { - 0xA6, 0x42, 0x26, 0x73, 0x01, 0x66, 0x9D, 0xF2, - 0x61, 0xB8, 0x39, 0xF8, 0x73, 0x65, 0x76, 0x29, - 0x05, 0xFF, 0x32, 0x0A, 0x0A, 0x2F, 0xC4, 0xBD, - 0xC4, 0x8E, 0x5A, 0x8E, 0x15, 0xD1, 0x32, 0x33 - }, - { - 0x0F, 0x8B, 0x10, 0x99, 0x38, 0x60, 0x93, 0x7A, - 0x74, 0xCC, 0x2D, 0xE4, 0x0A, 0x27, 0x31, 0xDD, - 0x99, 0x54, 0xB6, 0x54, 0xBB, 0x94, 0xC3, 0x4E, - 0x87, 0x66, 0x52, 0xE9, 0x8D, 0x4B, 0xBD, 0x16 - }, - { - 0xE6, 0x34, 0xA5, 0x85, 0x12, 0x49, 0x32, 0x73, - 0x26, 0x0F, 0x10, 0xD4, 0x49, 0x53, 0xCD, 0x99, - 0x8E, 0x34, 0xCB, 0x82, 0x81, 0xC4, 0x1B, 0xF4, - 0x2E, 0x0A, 0xE2, 0xF2, 0x5C, 0xBD, 0x1F, 0x75 - }, - { - 0xBD, 0xE6, 0xAF, 0x9B, 0xAF, 0x3C, 0x07, 0xE9, - 0x54, 0x23, 0xCA, 0xB5, 0x04, 0xDE, 0xE7, 0x0E, - 0xDC, 0xC3, 0x31, 0x8B, 0x22, 0xDD, 0x1E, 0xB6, - 0xFD, 0x85, 0xBE, 0x44, 0x7A, 0xC9, 0xF2, 0x09 - }, - { - 0x91, 0x4B, 0x37, 0xAB, 0x5B, 0x8C, 0xFD, 0xE6, - 0xA4, 0x80, 0x46, 0x6A, 0x0D, 0x82, 0x43, 0x2C, - 0x7D, 0x76, 0x32, 0x8E, 0x9A, 0x88, 0xEF, 0x5B, - 0x4F, 0x52, 0x42, 0x9F, 0x7A, 0x3F, 0xFC, 0x7D - }, - { - 0x55, 0xBE, 0x66, 0xE9, 0xA5, 0xAA, 0x67, 0x1A, - 0x23, 0x88, 0x2E, 0xF3, 0xE7, 0xD9, 0xD3, 0x6E, - 0xA9, 0x54, 0x87, 0xDC, 0x71, 0xB7, 0x25, 0xA5, - 0xAD, 0x4B, 0x79, 0x8A, 0x87, 0x91, 0x43, 0xD0 - }, - { - 0x3F, 0xD0, 0x45, 0x89, 0x4B, 0x83, 0x6E, 0x44, - 0xE9, 0xCA, 0x75, 0xFB, 0xE3, 0xEA, 0xDC, 0x48, - 0x6C, 0xBB, 0xD0, 0xD8, 0xCE, 0xE1, 0xB3, 0xCF, - 0x14, 0xF7, 0x6E, 0x7F, 0x1E, 0x77, 0xAE, 0xF3 - }, - { - 0xCE, 0x60, 0x34, 0x3D, 0xC4, 0x87, 0x4B, 0x66, - 0x04, 0xE1, 0xFB, 0x23, 0x1E, 0x37, 0xEC, 0x1E, - 0xEC, 0x3F, 0x06, 0x56, 0x6E, 0x42, 0x8A, 0xE7, - 0x64, 0xEF, 0xFF, 0xA2, 0x30, 0xAD, 0xD4, 0x85 - }, - { - 0xE3, 0x8C, 0x9D, 0xF0, 0x24, 0xDE, 0x21, 0x53, - 0xD2, 0x26, 0x73, 0x8A, 0x0E, 0x5B, 0xA9, 0xB8, - 0xC6, 0x78, 0x4D, 0xAC, 0xA6, 0x5C, 0x22, 0xA7, - 0x62, 0x8E, 0xB5, 0x8E, 0xA0, 0xD4, 0x95, 0xA7 - }, - { - 0x8D, 0xFE, 0xC0, 0xD4, 0xF3, 0x65, 0x8A, 0x20, - 0xA0, 0xBA, 0xD6, 0x6F, 0x21, 0x60, 0x83, 0x2B, - 0x16, 0x4E, 0x70, 0x0A, 0x21, 0xEC, 0x5A, 0x01, - 0x65, 0xC3, 0x67, 0x72, 0xB2, 0x08, 0x61, 0x11 - }, - { - 0x44, 0x01, 0xB5, 0x0E, 0x09, 0x86, 0x5F, 0x42, - 0x38, 0x24, 0x3B, 0x82, 0x25, 0xCA, 0x40, 0xA0, - 0x8D, 0xBB, 0x46, 0x85, 0xF5, 0xF8, 0x62, 0xFB, - 0xDD, 0x72, 0x98, 0x04, 0x31, 0xA8, 0x5D, 0x3F - }, - { - 0x86, 0x68, 0x94, 0x27, 0x88, 0xC4, 0xCE, 0x8A, - 0x33, 0x19, 0x0F, 0xFC, 0xFA, 0xD1, 0xC6, 0x78, - 0xC4, 0xFA, 0x41, 0xE9, 0x94, 0x17, 0x09, 0x4E, - 0x24, 0x0F, 0x4A, 0x43, 0xF3, 0x87, 0xA3, 0xB6 - }, - { - 0xA7, 0x28, 0x8D, 0x5E, 0x09, 0x80, 0x9B, 0x69, - 0x69, 0x84, 0xEC, 0xD5, 0x32, 0x6C, 0xDD, 0x84, - 0xFB, 0xE3, 0x5F, 0xCF, 0x67, 0x23, 0x5D, 0x81, - 0x1C, 0x82, 0x00, 0x25, 0x36, 0xA3, 0xC5, 0xE1 - }, - { - 0x8E, 0x92, 0x5C, 0x3C, 0x14, 0x6B, 0xAC, 0xF3, - 0x35, 0x1E, 0xC5, 0x32, 0x41, 0xAC, 0xE5, 0xF7, - 0x3E, 0x8F, 0xC9, 0xBD, 0x8C, 0x61, 0xCA, 0xD9, - 0x7F, 0xD7, 0x72, 0xB0, 0x7E, 0x1B, 0x83, 0x73 - }, - { - 0xC7, 0xEB, 0x9E, 0x6D, 0xED, 0x2F, 0x99, 0x3D, - 0x48, 0xB0, 0x17, 0x0D, 0xA2, 0x7C, 0x5B, 0x75, - 0x3B, 0x12, 0x17, 0x6B, 0xE1, 0x26, 0xC7, 0xBA, - 0x2D, 0x6A, 0xF8, 0x5F, 0x85, 0x93, 0xB7, 0x52 - }, - { - 0xCA, 0x27, 0xF1, 0x6F, 0x94, 0xE4, 0xEC, 0x0E, - 0x62, 0x8E, 0x7F, 0x8A, 0xEF, 0xC6, 0x65, 0x7B, - 0xED, 0xC9, 0x37, 0x42, 0x96, 0x59, 0x40, 0xAE, - 0x78, 0x6A, 0x73, 0xB5, 0xFD, 0x59, 0x3B, 0x97 - }, - { - 0x8C, 0x21, 0xE6, 0x56, 0x8B, 0xC6, 0xDC, 0x00, - 0xE3, 0xD6, 0xEB, 0xC0, 0x9E, 0xA9, 0xC2, 0xCE, - 0x00, 0x6C, 0xD3, 0x11, 0xD3, 0xB3, 0xE9, 0xCC, - 0x9D, 0x8D, 0xDB, 0xFB, 0x3C, 0x5A, 0x77, 0x76 - }, - { - 0x52, 0x56, 0x66, 0x96, 0x8B, 0x3B, 0x7D, 0x00, - 0x7B, 0xB9, 0x26, 0xB6, 0xEF, 0xDC, 0x7E, 0x21, - 0x2A, 0x31, 0x15, 0x4C, 0x9A, 0xE1, 0x8D, 0x43, - 0xEE, 0x0E, 0xB7, 0xE6, 0xB1, 0xA9, 0x38, 0xD3 - }, - { - 0xE0, 0x9A, 0x4F, 0xA5, 0xC2, 0x8B, 0xDC, 0xD7, - 0xC8, 0x39, 0x84, 0x0E, 0x0A, 0x38, 0x3E, 0x4F, - 0x7A, 0x10, 0x2D, 0x0B, 0x1B, 0xC8, 0x49, 0xC9, - 0x49, 0x62, 0x7C, 0x41, 0x00, 0xC1, 0x7D, 0xD3 - }, - { - 0xC1, 0x9F, 0x3E, 0x29, 0x5D, 0xB2, 0xFC, 0x0E, - 0x74, 0x81, 0xC4, 0xF1, 0x6A, 0xF0, 0x11, 0x55, - 0xDD, 0xB0, 0xD7, 0xD1, 0x38, 0x3D, 0x4A, 0x1F, - 0xF1, 0x69, 0x9D, 0xB7, 0x11, 0x77, 0x34, 0x0C - }, - { - 0x76, 0x9E, 0x67, 0x8C, 0x0A, 0x09, 0x09, 0xA2, - 0x02, 0x1C, 0x4D, 0xC2, 0x6B, 0x1A, 0x3C, 0x9B, - 0xC5, 0x57, 0xAD, 0xB2, 0x1A, 0x50, 0x83, 0x4C, - 0xDC, 0x5C, 0x92, 0x93, 0xF7, 0x53, 0x65, 0xF8 - }, - { - 0xB6, 0x48, 0x74, 0xAD, 0xAB, 0x6B, 0xCB, 0x85, - 0xB9, 0x4B, 0xD9, 0xA6, 0xC5, 0x65, 0xD0, 0xD2, - 0xBC, 0x35, 0x44, 0x5D, 0x75, 0x28, 0xBC, 0x85, - 0xB4, 0x1F, 0xDC, 0x79, 0xDC, 0x76, 0xE3, 0x4F - }, - { - 0xFA, 0xF2, 0x50, 0xDE, 0x15, 0x82, 0x0F, 0x7F, - 0xC6, 0x10, 0xDD, 0x53, 0xEE, 0xAE, 0x44, 0x60, - 0x1C, 0x3E, 0xFF, 0xA3, 0xAC, 0xCD, 0x08, 0x8E, - 0xB6, 0x69, 0x05, 0xBB, 0x26, 0x53, 0xBE, 0x8C - }, - { - 0x1E, 0x20, 0x38, 0x73, 0x9B, 0x2C, 0x01, 0x8B, - 0x0E, 0x9E, 0x0E, 0x1E, 0x52, 0x2F, 0xD9, 0x65, - 0x12, 0x87, 0xEE, 0x6E, 0x36, 0x65, 0x91, 0x9B, - 0x24, 0xC2, 0x12, 0x4F, 0x0C, 0x1A, 0x3F, 0x3A - }, - { - 0x5F, 0xEC, 0x3A, 0xA0, 0x08, 0x61, 0xDE, 0x1A, - 0xC5, 0xDA, 0xB3, 0xC1, 0x37, 0x06, 0x5D, 0x1E, - 0x01, 0xBB, 0x03, 0xF6, 0x9D, 0xCC, 0x7D, 0x1C, - 0xF7, 0xCA, 0x4F, 0x43, 0x56, 0xAE, 0xC9, 0xA3 - }, - { - 0x44, 0x51, 0xFE, 0x6B, 0xBE, 0xF3, 0x93, 0x43, - 0x91, 0x92, 0x44, 0xC5, 0x1D, 0xAE, 0x1E, 0xA9, - 0xA9, 0x54, 0xCF, 0x2C, 0x09, 0x66, 0xAB, 0x04, - 0x5B, 0x15, 0x52, 0x1E, 0xCF, 0x35, 0x00, 0x81 - }, - { - 0x8C, 0x62, 0x2F, 0xA2, 0x16, 0x0E, 0x8E, 0x99, - 0x18, 0x13, 0xF1, 0x80, 0xBF, 0xEC, 0x0B, 0x43, - 0x1C, 0x6D, 0xBF, 0xA2, 0x95, 0x6D, 0x91, 0x75, - 0x81, 0x6A, 0x23, 0xC3, 0x82, 0xC4, 0xF2, 0x00 - }, - { - 0x81, 0x7D, 0x5C, 0x8F, 0x92, 0xE7, 0xB5, 0xCA, - 0x57, 0xF5, 0xE1, 0x63, 0x90, 0x16, 0xAD, 0x57, - 0x60, 0xE4, 0x46, 0xD6, 0xE9, 0xCA, 0xA7, 0x49, - 0x84, 0x14, 0xAC, 0xE8, 0x22, 0x80, 0xB5, 0xCD - }, - { - 0xA6, 0xA1, 0xAD, 0x58, 0xCE, 0xE5, 0x4E, 0x69, - 0xCB, 0xBC, 0xAA, 0x87, 0xDF, 0x07, 0xA6, 0x70, - 0x7E, 0xB2, 0x24, 0x73, 0x9C, 0x21, 0x76, 0x13, - 0x46, 0x0A, 0xB4, 0x54, 0xB4, 0x59, 0xCA, 0x9C - }, - { - 0x63, 0xB8, 0x47, 0x27, 0x52, 0x26, 0x60, 0x5B, - 0xE6, 0x76, 0x81, 0x25, 0x8F, 0x7D, 0x00, 0xBB, - 0xB3, 0x07, 0xC6, 0x6F, 0x19, 0x59, 0xBF, 0x2E, - 0x46, 0x7A, 0x41, 0xAE, 0xE7, 0x14, 0xE5, 0x5C - }, - { - 0xFE, 0x52, 0xEB, 0xE5, 0xCF, 0xCF, 0xE6, 0xA2, - 0x29, 0x7B, 0x53, 0x9F, 0xA3, 0xDA, 0xDB, 0xD6, - 0xEB, 0xD2, 0x01, 0xAA, 0x2C, 0xA1, 0x35, 0x63, - 0xE3, 0xD7, 0xF1, 0x4D, 0x15, 0xAB, 0xFF, 0x63 - }, - { - 0xB7, 0xBE, 0xF9, 0xFA, 0x5A, 0x3D, 0x10, 0x42, - 0x62, 0x46, 0xB5, 0xF6, 0x58, 0xC0, 0x8F, 0xDF, - 0x80, 0x66, 0xEA, 0xA3, 0xE5, 0x5A, 0x2F, 0x7D, - 0xA1, 0x59, 0x1E, 0x05, 0xC8, 0x7D, 0xF8, 0xC7 - }, - { - 0xDE, 0xD1, 0xD6, 0xCA, 0xA9, 0xF8, 0xF3, 0xBD, - 0xA9, 0x2C, 0xEA, 0x7F, 0x65, 0x49, 0xB1, 0xFB, - 0x86, 0xA2, 0x21, 0x14, 0x78, 0xC4, 0xEC, 0x28, - 0x9B, 0x83, 0x7E, 0xFC, 0x2B, 0x5C, 0x27, 0xD7 - }, - { - 0x9F, 0x30, 0x00, 0x8A, 0x2E, 0xB0, 0x50, 0xF1, - 0x8E, 0x56, 0xA7, 0x6B, 0xE9, 0x20, 0x91, 0xB2, - 0xFD, 0xC1, 0x64, 0xD5, 0x6E, 0x32, 0xC8, 0x7D, - 0xD6, 0x4C, 0x9E, 0x3A, 0x61, 0x10, 0x41, 0xB1 - }, - { - 0x01, 0x0B, 0x6A, 0x3B, 0x11, 0x86, 0x00, 0x88, - 0xF0, 0xAB, 0xC8, 0x0A, 0x89, 0x72, 0xCB, 0xBC, - 0x32, 0x9D, 0x52, 0x75, 0x34, 0x29, 0x50, 0xEB, - 0x9A, 0x04, 0x5A, 0xFD, 0xC8, 0xBB, 0xED, 0x24 - }, - { - 0x0C, 0xD2, 0x10, 0xAA, 0xC1, 0x1F, 0x1C, 0x1C, - 0xED, 0x49, 0x7F, 0x67, 0x3E, 0x53, 0xDB, 0x68, - 0xC3, 0xEC, 0x36, 0x07, 0xF0, 0xC5, 0x78, 0x7D, - 0xDC, 0x60, 0xA3, 0x55, 0xDF, 0xE5, 0x6C, 0x25 - }, - { - 0x0E, 0x56, 0xFD, 0x01, 0xDA, 0x3B, 0x4F, 0x8B, - 0xE2, 0xC9, 0x90, 0x55, 0x2A, 0xAC, 0x8D, 0x1E, - 0x8D, 0xA2, 0x09, 0xBC, 0xF4, 0xAA, 0xD4, 0xFF, - 0xB5, 0x42, 0x7F, 0xD6, 0x31, 0x72, 0x46, 0x3E - }, - { - 0xD6, 0xD5, 0xCD, 0xB1, 0x14, 0x40, 0xE3, 0x4A, - 0xCA, 0x3A, 0x2F, 0xCF, 0x30, 0xF5, 0x9E, 0x08, - 0xB1, 0x1A, 0x2A, 0x3D, 0xE5, 0x39, 0xE3, 0xE6, - 0x51, 0x3E, 0xD7, 0x8A, 0x4F, 0xEE, 0x51, 0x3B - }, - { - 0xAA, 0x35, 0xAC, 0x90, 0x68, 0x06, 0x70, 0xC7, - 0x32, 0xED, 0x1E, 0xF3, 0x7E, 0x8C, 0xBA, 0xAE, - 0x49, 0xA4, 0xD8, 0x8E, 0xCF, 0x4D, 0xF2, 0xB6, - 0x89, 0xA0, 0xF1, 0x01, 0xB7, 0x56, 0xAE, 0x47 - }, - { - 0x27, 0x8E, 0x56, 0x12, 0x88, 0x72, 0x26, 0x30, - 0xE2, 0x6A, 0x5F, 0xC9, 0x54, 0xBF, 0x2D, 0xCD, - 0x6A, 0x65, 0x81, 0x67, 0x39, 0xAB, 0xEE, 0x7B, - 0xE1, 0x43, 0x07, 0xA9, 0x61, 0x74, 0xE5, 0xB0 - }, - { - 0xAB, 0x4B, 0x2C, 0xA1, 0xA2, 0xB3, 0x49, 0x98, - 0x15, 0x24, 0xB6, 0x15, 0x54, 0x62, 0xF0, 0xFF, - 0x10, 0x60, 0xBF, 0x9B, 0xFA, 0x07, 0xFB, 0x9E, - 0xC6, 0x9C, 0xA4, 0x71, 0x64, 0x5B, 0x6A, 0x18 - }, - { - 0x18, 0xA9, 0xBB, 0xEC, 0x3C, 0x8E, 0x1F, 0x8E, - 0xE9, 0x57, 0x12, 0x97, 0xA9, 0x34, 0x36, 0xDE, - 0x42, 0x7C, 0xD2, 0x70, 0xEC, 0x69, 0xDF, 0xE8, - 0x88, 0xDB, 0x7D, 0xBF, 0x10, 0xB6, 0x49, 0x93 - }, - { - 0xBA, 0xFC, 0x7E, 0x43, 0xD2, 0x65, 0xA1, 0x73, - 0x02, 0x1A, 0x9D, 0x9E, 0x58, 0x3D, 0x60, 0xED, - 0x42, 0xA8, 0x03, 0xFA, 0xCD, 0x6B, 0x83, 0x60, - 0xDE, 0x1F, 0x91, 0x68, 0x35, 0x38, 0x9B, 0xF0 - }, - { - 0xA5, 0xB6, 0x7B, 0xE9, 0x50, 0xFB, 0xC2, 0xF0, - 0xDD, 0x32, 0x3A, 0x79, 0xA1, 0x9E, 0x3E, 0xD1, - 0xF4, 0xAE, 0x4B, 0xA7, 0x89, 0x4F, 0x93, 0x0E, - 0xA5, 0xEF, 0x73, 0x4D, 0xE7, 0xDB, 0x83, 0xAE - }, - { - 0xBF, 0x1E, 0x65, 0xF3, 0xCD, 0x84, 0x98, 0x88, - 0x4D, 0x9D, 0x5C, 0x19, 0xEB, 0xF7, 0xB9, 0x16, - 0x06, 0x76, 0x37, 0x60, 0x4E, 0x26, 0xDB, 0xE2, - 0xB7, 0x28, 0x8E, 0xCB, 0x11, 0x42, 0x60, 0x68 - }, - { - 0xC3, 0x34, 0x2C, 0xF9, 0xCB, 0xBF, 0x29, 0xD4, - 0x06, 0xD7, 0x89, 0x5D, 0xD4, 0xD9, 0x54, 0x8D, - 0x4A, 0xC7, 0x8B, 0x4D, 0x00, 0xE9, 0xB6, 0x3E, - 0x20, 0x3E, 0x5E, 0x19, 0xE9, 0x97, 0x46, 0x20 - }, - { - 0x1C, 0x0B, 0xE6, 0x02, 0x77, 0x43, 0x4B, 0x0E, - 0x00, 0x4B, 0x7B, 0x38, 0x8A, 0x37, 0x55, 0x9F, - 0x84, 0xB3, 0x0C, 0x6C, 0xF8, 0x60, 0x0F, 0x52, - 0x8B, 0xFC, 0xD3, 0x3C, 0xAF, 0x52, 0xCB, 0x1E - }, - { - 0x73, 0x95, 0x45, 0x30, 0xD0, 0x3F, 0x10, 0xBE, - 0xF5, 0x2A, 0xD5, 0xBC, 0x7F, 0xB4, 0xC0, 0x76, - 0xF8, 0x3F, 0x63, 0x31, 0xC8, 0xBD, 0x1E, 0xEE, - 0xC3, 0x88, 0x7F, 0x4A, 0xA2, 0x06, 0x92, 0x40 - }, - { - 0x69, 0xC1, 0x1E, 0xE0, 0x49, 0x44, 0xDE, 0xA9, - 0x85, 0xAC, 0x9F, 0x13, 0x96, 0x0E, 0x73, 0x98, - 0x0E, 0x1B, 0xB0, 0xE3, 0x09, 0xF4, 0x38, 0x4A, - 0x16, 0x76, 0xF8, 0xEF, 0xAB, 0x38, 0x42, 0x88 - }, - { - 0x36, 0xFB, 0x8F, 0xDE, 0x0E, 0xC2, 0x8C, 0xE8, - 0x53, 0xFB, 0x71, 0x75, 0xC1, 0xB7, 0x9D, 0xA3, - 0xB5, 0xE8, 0xC3, 0x91, 0x86, 0xE7, 0x8A, 0xAE, - 0xCE, 0x54, 0x64, 0xDB, 0xD9, 0xFE, 0x2A, 0xA2 - }, - { - 0x6B, 0xB2, 0xA0, 0x9D, 0xFC, 0xAF, 0x96, 0x96, - 0x2D, 0xE0, 0x0C, 0x8A, 0x08, 0x2D, 0x6D, 0xF9, - 0x32, 0x2B, 0x49, 0x66, 0xAE, 0x8D, 0x2E, 0xCF, - 0x73, 0x24, 0x11, 0xA7, 0x6A, 0x1A, 0x0E, 0xE6 - }, - { - 0x74, 0x12, 0xE7, 0xDD, 0x1B, 0xF1, 0xAA, 0x93, - 0x97, 0x41, 0x1B, 0xBA, 0x4D, 0x3E, 0x02, 0x76, - 0xD2, 0xE7, 0xA1, 0xA2, 0x9A, 0x24, 0x77, 0x15, - 0x7A, 0xD6, 0x03, 0x60, 0xD3, 0x3D, 0x4E, 0x76 - }, - { - 0xDD, 0xDE, 0xAF, 0xCF, 0xC7, 0x23, 0x21, 0xC8, - 0x49, 0xFB, 0x25, 0x94, 0x7A, 0xB4, 0x2C, 0x1A, - 0xF2, 0xA5, 0xE4, 0x3F, 0xEF, 0x68, 0x1B, 0xE4, - 0x2C, 0x7E, 0xAF, 0x36, 0x60, 0x08, 0x0A, 0xD3 - }, - { - 0x9D, 0xEF, 0xEB, 0xAD, 0xBD, 0xCB, 0x0A, 0x0E, - 0x7F, 0xF9, 0x92, 0xF9, 0x47, 0xCE, 0xD3, 0xD0, - 0xA4, 0xC8, 0x99, 0xE6, 0x4F, 0xE7, 0x73, 0x60, - 0xE8, 0x1E, 0x1F, 0x0E, 0x97, 0xF8, 0xC1, 0xA2 - }, - { - 0x84, 0x4C, 0x59, 0xFB, 0xE6, 0x47, 0x6F, 0xD1, - 0x89, 0x23, 0x99, 0x54, 0xF1, 0x7E, 0x36, 0xE1, - 0xF6, 0x9E, 0x24, 0xAA, 0xED, 0x5D, 0x5C, 0x8B, - 0x84, 0x05, 0xEF, 0x2A, 0x83, 0x0C, 0xC2, 0xA0 - }, - { - 0xFF, 0x3F, 0xAF, 0xB6, 0x77, 0x86, 0xE0, 0x1A, - 0x0C, 0x38, 0xEA, 0xDF, 0x99, 0xC4, 0xCA, 0xE8, - 0x02, 0x9D, 0xA8, 0xCF, 0x29, 0x87, 0x5F, 0xC4, - 0x19, 0xBF, 0x68, 0x00, 0x09, 0xB3, 0xBD, 0xB3 - }, - { - 0xCA, 0x67, 0x60, 0xF3, 0x45, 0x67, 0x8F, 0x30, - 0xA2, 0x8D, 0x62, 0x82, 0x94, 0x27, 0x2A, 0x19, - 0xE3, 0x07, 0x2E, 0xBC, 0x61, 0xB1, 0x9F, 0xF1, - 0x3B, 0x31, 0x89, 0x73, 0xE9, 0x7C, 0x27, 0x38 - }, - { - 0xC0, 0x8E, 0x1A, 0x90, 0x47, 0xC5, 0x05, 0x26, - 0x4A, 0x16, 0x44, 0x7C, 0x9E, 0xD9, 0x81, 0xA7, - 0x19, 0xD3, 0x81, 0xF2, 0x8E, 0x60, 0x5F, 0xD7, - 0xCA, 0xA9, 0xE8, 0xBD, 0xBB, 0x42, 0x99, 0x6A - }, - { - 0xF1, 0x73, 0xBA, 0x9D, 0x45, 0x84, 0xCD, 0x12, - 0x60, 0x50, 0xC6, 0x9F, 0xC2, 0x19, 0xA9, 0x19, - 0x0A, 0x0B, 0xF0, 0xAE, 0xCE, 0xCB, 0xE6, 0x11, - 0xBE, 0xED, 0x19, 0x3D, 0xA6, 0xCA, 0x4D, 0xE7 - }, - { - 0xB1, 0x84, 0x87, 0x65, 0x20, 0xDE, 0xD8, 0xBD, - 0x7D, 0xE2, 0x5E, 0xAE, 0xFB, 0xD3, 0xE0, 0x36, - 0x88, 0xC3, 0xBE, 0x39, 0xC1, 0x9F, 0xB7, 0x3E, - 0x1F, 0x0E, 0xCC, 0xAC, 0x7C, 0xC0, 0xF0, 0x14 - }, - { - 0x90, 0x25, 0xDB, 0x07, 0x58, 0xBD, 0xFB, 0x48, - 0xF0, 0x66, 0x7E, 0xBD, 0x7E, 0x12, 0x02, 0x46, - 0x59, 0x8F, 0xED, 0x01, 0xC2, 0x58, 0x76, 0x4F, - 0xA0, 0xFA, 0xE3, 0x34, 0xA2, 0xA0, 0x0A, 0x97 - }, - { - 0xE8, 0x3D, 0x80, 0x86, 0xFA, 0xBC, 0x46, 0x0D, - 0x5E, 0xFC, 0x45, 0x9F, 0x95, 0xA2, 0x68, 0xF5, - 0xDC, 0x4A, 0xC2, 0x84, 0x09, 0x3C, 0x24, 0x7C, - 0xA6, 0xEC, 0x84, 0x1A, 0xD6, 0x18, 0x3F, 0xE1 - }, - { - 0xCC, 0x9D, 0xF4, 0x1D, 0x35, 0xAA, 0x75, 0x92, - 0x8C, 0x18, 0x5F, 0x73, 0x93, 0x66, 0x61, 0x10, - 0xB8, 0x0F, 0x09, 0x86, 0xA2, 0x21, 0xC3, 0x70, - 0xF4, 0x5C, 0x2E, 0xB9, 0x01, 0x6C, 0x9A, 0x3B - }, - { - 0x92, 0xF9, 0xA5, 0x94, 0x95, 0x45, 0x90, 0xFA, - 0x81, 0x98, 0x17, 0xE5, 0xD1, 0xC2, 0x8A, 0xAB, - 0x2B, 0x1C, 0xC5, 0x04, 0xD8, 0x6D, 0xBA, 0x44, - 0x36, 0x76, 0xBD, 0xF8, 0x66, 0x79, 0x68, 0x11 - }, - { - 0x72, 0x95, 0x62, 0xA1, 0xE0, 0x7B, 0x0E, 0x26, - 0x05, 0x49, 0x48, 0x09, 0xBD, 0x48, 0x0F, 0x15, - 0x37, 0xCE, 0xA1, 0x0D, 0xCA, 0xD4, 0x3E, 0xF9, - 0xF6, 0x8C, 0x66, 0xE8, 0x25, 0xDC, 0x46, 0xB1 - }, - { - 0x26, 0xF1, 0x60, 0xAB, 0x96, 0xF5, 0x58, 0x20, - 0x45, 0x14, 0x6E, 0xAF, 0xF2, 0xE2, 0xA8, 0xD4, - 0xDA, 0xB2, 0x98, 0xB4, 0xC5, 0x7E, 0x11, 0x7C, - 0xDF, 0xC5, 0xD0, 0x25, 0xC9, 0x2A, 0x22, 0x68 - }, - { - 0x87, 0xEB, 0xE7, 0x21, 0x38, 0x38, 0x73, 0xD2, - 0x47, 0xF8, 0x61, 0x82, 0xE3, 0xF5, 0x99, 0xA7, - 0x63, 0x4F, 0xCA, 0xEC, 0x5E, 0x07, 0xB1, 0xE8, - 0x3E, 0xBB, 0x79, 0x62, 0x5B, 0xA3, 0x54, 0xE6 - }, - { - 0xE0, 0x8D, 0x38, 0x9F, 0x75, 0x69, 0x4A, 0xDC, - 0x99, 0x6C, 0x22, 0xF5, 0x5D, 0x4F, 0x85, 0x9F, - 0xFD, 0x0C, 0x13, 0x19, 0xFF, 0x9C, 0xED, 0xF7, - 0x8C, 0x31, 0xBE, 0x84, 0xB6, 0xF2, 0x1A, 0xBC - }, - { - 0x13, 0x63, 0xE2, 0x29, 0x13, 0xC6, 0xE1, 0x8E, - 0x7A, 0xA6, 0x5B, 0x83, 0xE7, 0x51, 0xC8, 0xA2, - 0xC6, 0x1B, 0x0F, 0x30, 0x71, 0x55, 0x86, 0x5A, - 0x57, 0xDB, 0xA5, 0x69, 0xA9, 0x9C, 0x7B, 0x0E - }, - { - 0x88, 0x78, 0x08, 0x8E, 0xB2, 0xD1, 0xF6, 0xD0, - 0xBB, 0x48, 0x1B, 0x4B, 0xB1, 0x87, 0xDA, 0x04, - 0xBC, 0xD8, 0xC2, 0xC6, 0x39, 0xF0, 0x05, 0xB0, - 0x80, 0x54, 0xCC, 0x41, 0x75, 0x39, 0x05, 0xFB - }, - { - 0x04, 0x18, 0xD6, 0x0D, 0x05, 0xB4, 0xE1, 0x24, - 0x64, 0x6E, 0xE5, 0x0E, 0x77, 0x49, 0xA1, 0xD2, - 0x09, 0x45, 0x7B, 0xC5, 0x43, 0xE3, 0xCC, 0x11, - 0x30, 0x27, 0x4A, 0xEA, 0x0F, 0x7B, 0xF3, 0xC1 - }, - { - 0x7A, 0x39, 0x7E, 0x50, 0x3F, 0x29, 0x3B, 0xC4, - 0x2D, 0x5F, 0x7E, 0xF5, 0xEC, 0x37, 0x87, 0x24, - 0x60, 0xA4, 0xF5, 0xB5, 0xCC, 0xDE, 0x77, 0xFB, - 0x4D, 0x47, 0xAC, 0x06, 0x81, 0xE5, 0xA0, 0x49 - }, - { - 0x5C, 0x0D, 0x29, 0x83, 0xE7, 0x2A, 0x6D, 0xD4, - 0xE6, 0x52, 0xD7, 0x23, 0xC1, 0xDF, 0xC1, 0x2B, - 0x41, 0x4C, 0x87, 0x3D, 0x4A, 0xB4, 0xA0, 0xA1, - 0x50, 0x40, 0x8E, 0xB3, 0x43, 0x47, 0xE9, 0x95 - }, - { - 0x56, 0x23, 0x36, 0x54, 0x53, 0xC0, 0x49, 0x89, - 0xC7, 0xCF, 0x33, 0x63, 0x5E, 0x0F, 0xC4, 0xCD, - 0xDD, 0x68, 0x6F, 0xC9, 0x5A, 0x33, 0xDF, 0xED, - 0xCF, 0x33, 0x35, 0x79, 0x4C, 0x7D, 0xC3, 0x44 - }, - { - 0x11, 0xF6, 0xDA, 0xD1, 0x88, 0x02, 0x8F, 0xDF, - 0x13, 0x78, 0xA2, 0x56, 0xE4, 0x57, 0x0E, 0x90, - 0x63, 0x10, 0x7B, 0x8F, 0x79, 0xDC, 0x66, 0x3F, - 0xA5, 0x55, 0x6F, 0x56, 0xFD, 0x44, 0xA0, 0xF0 - }, - { - 0x0E, 0xD8, 0x16, 0x17, 0x97, 0xEC, 0xEE, 0x88, - 0x1E, 0x7D, 0x0E, 0x3F, 0x4C, 0x5F, 0xB8, 0x39, - 0xC8, 0x4E, 0xB7, 0xA9, 0x24, 0x26, 0x57, 0xCC, - 0x48, 0x30, 0x68, 0x07, 0xB3, 0x2B, 0xEF, 0xDE - }, - { - 0x73, 0x66, 0x67, 0xC9, 0x36, 0x4C, 0xE1, 0x2D, - 0xB8, 0xF6, 0xB1, 0x43, 0xC6, 0xC1, 0x78, 0xCD, - 0xEF, 0x1E, 0x14, 0x45, 0xBC, 0x5A, 0x2F, 0x26, - 0x34, 0xF0, 0x8E, 0x99, 0x32, 0x27, 0x3C, 0xAA - }, - { - 0xE1, 0x5F, 0x36, 0x8B, 0x44, 0x06, 0xC1, 0xF6, - 0x55, 0x57, 0xC8, 0x35, 0x5C, 0xBE, 0x69, 0x4B, - 0x63, 0x3E, 0x26, 0xF1, 0x55, 0xF5, 0x2B, 0x7D, - 0xA9, 0x4C, 0xFB, 0x23, 0xFD, 0x4A, 0x5D, 0x96 - }, - { - 0x43, 0x7A, 0xB2, 0xD7, 0x4F, 0x50, 0xCA, 0x86, - 0xCC, 0x3D, 0xE9, 0xBE, 0x70, 0xE4, 0x55, 0x48, - 0x25, 0xE3, 0x3D, 0x82, 0x4B, 0x3A, 0x49, 0x23, - 0x62, 0xE2, 0xE9, 0xD6, 0x11, 0xBC, 0x57, 0x9D - }, - { - 0x2B, 0x91, 0x58, 0xC7, 0x22, 0x89, 0x8E, 0x52, - 0x6D, 0x2C, 0xDD, 0x3F, 0xC0, 0x88, 0xE9, 0xFF, - 0xA7, 0x9A, 0x9B, 0x73, 0xB7, 0xD2, 0xD2, 0x4B, - 0xC4, 0x78, 0xE2, 0x1C, 0xDB, 0x3B, 0x67, 0x63 - }, - { - 0x0C, 0x8A, 0x36, 0x59, 0x7D, 0x74, 0x61, 0xC6, - 0x3A, 0x94, 0x73, 0x28, 0x21, 0xC9, 0x41, 0x85, - 0x6C, 0x66, 0x83, 0x76, 0x60, 0x6C, 0x86, 0xA5, - 0x2D, 0xE0, 0xEE, 0x41, 0x04, 0xC6, 0x15, 0xDB - }, -}; - - - - -static const uint8_t blake2bp_kat[KAT_LENGTH][BLAKE2B_OUTBYTES] = -{ - { - 0xB5, 0xEF, 0x81, 0x1A, 0x80, 0x38, 0xF7, 0x0B, - 0x62, 0x8F, 0xA8, 0xB2, 0x94, 0xDA, 0xAE, 0x74, - 0x92, 0xB1, 0xEB, 0xE3, 0x43, 0xA8, 0x0E, 0xAA, - 0xBB, 0xF1, 0xF6, 0xAE, 0x66, 0x4D, 0xD6, 0x7B, - 0x9D, 0x90, 0xB0, 0x12, 0x07, 0x91, 0xEA, 0xB8, - 0x1D, 0xC9, 0x69, 0x85, 0xF2, 0x88, 0x49, 0xF6, - 0xA3, 0x05, 0x18, 0x6A, 0x85, 0x50, 0x1B, 0x40, - 0x51, 0x14, 0xBF, 0xA6, 0x78, 0xDF, 0x93, 0x80 - }, - { - 0xA1, 0x39, 0x28, 0x0E, 0x72, 0x75, 0x7B, 0x72, - 0x3E, 0x64, 0x73, 0xD5, 0xBE, 0x59, 0xF3, 0x6E, - 0x9D, 0x50, 0xFC, 0x5C, 0xD7, 0xD4, 0x58, 0x5C, - 0xBC, 0x09, 0x80, 0x48, 0x95, 0xA3, 0x6C, 0x52, - 0x12, 0x42, 0xFB, 0x27, 0x89, 0xF8, 0x5C, 0xB9, - 0xE3, 0x54, 0x91, 0xF3, 0x1D, 0x4A, 0x69, 0x52, - 0xF9, 0xD8, 0xE0, 0x97, 0xAE, 0xF9, 0x4F, 0xA1, - 0xCA, 0x0B, 0x12, 0x52, 0x57, 0x21, 0xF0, 0x3D - }, - { - 0xEF, 0x8C, 0xDA, 0x96, 0x35, 0xD5, 0x06, 0x3A, - 0xF8, 0x11, 0x15, 0xDA, 0x3C, 0x52, 0x32, 0x5A, - 0x86, 0xE8, 0x40, 0x74, 0xF9, 0xF7, 0x24, 0xB7, - 0xCB, 0xD0, 0xB0, 0x85, 0x6F, 0xF0, 0x01, 0x77, - 0xCD, 0xD2, 0x83, 0xC2, 0x98, 0x32, 0x6C, 0xD0, - 0x91, 0x77, 0x54, 0xC5, 0x24, 0x1F, 0x14, 0x80, - 0xFB, 0x50, 0x9C, 0xF2, 0xD2, 0xC4, 0x49, 0x81, - 0x80, 0x77, 0xAE, 0x35, 0xFC, 0x33, 0x07, 0x37 - }, - { - 0x8C, 0xF9, 0x33, 0xA2, 0xD3, 0x61, 0xA3, 0xE6, - 0xA1, 0x36, 0xDB, 0xE4, 0xA0, 0x1E, 0x79, 0x03, - 0x79, 0x7A, 0xD6, 0xCE, 0x76, 0x6E, 0x2B, 0x91, - 0xB9, 0xB4, 0xA4, 0x03, 0x51, 0x27, 0xD6, 0x5F, - 0x4B, 0xE8, 0x65, 0x50, 0x11, 0x94, 0x18, 0xE2, - 0x2D, 0xA0, 0x0F, 0xD0, 0x6B, 0xF2, 0xB2, 0x75, - 0x96, 0xB3, 0x7F, 0x06, 0xBE, 0x0A, 0x15, 0x4A, - 0xAF, 0x7E, 0xCA, 0x54, 0xC4, 0x52, 0x0B, 0x97 - }, - { - 0x24, 0xDC, 0x1E, 0x6D, 0xC4, 0xE5, 0x1A, 0x3A, - 0x3C, 0x8D, 0xA6, 0x7A, 0xAC, 0xB4, 0xC5, 0x41, - 0xE4, 0x18, 0x18, 0xD1, 0x80, 0xE5, 0xBB, 0x69, - 0x75, 0x3D, 0xBB, 0xFF, 0x2F, 0x44, 0xD0, 0xE7, - 0xDA, 0x83, 0x03, 0x86, 0xBF, 0xC8, 0x3B, 0x27, - 0xA5, 0x9D, 0xBB, 0x62, 0xB9, 0x64, 0xFC, 0x8E, - 0xA6, 0xCB, 0xDF, 0x30, 0x49, 0xBF, 0xF8, 0x1F, - 0x24, 0xF3, 0x48, 0xDB, 0x4E, 0xFD, 0x0D, 0x07 - }, - { - 0xBC, 0x23, 0xF5, 0xAB, 0xDF, 0xFD, 0x6A, 0x32, - 0xA5, 0xD4, 0x08, 0x11, 0x26, 0x2E, 0xD4, 0x47, - 0x9E, 0xF7, 0x0B, 0x42, 0x33, 0xCA, 0x20, 0x5B, - 0xC5, 0xB9, 0xBF, 0x85, 0x96, 0x73, 0x19, 0x82, - 0xD0, 0x41, 0x69, 0xA9, 0x04, 0xDD, 0x43, 0xB0, - 0xE0, 0xF9, 0x48, 0x99, 0xF7, 0x33, 0x02, 0x2D, - 0x24, 0xD8, 0x4F, 0xAD, 0x0A, 0x99, 0x16, 0x00, - 0xF1, 0x97, 0x9B, 0x27, 0x2A, 0xD6, 0x20, 0x73 - }, - { - 0xEF, 0x10, 0x7F, 0xCD, 0x0D, 0x92, 0xD8, 0x4E, - 0xF5, 0xEF, 0x94, 0x63, 0xE6, 0xE9, 0x62, 0x41, - 0x25, 0x45, 0x29, 0xD2, 0xB9, 0x7F, 0xDB, 0xE5, - 0x64, 0x19, 0x07, 0x0A, 0xDB, 0xC7, 0xD5, 0x70, - 0x6F, 0xEB, 0x8F, 0x44, 0x95, 0x79, 0x81, 0x9E, - 0xD4, 0xBE, 0x61, 0x97, 0x85, 0xFF, 0xFA, 0xAF, - 0x0D, 0x97, 0x89, 0xCF, 0xE7, 0x26, 0x24, 0x9A, - 0xB0, 0x8C, 0x94, 0x68, 0xCB, 0x5F, 0xDE, 0x22 - }, - { - 0x23, 0x1F, 0xBF, 0xB7, 0xA1, 0xDD, 0xC5, 0xB7, - 0x49, 0x33, 0xA2, 0x85, 0xA4, 0x22, 0x4C, 0x04, - 0x9C, 0xBA, 0x14, 0x85, 0xCE, 0x35, 0x64, 0x0D, - 0x9C, 0x51, 0x6E, 0xD7, 0x8E, 0xAA, 0x22, 0x6D, - 0x36, 0xF6, 0x5B, 0x25, 0x89, 0xB8, 0x26, 0xC4, - 0x59, 0xFA, 0x6A, 0x91, 0xC4, 0x26, 0xFD, 0x2A, - 0x8A, 0xB4, 0x61, 0xC9, 0x76, 0x7E, 0x7B, 0xDD, - 0x99, 0x6B, 0xEF, 0x5A, 0x78, 0xF4, 0x81, 0xB7 - }, - { - 0x3A, 0x83, 0x1F, 0x2D, 0xA9, 0x69, 0xB9, 0xB7, - 0x36, 0x0E, 0x74, 0xEE, 0x53, 0xB5, 0x18, 0x98, - 0x0A, 0x5E, 0xBC, 0xDF, 0xD4, 0xEE, 0x23, 0xED, - 0x80, 0x5C, 0x26, 0x39, 0x4D, 0x18, 0x24, 0x20, - 0x8D, 0x7E, 0x8F, 0x63, 0x27, 0xD4, 0xEC, 0x87, - 0x97, 0x9C, 0xE4, 0xAF, 0x8A, 0xB0, 0x97, 0xD6, - 0x9E, 0x26, 0x1C, 0xA3, 0x2D, 0xB0, 0xEE, 0xFD, - 0xBC, 0x18, 0xD1, 0x63, 0x77, 0xA6, 0xBD, 0x20 - }, - { - 0x83, 0x49, 0xA2, 0x0F, 0xDD, 0xBA, 0xE1, 0xD8, - 0x47, 0x2B, 0x67, 0xF0, 0x34, 0x7A, 0xA0, 0xFD, - 0x40, 0x4D, 0x65, 0xC6, 0xFA, 0x14, 0x72, 0xB3, - 0x10, 0x39, 0x0D, 0x75, 0x65, 0xBA, 0x6B, 0xC1, - 0x02, 0x60, 0xD3, 0xDC, 0xE6, 0xA1, 0x4F, 0x4D, - 0xD9, 0xB8, 0xB3, 0xE0, 0xA0, 0xC4, 0x7F, 0x6D, - 0xB7, 0xE7, 0x10, 0x0A, 0x7A, 0x9B, 0x64, 0xA8, - 0x44, 0xF0, 0x10, 0x64, 0xD0, 0x79, 0x05, 0xC5 - }, - { - 0x23, 0x9A, 0xE3, 0xD6, 0x85, 0x9C, 0x7C, 0x97, - 0x2A, 0x5D, 0xC8, 0xB9, 0xC5, 0x5A, 0xEB, 0x93, - 0x85, 0x90, 0xCF, 0xB8, 0x55, 0x2A, 0xA3, 0x05, - 0xA6, 0xF6, 0xF3, 0x1F, 0xFA, 0x95, 0xA8, 0x40, - 0xF4, 0xEC, 0x36, 0xF6, 0xFB, 0x8F, 0x83, 0xB6, - 0x9C, 0x1D, 0xA9, 0x81, 0xFC, 0x9B, 0xA1, 0x63, - 0x60, 0xDB, 0x0F, 0x4F, 0x7C, 0x68, 0xEB, 0x54, - 0x3E, 0xD5, 0x8B, 0x28, 0x75, 0x6A, 0x1E, 0x0D - }, - { - 0x7C, 0x56, 0x73, 0x28, 0x63, 0x08, 0x40, 0x8F, - 0xBC, 0x62, 0x24, 0x0E, 0x07, 0x47, 0x28, 0xB2, - 0x7A, 0x57, 0x5C, 0xAD, 0x2A, 0x15, 0x6E, 0x00, - 0xB5, 0xC0, 0x8B, 0x21, 0x8D, 0x88, 0x87, 0x79, - 0x1E, 0x47, 0xBF, 0x10, 0xB0, 0xBC, 0x61, 0xA5, - 0x82, 0x54, 0x5A, 0x24, 0x69, 0x63, 0x9C, 0xE6, - 0x28, 0xC4, 0x0F, 0x20, 0xEA, 0x8B, 0x84, 0x9C, - 0xD0, 0x05, 0x44, 0x5F, 0x29, 0xA0, 0x8C, 0xCE - }, - { - 0xDD, 0x07, 0x7E, 0x76, 0x9E, 0x0D, 0xEF, 0x78, - 0xDD, 0x7A, 0xAD, 0xD5, 0x7D, 0x58, 0x42, 0x1B, - 0xDA, 0x3A, 0x1A, 0x4E, 0x69, 0x72, 0x05, 0x9F, - 0x8E, 0x64, 0x9C, 0xD6, 0xBC, 0xA4, 0x4A, 0x13, - 0xAB, 0x71, 0xEB, 0x53, 0x5D, 0x24, 0x49, 0x22, - 0x94, 0x84, 0x65, 0xD7, 0x3B, 0xD6, 0x4E, 0xFB, - 0x09, 0x10, 0x46, 0x94, 0x90, 0x66, 0x65, 0x36, - 0x03, 0x57, 0x5A, 0x2E, 0x89, 0x1E, 0xBD, 0x54 - }, - { - 0xB3, 0x6C, 0xEF, 0x28, 0x53, 0x2B, 0x40, 0xD8, - 0x17, 0x86, 0x28, 0xF0, 0xFA, 0xB5, 0xE5, 0xB4, - 0xA1, 0xDE, 0xC0, 0xC0, 0xE9, 0x11, 0xD7, 0x27, - 0xBF, 0x09, 0x49, 0x0F, 0x5E, 0x8D, 0x9F, 0xAC, - 0x57, 0x21, 0x3F, 0xD2, 0xA2, 0xD1, 0x2E, 0xD3, - 0xD7, 0x7A, 0x41, 0xF5, 0xE2, 0xFE, 0xCC, 0x40, - 0xE4, 0xEE, 0xCA, 0x16, 0x12, 0xF5, 0x1C, 0x45, - 0x23, 0x31, 0xAE, 0x93, 0x96, 0x62, 0x35, 0xBC - }, - { - 0xDE, 0x73, 0x7D, 0xBC, 0x61, 0x2E, 0xBD, 0x31, - 0xBC, 0x49, 0xA2, 0xD7, 0xC6, 0x44, 0xD4, 0xB1, - 0x37, 0x81, 0x74, 0x19, 0x42, 0x1C, 0x32, 0xF4, - 0xE7, 0x51, 0x14, 0xD8, 0x99, 0xE3, 0x13, 0x1D, - 0x45, 0xCA, 0x54, 0x51, 0x24, 0x8F, 0x24, 0x16, - 0x9F, 0xBF, 0x17, 0xEE, 0x60, 0xA9, 0xB7, 0x07, - 0x98, 0xA4, 0xB9, 0x37, 0xCE, 0xA6, 0x27, 0x95, - 0x28, 0x96, 0x39, 0xD1, 0x8F, 0xCD, 0x89, 0xE4 - }, - { - 0xB4, 0xC1, 0xBB, 0xCB, 0xBC, 0xCD, 0xFC, 0xE4, - 0xD2, 0xBE, 0x9D, 0xCD, 0xB9, 0x83, 0xC1, 0xB0, - 0x20, 0xC5, 0xF7, 0x20, 0xDA, 0x5B, 0xEC, 0xF4, - 0xCB, 0x2A, 0x9A, 0x3D, 0x1B, 0x8D, 0x23, 0xCE, - 0xA7, 0xA9, 0xF5, 0xFD, 0x70, 0xD3, 0x74, 0x0E, - 0xCD, 0x67, 0xCE, 0x7D, 0x1E, 0x9C, 0x5E, 0x31, - 0xA3, 0x30, 0x2D, 0xF6, 0x6A, 0x9B, 0x5D, 0x54, - 0x30, 0x44, 0x90, 0xFB, 0xE1, 0xC4, 0xA8, 0xB9 - }, - { - 0xB1, 0xD6, 0x5E, 0x70, 0xC6, 0x9B, 0xA7, 0xE3, - 0xA7, 0x28, 0xE8, 0xB6, 0x44, 0x94, 0x93, 0xF2, - 0x37, 0x51, 0x0B, 0x23, 0xB6, 0xE7, 0x7D, 0x95, - 0x84, 0xD0, 0x5F, 0xF4, 0xD3, 0xF0, 0x87, 0x80, - 0x92, 0x9D, 0x74, 0xFA, 0x5B, 0xED, 0x9B, 0x75, - 0xD4, 0xD6, 0xD1, 0xCA, 0x91, 0xAB, 0x8D, 0x26, - 0x37, 0xDC, 0x2E, 0x79, 0xBA, 0x0F, 0xE0, 0x59, - 0x4A, 0xCD, 0x68, 0xFB, 0x3C, 0xC6, 0x60, 0xB9 - }, - { - 0xDA, 0x79, 0xF7, 0x29, 0xEA, 0xB9, 0x8C, 0x04, - 0xF3, 0x7F, 0xCC, 0x85, 0x4B, 0x69, 0xA8, 0x4E, - 0x46, 0x7D, 0xEA, 0x1E, 0x77, 0x82, 0xE7, 0xAF, - 0x02, 0xCB, 0x44, 0xA4, 0x9D, 0x21, 0x0D, 0x25, - 0x23, 0x68, 0x3D, 0x42, 0x0A, 0xC1, 0xDE, 0xC8, - 0xAD, 0x1F, 0xB4, 0x0E, 0x65, 0xAB, 0x3F, 0xE2, - 0x51, 0xA8, 0x51, 0xE2, 0x83, 0xD8, 0x58, 0x38, - 0x08, 0x42, 0x61, 0x30, 0x1E, 0xCD, 0x08, 0x9B - }, - { - 0x71, 0x40, 0x40, 0x40, 0x39, 0x21, 0xAE, 0x55, - 0x48, 0xA2, 0x03, 0x39, 0xD6, 0x9E, 0x09, 0x3F, - 0x60, 0x9A, 0xA9, 0x9C, 0x22, 0xDB, 0x72, 0x59, - 0x1D, 0x1E, 0xF4, 0xFC, 0xB0, 0xAF, 0x01, 0x61, - 0x73, 0xE5, 0x77, 0xD8, 0xC1, 0xA3, 0x06, 0x3B, - 0x44, 0x3A, 0x0E, 0x48, 0xF3, 0x13, 0xCF, 0x2E, - 0x0F, 0x9B, 0x0C, 0x2E, 0xF9, 0x6A, 0x96, 0xC4, - 0x24, 0x32, 0x2C, 0xCC, 0x0C, 0xD5, 0x30, 0x4C - }, - { - 0x8B, 0x2E, 0x8C, 0x3F, 0x0E, 0x3C, 0x31, 0x9B, - 0xA6, 0x7E, 0x86, 0x01, 0x4B, 0xDA, 0x68, 0x3E, - 0x53, 0x57, 0xA0, 0x40, 0x37, 0xB4, 0x56, 0x32, - 0x86, 0xAC, 0x89, 0xCD, 0xDB, 0x7E, 0xE0, 0x4C, - 0xF6, 0x67, 0x5F, 0x9A, 0xB6, 0x1F, 0xC8, 0x33, - 0x2D, 0x21, 0x8D, 0x2B, 0xCA, 0x97, 0x15, 0xE7, - 0xDB, 0xE5, 0x83, 0x72, 0xD1, 0xEE, 0xBF, 0x6B, - 0xC2, 0x94, 0x84, 0x71, 0xCF, 0xCE, 0xBB, 0x77 - }, - { - 0x32, 0xEE, 0x95, 0x49, 0xD4, 0xE3, 0x2F, 0x4B, - 0xE9, 0xC5, 0x00, 0xBD, 0x85, 0x43, 0xAF, 0xD0, - 0xB6, 0x97, 0x82, 0xD0, 0xB3, 0xFF, 0x7E, 0xD4, - 0x7A, 0x88, 0x1A, 0x0E, 0x49, 0x1F, 0x37, 0x65, - 0x0A, 0x21, 0xB2, 0x6C, 0x3F, 0x5D, 0x0A, 0x64, - 0xE0, 0x90, 0x58, 0xB3, 0x00, 0x4A, 0x23, 0x68, - 0xB9, 0x50, 0xE4, 0x72, 0x30, 0xC2, 0x29, 0x66, - 0xD3, 0xF7, 0x9D, 0xA7, 0xBA, 0xA0, 0xB8, 0x7F - }, - { - 0xCA, 0xE7, 0xF2, 0x92, 0x71, 0x37, 0x82, 0xC4, - 0x71, 0xFE, 0x31, 0x78, 0xA9, 0x42, 0x0C, 0xD4, - 0xC1, 0x1F, 0xCD, 0x3F, 0x6D, 0xBE, 0x5D, 0x15, - 0xC8, 0x4A, 0xB7, 0x35, 0x3C, 0x73, 0x9E, 0xF0, - 0x64, 0x16, 0x39, 0xA2, 0xF9, 0x2A, 0xED, 0x31, - 0xC5, 0x6A, 0x20, 0x21, 0xCC, 0x5E, 0x58, 0xCB, - 0xEA, 0xD3, 0x74, 0xE2, 0xDC, 0x8A, 0x0D, 0xBC, - 0xE5, 0x45, 0x0F, 0xE7, 0xA0, 0x18, 0xCF, 0xA4 - }, - { - 0xF1, 0x7F, 0xEF, 0xAE, 0xAE, 0x7D, 0x40, 0xCD, - 0x88, 0x5D, 0xAC, 0x0B, 0xC3, 0x50, 0xC0, 0x27, - 0x36, 0x68, 0xEA, 0x02, 0x22, 0xDF, 0x5C, 0x75, - 0x69, 0x4F, 0x5C, 0xB3, 0xA3, 0x21, 0x51, 0x9F, - 0x6E, 0x0E, 0xC4, 0x3B, 0xA0, 0xC8, 0x59, 0x3D, - 0xC7, 0x34, 0x13, 0x41, 0xE5, 0x19, 0x48, 0x8F, - 0x20, 0xAB, 0xD5, 0xB8, 0x12, 0x4D, 0xFA, 0xCE, - 0xA5, 0xCD, 0xE0, 0x96, 0x5B, 0x69, 0x70, 0xF9 - }, - { - 0xE2, 0xCF, 0x86, 0xDD, 0xC8, 0x42, 0x4E, 0xE5, - 0x47, 0xEB, 0x72, 0x45, 0xB7, 0x32, 0x5E, 0x02, - 0xF2, 0xE3, 0xAC, 0x01, 0x3C, 0x8D, 0x38, 0x6B, - 0x3D, 0x2E, 0x09, 0x20, 0x8A, 0x9B, 0xCC, 0x0B, - 0x44, 0xC4, 0xC4, 0x38, 0xEA, 0xAF, 0x52, 0xD2, - 0x07, 0x7E, 0x91, 0x77, 0xEB, 0x8E, 0xE1, 0xD5, - 0x90, 0x75, 0xB5, 0x25, 0x92, 0x20, 0x20, 0x62, - 0x22, 0x93, 0x54, 0xBF, 0x23, 0xC9, 0x62, 0x39 - }, - { - 0x38, 0xF2, 0x6A, 0x11, 0x02, 0xCB, 0x16, 0x2D, - 0x35, 0x1F, 0x84, 0x3B, 0x3C, 0x49, 0xF6, 0xFF, - 0x85, 0x44, 0x16, 0x33, 0xB6, 0x70, 0x4A, 0x28, - 0x6A, 0xF8, 0x1C, 0xCB, 0xAE, 0x5A, 0x67, 0xD3, - 0x01, 0x5C, 0xC0, 0xEF, 0xAF, 0xB7, 0x05, 0x7D, - 0xC2, 0xB2, 0x8D, 0x67, 0x66, 0xE8, 0x2A, 0x06, - 0x8A, 0x4C, 0x0B, 0x52, 0x4B, 0x66, 0xD0, 0xA6, - 0x32, 0x77, 0x5D, 0x93, 0x06, 0x15, 0x75, 0xF9 - }, - { - 0xA2, 0xC4, 0x30, 0x2D, 0xAC, 0xA7, 0xA7, 0xC6, - 0x32, 0xF6, 0x76, 0x30, 0x4E, 0x62, 0x75, 0xC1, - 0xC1, 0xF0, 0xDB, 0xFE, 0x38, 0xDC, 0x57, 0x1C, - 0xB2, 0x3E, 0x1F, 0x7B, 0xA5, 0xDC, 0x18, 0x18, - 0x0F, 0xC4, 0x8A, 0x01, 0x5F, 0x92, 0x7C, 0x89, - 0x96, 0x7C, 0x1E, 0x10, 0x4E, 0x66, 0xF5, 0xEA, - 0x5B, 0x2D, 0xD3, 0x1D, 0x78, 0x1C, 0x38, 0x49, - 0xBF, 0xC6, 0x49, 0x22, 0x0C, 0x38, 0x5C, 0x82 - }, - { - 0xC1, 0x9C, 0x6B, 0x3F, 0xB5, 0x35, 0x2B, 0xB3, - 0x94, 0xC2, 0x68, 0x46, 0x52, 0x3C, 0x25, 0xE8, - 0x26, 0x5D, 0x50, 0x5F, 0x50, 0x1F, 0x96, 0x03, - 0xA4, 0xF8, 0xBD, 0x55, 0x38, 0x6C, 0xF4, 0xCC, - 0x9F, 0x4D, 0x71, 0xF3, 0x8F, 0xF4, 0x45, 0xF4, - 0xEF, 0xC8, 0x30, 0x98, 0xD4, 0x79, 0x69, 0x33, - 0x4E, 0x79, 0xA2, 0xBC, 0xB4, 0x02, 0x6B, 0xC6, - 0x3B, 0x79, 0x59, 0xDE, 0xDB, 0x62, 0xB7, 0xBD - }, - { - 0x1F, 0x4A, 0xB9, 0x84, 0x0A, 0x1C, 0xFA, 0x8F, - 0xE6, 0xC5, 0x62, 0x2D, 0x9B, 0x53, 0x8B, 0xEC, - 0xB8, 0x80, 0x7A, 0x87, 0x78, 0xB6, 0x9D, 0x93, - 0x05, 0xF9, 0x08, 0x57, 0x65, 0x73, 0xB2, 0x0C, - 0xA3, 0x70, 0x4E, 0x89, 0x12, 0x97, 0x26, 0xD5, - 0x02, 0xE1, 0x98, 0x58, 0x8D, 0x07, 0x26, 0x68, - 0xBF, 0x03, 0x63, 0x0B, 0x5B, 0x5A, 0x92, 0x32, - 0xFF, 0x39, 0x25, 0x27, 0x24, 0x9D, 0xF9, 0x9B - }, - { - 0xFE, 0x03, 0x17, 0x7B, 0x58, 0xB4, 0x88, 0x83, - 0xA8, 0x6D, 0x42, 0x68, 0x33, 0x4B, 0x95, 0x91, - 0xD9, 0xFB, 0xD8, 0xBF, 0x7C, 0xC2, 0xAA, 0xCC, - 0x50, 0x25, 0xEF, 0x47, 0x6B, 0x45, 0x33, 0xBA, - 0x7B, 0xD7, 0x81, 0xDF, 0x01, 0x11, 0x47, 0xB3, - 0xCF, 0x51, 0x1D, 0x8B, 0x3D, 0xCD, 0x8C, 0x78, - 0x0D, 0x30, 0xD7, 0xDA, 0x71, 0x8C, 0x22, 0x44, - 0x23, 0x19, 0x81, 0x7B, 0xE3, 0x18, 0x6B, 0xC5 - }, - { - 0xF4, 0xC3, 0xB0, 0x59, 0x10, 0x5B, 0x6A, 0xA5, - 0xFE, 0x78, 0x84, 0x3A, 0x07, 0xD9, 0x4F, 0x71, - 0x20, 0x62, 0xCB, 0x5A, 0x4D, 0xD6, 0x05, 0x9F, - 0x97, 0x90, 0x4D, 0x0C, 0x57, 0x97, 0x3B, 0xA8, - 0xDF, 0x71, 0xD1, 0x5A, 0x51, 0x1A, 0x06, 0x68, - 0x64, 0xFE, 0x45, 0x5E, 0xDC, 0x9E, 0x5F, 0x16, - 0x52, 0x4C, 0xEC, 0x7E, 0xE2, 0x48, 0xEE, 0x3E, - 0xC9, 0x29, 0x06, 0x3B, 0xD1, 0x07, 0x98, 0xDA - }, - { - 0x57, 0xA1, 0x6F, 0x96, 0x4B, 0x18, 0x1B, 0x12, - 0x03, 0xA5, 0x80, 0x3B, 0x73, 0x81, 0x7D, 0x77, - 0x44, 0x83, 0x82, 0x6C, 0xEA, 0x11, 0x3B, 0x9C, - 0xCF, 0xCF, 0x0E, 0xB8, 0x7C, 0xB2, 0x30, 0x64, - 0x28, 0x49, 0x62, 0xD8, 0x47, 0xBB, 0x1F, 0xAE, - 0x8C, 0xBF, 0x5C, 0xC6, 0x3B, 0x3C, 0xEA, 0xA1, - 0x24, 0x1E, 0xA4, 0x2C, 0x63, 0xF8, 0x98, 0x01, - 0x1F, 0xC4, 0xDB, 0xCA, 0xE6, 0xF5, 0xE8, 0xC5 - }, - { - 0x79, 0x52, 0xFC, 0x83, 0xAC, 0xF1, 0x3A, 0x95, - 0xCA, 0x9C, 0x27, 0xA2, 0x15, 0x6D, 0x9C, 0x1B, - 0x63, 0x00, 0xB0, 0xEF, 0x79, 0x0F, 0x57, 0x2B, - 0xC3, 0x94, 0xC6, 0x77, 0xF7, 0xC1, 0x46, 0x29, - 0xEB, 0xD8, 0xE7, 0xD5, 0xD7, 0xC7, 0xF1, 0xA5, - 0xEB, 0xBD, 0xC3, 0x90, 0xCC, 0x08, 0xCD, 0x58, - 0xC2, 0x00, 0x89, 0x00, 0xCB, 0x55, 0xEB, 0x05, - 0xE4, 0x44, 0xA6, 0x8C, 0x3B, 0x39, 0x3E, 0x60 - }, - { - 0x2C, 0x22, 0x40, 0xD6, 0xB5, 0x41, 0xF4, 0x29, - 0x4F, 0xF9, 0x76, 0x79, 0x1D, 0x35, 0xE6, 0xA2, - 0xD4, 0x92, 0xF5, 0x7A, 0x91, 0x5F, 0xBA, 0xC5, - 0x83, 0x26, 0x60, 0xC1, 0x0E, 0x9C, 0x96, 0x46, - 0x5C, 0x7B, 0xD5, 0xFC, 0xA7, 0x51, 0xBF, 0x68, - 0xE2, 0x67, 0x3A, 0x63, 0x8E, 0x3A, 0xF7, 0x35, - 0xB0, 0x20, 0x91, 0xD7, 0x5D, 0x1A, 0x7F, 0x89, - 0xE3, 0xF7, 0x61, 0xC5, 0xDF, 0x82, 0x1A, 0x6B - }, - { - 0x59, 0xDC, 0x84, 0x6D, 0x34, 0x05, 0xCC, 0xD8, - 0x06, 0xF8, 0xFA, 0x20, 0xC8, 0x96, 0x9E, 0xF6, - 0x8A, 0x43, 0x85, 0xEF, 0x6C, 0x27, 0x4E, 0xEE, - 0x6D, 0xC0, 0x69, 0x2C, 0x3E, 0xCF, 0xB1, 0xA8, - 0x34, 0xCE, 0x64, 0x43, 0x76, 0xC5, 0x2B, 0x80, - 0x42, 0x1B, 0xAE, 0x94, 0xD6, 0xC7, 0xFD, 0xCC, - 0xA5, 0xA8, 0xF1, 0x85, 0x9C, 0x45, 0xA1, 0x0C, - 0x4E, 0xB2, 0x74, 0x82, 0x6F, 0x1F, 0x08, 0x9F - }, - { - 0xB7, 0x52, 0x96, 0x27, 0x07, 0xA1, 0x7B, 0x66, - 0x4F, 0xAE, 0xB3, 0x13, 0xE2, 0xB9, 0x52, 0xDC, - 0x03, 0xE7, 0x4A, 0x7E, 0x94, 0x47, 0x09, 0x8A, - 0xA6, 0xD4, 0xEA, 0x5B, 0xD2, 0x87, 0xD0, 0x7A, - 0x12, 0x25, 0xEC, 0xED, 0xA9, 0x81, 0x15, 0x70, - 0x58, 0x0A, 0x51, 0x2B, 0x2B, 0x20, 0xB3, 0xFC, - 0xFC, 0xA7, 0x0B, 0x44, 0xF6, 0x45, 0x4E, 0xF3, - 0xC3, 0x52, 0x4C, 0xCA, 0x6B, 0x69, 0x47, 0x5B - }, - { - 0xDA, 0x0D, 0x8E, 0x54, 0x61, 0xF8, 0x10, 0x24, - 0xEF, 0xFE, 0xED, 0x5D, 0x70, 0x76, 0xA0, 0x4F, - 0xED, 0xED, 0xAC, 0x57, 0xE7, 0xC9, 0x8A, 0x59, - 0x45, 0xBF, 0xDE, 0x66, 0x75, 0x58, 0x18, 0x85, - 0x1B, 0xE1, 0x13, 0x6B, 0x71, 0xF4, 0x33, 0xA5, - 0x6B, 0xDA, 0x18, 0x41, 0xAE, 0x71, 0x39, 0x2C, - 0x4B, 0x82, 0x90, 0x82, 0x63, 0x59, 0xF5, 0x87, - 0x22, 0x3C, 0x3E, 0xF7, 0x37, 0xFF, 0x73, 0x2A - }, - { - 0xED, 0xB8, 0x6A, 0x23, 0x7C, 0x6F, 0x13, 0x7D, - 0xFB, 0xB3, 0x47, 0x01, 0x1E, 0xDB, 0x4C, 0x6E, - 0x86, 0x1F, 0x4D, 0x58, 0x14, 0x60, 0x85, 0x46, - 0x34, 0x41, 0x04, 0x2F, 0xA3, 0x63, 0x16, 0xF1, - 0xFA, 0xF8, 0x87, 0x11, 0xBB, 0x0F, 0x18, 0x11, - 0xDF, 0xBB, 0xBF, 0xA7, 0xB5, 0x1F, 0x9C, 0xE2, - 0xD4, 0x96, 0x05, 0x24, 0x3E, 0xD0, 0x16, 0xCB, - 0xAD, 0x68, 0x85, 0xEA, 0xE2, 0x03, 0x67, 0x4F - }, - { - 0xE6, 0xD8, 0xE0, 0xFB, 0xAA, 0x29, 0xDB, 0xEB, - 0x60, 0xF3, 0xC7, 0xF9, 0x85, 0xBA, 0xD7, 0x54, - 0xD7, 0x21, 0xAA, 0xC6, 0x3D, 0xA6, 0xF4, 0x49, - 0x0C, 0x9D, 0x7E, 0xA2, 0x31, 0xD2, 0x62, 0x2F, - 0xDF, 0xDE, 0xF1, 0x48, 0xD0, 0xCA, 0x44, 0x2B, - 0x8D, 0x59, 0xCF, 0x3E, 0x4F, 0x98, 0x35, 0xCB, - 0xC2, 0x40, 0xAF, 0x40, 0xFB, 0xA6, 0x3A, 0x2E, - 0xA5, 0xA2, 0x35, 0xD4, 0x6E, 0xEA, 0x6E, 0xAC - }, - { - 0xD4, 0xE4, 0x63, 0xC4, 0x88, 0x29, 0x87, 0xEB, - 0x44, 0xA5, 0xED, 0x0C, 0x82, 0x1D, 0x68, 0xB0, - 0xFE, 0xF9, 0x9D, 0x6F, 0x53, 0xA5, 0x7B, 0xF3, - 0x19, 0xBD, 0xAC, 0x25, 0xAC, 0x38, 0xEB, 0x0B, - 0x23, 0xE1, 0x13, 0x8C, 0x00, 0x12, 0xF5, 0xF3, - 0x83, 0x46, 0xA1, 0xDE, 0x9D, 0x4A, 0x99, 0x2A, - 0x64, 0xB9, 0x42, 0x83, 0x4A, 0x85, 0x6E, 0xFB, - 0xAA, 0x06, 0x20, 0xBD, 0xA2, 0x9F, 0x6A, 0x86 - }, - { - 0x42, 0xD8, 0x10, 0xD0, 0x1C, 0x2D, 0xA2, 0x47, - 0x35, 0xF0, 0x4A, 0x5E, 0x90, 0x13, 0x38, 0xFD, - 0xFC, 0x2D, 0xE1, 0x71, 0x5F, 0xF6, 0x64, 0x3A, - 0x37, 0x2F, 0x88, 0x0E, 0x6C, 0x5C, 0x6C, 0x13, - 0xD2, 0xB3, 0xAD, 0x70, 0x77, 0x46, 0x9D, 0x64, - 0x33, 0x54, 0x05, 0x4D, 0x32, 0xDD, 0x80, 0x49, - 0xEA, 0x63, 0x73, 0x2B, 0x57, 0x45, 0xBD, 0xB2, - 0x3B, 0xE2, 0xB5, 0x8E, 0x48, 0xC1, 0x01, 0x3A - }, - { - 0xCF, 0xBF, 0x54, 0x30, 0x07, 0x6F, 0x82, 0x5A, - 0x3B, 0xBB, 0x88, 0xC1, 0xBC, 0x0A, 0xEF, 0x61, - 0x25, 0x9E, 0x8F, 0x4D, 0x5F, 0xA3, 0x3C, 0x39, - 0x82, 0x50, 0x62, 0xF1, 0x5D, 0x19, 0xFD, 0x4A, - 0x01, 0x82, 0xCD, 0x97, 0x36, 0xD2, 0xAE, 0xC9, - 0x74, 0x9C, 0xCF, 0x83, 0x18, 0x6C, 0x35, 0x74, - 0xAB, 0x94, 0x42, 0x65, 0x40, 0x66, 0x0A, 0x9D, - 0xB8, 0xC3, 0xAA, 0xBB, 0xCB, 0xDD, 0x9D, 0x0F - }, - { - 0x6C, 0x24, 0x34, 0xA1, 0xAF, 0xA1, 0x57, 0xAC, - 0xCC, 0x34, 0xA5, 0xC4, 0x87, 0x2D, 0xFF, 0x69, - 0xFE, 0x7F, 0x31, 0x96, 0xCB, 0x1A, 0x75, 0x0C, - 0x54, 0x1D, 0x8B, 0x73, 0x92, 0x28, 0x88, 0xBA, - 0xBE, 0x89, 0xB1, 0xC3, 0x82, 0x02, 0x21, 0x86, - 0x20, 0xD8, 0x8D, 0x77, 0xDA, 0xD9, 0xDF, 0xBA, - 0xB3, 0xFB, 0xF7, 0x40, 0xB2, 0xD1, 0xD8, 0xF3, - 0x7E, 0xAD, 0x25, 0x8E, 0x2E, 0xF1, 0x06, 0x52 - }, - { - 0x48, 0xB7, 0x26, 0x8A, 0xA4, 0x34, 0x2F, 0xAB, - 0x02, 0x1D, 0x14, 0x72, 0xE9, 0x25, 0x7F, 0x76, - 0x58, 0x5C, 0xC5, 0x68, 0x10, 0xC8, 0xF2, 0xA6, - 0xE1, 0xD4, 0xA8, 0x94, 0x6B, 0x77, 0x71, 0x42, - 0xD4, 0x4A, 0xE5, 0x13, 0xA8, 0x80, 0x9F, 0x2D, - 0x6D, 0xC7, 0x26, 0x30, 0x5F, 0x79, 0x44, 0x60, - 0x4D, 0x95, 0x2D, 0x4A, 0x9F, 0x08, 0x5C, 0x5C, - 0x10, 0x50, 0xBA, 0xFD, 0xD2, 0x1D, 0x1E, 0x60 - }, - { - 0xCE, 0xCF, 0xCE, 0x4B, 0x12, 0xC6, 0xCF, 0x53, - 0xD1, 0xB1, 0xB2, 0xD4, 0x18, 0xA4, 0x93, 0xE3, - 0xF4, 0x29, 0x17, 0x03, 0x21, 0xE8, 0x1A, 0xA2, - 0x52, 0x63, 0xAA, 0xA7, 0x15, 0xD5, 0xCA, 0x38, - 0x9F, 0x65, 0xC3, 0xAC, 0xF9, 0x9B, 0x18, 0x0E, - 0x44, 0x6B, 0x50, 0xE6, 0x01, 0xFC, 0xBF, 0x44, - 0x61, 0xD0, 0x42, 0x6A, 0x85, 0x92, 0xA0, 0x77, - 0x42, 0x20, 0x18, 0x57, 0x12, 0x5F, 0x71, 0xEE - }, - { - 0x38, 0x5A, 0x75, 0x22, 0x42, 0xEB, 0x9E, 0xD5, - 0x6B, 0x07, 0x4B, 0x70, 0x2C, 0x91, 0xE7, 0x5A, - 0xEC, 0x0B, 0xE9, 0x06, 0x4B, 0xD9, 0xCF, 0x88, - 0x03, 0x04, 0xC2, 0x13, 0x27, 0x0C, 0xB2, 0xEA, - 0xE8, 0xE2, 0x1D, 0x9A, 0xE8, 0xC6, 0x08, 0x15, - 0x19, 0xF7, 0x5D, 0xFA, 0xBB, 0x00, 0x3B, 0x24, - 0x32, 0xB0, 0x47, 0x55, 0xB8, 0xC3, 0x2C, 0x97, - 0xAC, 0x29, 0x14, 0xE8, 0xBF, 0x45, 0xB2, 0x34 - }, - { - 0xD8, 0x9A, 0x12, 0x4A, 0x9B, 0x95, 0x8B, 0xA2, - 0x3D, 0x09, 0x20, 0x7A, 0xCF, 0xA6, 0x2A, 0x33, - 0xB8, 0x70, 0x89, 0xB2, 0x86, 0xE8, 0x43, 0x8B, - 0xDC, 0x01, 0xE2, 0x33, 0xAB, 0x2A, 0x86, 0x30, - 0xA1, 0xEE, 0xB6, 0xB2, 0xB9, 0xBA, 0x6B, 0x7D, - 0x21, 0x00, 0x10, 0x77, 0x33, 0xDE, 0xAF, 0x4C, - 0x20, 0x47, 0x8C, 0x26, 0xF2, 0x49, 0xC6, 0x89, - 0xC5, 0x26, 0x84, 0x73, 0xE2, 0xE9, 0xFA, 0x60 - }, - { - 0x43, 0xDE, 0x10, 0x92, 0xFF, 0x9F, 0xF5, 0x28, - 0x20, 0x6C, 0x6F, 0xCF, 0x81, 0x32, 0x2E, 0xAD, - 0x3D, 0x22, 0xEA, 0xA4, 0xC8, 0x54, 0x52, 0x15, - 0x77, 0xDF, 0x33, 0x62, 0x47, 0x49, 0x5C, 0xE1, - 0x72, 0xFC, 0x87, 0x39, 0x95, 0x30, 0x0B, 0x21, - 0xB9, 0x46, 0x10, 0xC9, 0xD2, 0xF6, 0x33, 0xB5, - 0x33, 0xBD, 0xE4, 0x56, 0x8C, 0xA0, 0x9C, 0x38, - 0x0E, 0x84, 0x68, 0xFE, 0x6A, 0xD8, 0xD8, 0x1D - }, - { - 0x86, 0x8B, 0x60, 0x11, 0x99, 0xEF, 0x00, 0x0B, - 0x70, 0x5C, 0xD6, 0x4D, 0x39, 0x30, 0x26, 0x2A, - 0x5A, 0xB9, 0x10, 0xE3, 0x4E, 0x2D, 0x78, 0xE8, - 0x58, 0x7B, 0x4E, 0x01, 0x0D, 0x37, 0x6D, 0xD4, - 0xA0, 0x0D, 0xE4, 0x48, 0x67, 0xD0, 0xE9, 0x33, - 0xEE, 0x39, 0xA1, 0xFA, 0x91, 0x47, 0xD4, 0x99, - 0xD1, 0x84, 0xF3, 0xA9, 0xCF, 0x35, 0x4F, 0x2D, - 0x3C, 0x51, 0x14, 0x6F, 0xF7, 0x15, 0x2D, 0x68 - }, - { - 0x15, 0x17, 0xF8, 0xF0, 0x44, 0x2F, 0x0D, 0x50, - 0xBB, 0xC0, 0xAA, 0xB6, 0x84, 0x6F, 0xDC, 0xE3, - 0xB7, 0x0F, 0xAE, 0xA4, 0xBB, 0x51, 0x13, 0xAC, - 0xB2, 0x3A, 0xBE, 0x10, 0x1D, 0x99, 0xA4, 0x0A, - 0x1B, 0x76, 0xC1, 0xE8, 0xDC, 0x2E, 0xA1, 0x93, - 0x62, 0x94, 0x82, 0x3A, 0xD8, 0x35, 0x4C, 0x11, - 0xE2, 0xE9, 0x6C, 0x67, 0x12, 0xBE, 0x4C, 0xF7, - 0x7C, 0x58, 0x3F, 0xD0, 0x6B, 0x5E, 0x5C, 0x55 - }, - { - 0xAF, 0x4C, 0x6C, 0x67, 0xC5, 0xCA, 0x38, 0x38, - 0x73, 0x48, 0xCA, 0x3E, 0xC2, 0xBE, 0xD7, 0xFB, - 0xA8, 0xC2, 0xB3, 0xD2, 0x2D, 0xE1, 0x48, 0xD0, - 0x8A, 0x61, 0x8C, 0x29, 0x70, 0x23, 0xFB, 0x7B, - 0x6D, 0x2C, 0x15, 0x3D, 0x5E, 0xFC, 0xD1, 0x68, - 0x89, 0x99, 0x91, 0x0B, 0x20, 0xE1, 0xEA, 0xC7, - 0xC1, 0x00, 0xA2, 0xC5, 0xA6, 0xC1, 0xAC, 0xF5, - 0xE9, 0x8F, 0x14, 0x3B, 0x41, 0xDC, 0x8A, 0x12 - }, - { - 0xA2, 0xAD, 0x94, 0x24, 0x3B, 0x8E, 0xEA, 0x68, - 0xF5, 0xFA, 0xDD, 0x69, 0x08, 0xAD, 0xB0, 0xDA, - 0xCD, 0xAA, 0x6A, 0x6D, 0x24, 0xC2, 0x50, 0xD3, - 0x39, 0x40, 0x3D, 0xBA, 0x82, 0x31, 0xBD, 0x51, - 0xE8, 0x87, 0xCB, 0x5B, 0x1B, 0x7B, 0xDE, 0x27, - 0x74, 0xC6, 0xB0, 0x8A, 0xCC, 0xE0, 0xF7, 0x49, - 0x56, 0x48, 0xDA, 0x3B, 0xEB, 0xC7, 0xB1, 0xC2, - 0x82, 0x15, 0x08, 0xC4, 0xD3, 0x82, 0xF7, 0x30 - }, - { - 0x28, 0xF8, 0x8C, 0xDB, 0xE9, 0x03, 0xAD, 0x63, - 0xA0, 0x23, 0x31, 0xDE, 0x1A, 0x32, 0xAF, 0x6D, - 0xBB, 0xA8, 0x2D, 0x7F, 0xC0, 0x79, 0x87, 0x02, - 0x72, 0x49, 0x33, 0xDA, 0x77, 0x38, 0x07, 0xBC, - 0x80, 0x42, 0x78, 0x13, 0x47, 0x81, 0xF1, 0x26, - 0x23, 0x32, 0x20, 0xE3, 0x07, 0x92, 0x81, 0x31, - 0xB2, 0x47, 0x10, 0xB4, 0x67, 0x4E, 0xD7, 0x05, - 0x11, 0x2F, 0x95, 0xD1, 0xAA, 0x37, 0xA2, 0xDC - }, - { - 0x5B, 0xB2, 0x92, 0x65, 0xE2, 0x46, 0xB8, 0x84, - 0xFF, 0x40, 0x91, 0x4F, 0xFA, 0x93, 0xD9, 0xA1, - 0x2E, 0xDC, 0x19, 0xEE, 0xE9, 0xCC, 0x8A, 0x83, - 0x63, 0x1D, 0x68, 0xBD, 0x46, 0xAA, 0xD3, 0x35, - 0x4B, 0xA6, 0x67, 0x4B, 0x91, 0x3F, 0x4F, 0x82, - 0x3E, 0x79, 0x1F, 0x0C, 0xB1, 0x9E, 0xA6, 0xA6, - 0x7C, 0x6E, 0x32, 0xE9, 0xBE, 0x0D, 0x0F, 0xF5, - 0x76, 0x0F, 0x16, 0xDD, 0x75, 0xA8, 0x7B, 0x5D - }, - { - 0xBF, 0x3C, 0x06, 0xDC, 0x6D, 0x94, 0xE3, 0x85, - 0x9A, 0x4D, 0xAA, 0x50, 0xEC, 0xA1, 0xAF, 0x53, - 0x57, 0xE3, 0x45, 0x79, 0xE5, 0x99, 0xF8, 0x20, - 0x49, 0xE1, 0xCC, 0xA7, 0xA7, 0xD4, 0xF3, 0x3F, - 0xEA, 0x44, 0x3B, 0x44, 0x69, 0x1B, 0xD4, 0x36, - 0x88, 0xF5, 0x55, 0x05, 0x31, 0xCF, 0x22, 0xB7, - 0x12, 0x77, 0x89, 0x0B, 0xFF, 0xAE, 0x1E, 0xCE, - 0x78, 0x3F, 0x56, 0x63, 0xA1, 0xC4, 0xD7, 0x1A - }, - { - 0xC9, 0x0D, 0xF5, 0x32, 0xF2, 0xF1, 0x49, 0x3A, - 0x11, 0x55, 0xBE, 0x8C, 0x2A, 0x44, 0x00, 0x92, - 0x20, 0x49, 0x97, 0x4E, 0x7D, 0x4F, 0x4B, 0x54, - 0xF8, 0x20, 0xC2, 0x26, 0x9D, 0x3B, 0x16, 0x1B, - 0x6E, 0x88, 0xEB, 0x77, 0x6B, 0x85, 0x9B, 0x89, - 0xB8, 0x56, 0x7F, 0xBC, 0x55, 0x0C, 0x4F, 0x54, - 0xAA, 0xD2, 0x7A, 0x16, 0x10, 0x65, 0x6D, 0x62, - 0x5C, 0x32, 0x7F, 0x66, 0x5D, 0xCA, 0x70, 0x7C - }, - { - 0x3D, 0x39, 0xEE, 0xCC, 0x9E, 0x90, 0x42, 0x36, - 0xDC, 0x85, 0x7B, 0xA4, 0x9D, 0x55, 0xD3, 0xBA, - 0xD7, 0x65, 0x72, 0xA9, 0x1A, 0x75, 0x95, 0x03, - 0x37, 0x6B, 0x77, 0x08, 0xD6, 0x2D, 0x5A, 0x78, - 0x5C, 0x23, 0x06, 0x80, 0x59, 0xCF, 0x68, 0x89, - 0x7F, 0x23, 0xEE, 0xC5, 0x07, 0x21, 0x9B, 0x0A, - 0x02, 0xED, 0xA2, 0xD8, 0xBC, 0x94, 0xFA, 0x69, - 0x89, 0xA5, 0x14, 0x82, 0x22, 0x03, 0xC8, 0xD1 - }, - { - 0xE0, 0x8C, 0x54, 0xD9, 0x98, 0xF9, 0x2B, 0x7A, - 0x54, 0xA2, 0x4C, 0xA6, 0xAE, 0xB1, 0x53, 0xA6, - 0x4F, 0x9C, 0x9F, 0x1F, 0xC3, 0x36, 0x58, 0xB3, - 0xED, 0xAC, 0x2C, 0x4B, 0xB5, 0x26, 0x31, 0x58, - 0xDA, 0xDF, 0x00, 0xD3, 0x51, 0x9A, 0x11, 0x9A, - 0x56, 0x14, 0xC7, 0xF3, 0x79, 0x40, 0xE5, 0x5D, - 0x13, 0xCC, 0xE4, 0x66, 0xCB, 0x71, 0xA4, 0x07, - 0xC3, 0x9F, 0xC5, 0x1E, 0x1E, 0xFE, 0x18, 0xDA - }, - { - 0x74, 0x76, 0x76, 0x07, 0x04, 0x1D, 0xD4, 0xB7, - 0xC5, 0x6B, 0x18, 0x9E, 0xE8, 0xF2, 0x77, 0x31, - 0xA5, 0x16, 0x72, 0x23, 0xEB, 0x7A, 0xF9, 0xB9, - 0x39, 0xE1, 0x18, 0xF8, 0x7D, 0x80, 0xB4, 0x9E, - 0xA8, 0xD0, 0xD0, 0x1F, 0x74, 0xF3, 0x98, 0xB1, - 0x72, 0xA8, 0xAD, 0x0D, 0xBF, 0x99, 0x41, 0x4F, - 0x08, 0xD2, 0xB7, 0xD8, 0xD7, 0x52, 0x16, 0xA1, - 0x82, 0x25, 0x27, 0x3D, 0x8D, 0x7F, 0xD0, 0x5D - }, - { - 0xFE, 0xE8, 0x9A, 0x92, 0xCC, 0xF9, 0xF1, 0xEB, - 0x08, 0x4A, 0xAB, 0xA9, 0x54, 0x97, 0xEF, 0x0F, - 0x30, 0x13, 0x4C, 0x19, 0x1C, 0xF9, 0x0A, 0x49, - 0xD2, 0x2C, 0x7D, 0x2F, 0x66, 0x14, 0x99, 0x3C, - 0xBE, 0x1A, 0x4B, 0x65, 0x13, 0xED, 0xC1, 0x53, - 0x86, 0x8A, 0x3D, 0x56, 0x2B, 0x5B, 0x02, 0x26, - 0xBA, 0x8E, 0x1B, 0x0D, 0xCB, 0x69, 0xED, 0x45, - 0xAF, 0x47, 0xCE, 0x4F, 0x86, 0xBA, 0x47, 0x4A - }, - { - 0xCD, 0xAE, 0x94, 0xB6, 0xD1, 0xD8, 0x35, 0xF6, - 0xC7, 0x4C, 0x76, 0xEC, 0x3A, 0x2D, 0xB6, 0x5B, - 0xBD, 0xFA, 0xE1, 0x9D, 0x7B, 0x05, 0x0D, 0xC9, - 0x5D, 0x65, 0x87, 0x33, 0xB8, 0xB2, 0x2C, 0x6F, - 0x9E, 0x0B, 0x63, 0xCC, 0x90, 0x5A, 0x29, 0xEA, - 0x88, 0x78, 0xCA, 0x39, 0x45, 0x56, 0xB3, 0x67, - 0x3C, 0x62, 0x79, 0x15, 0x46, 0xA9, 0xA1, 0xF0, - 0xD1, 0x56, 0x5F, 0xAD, 0xC5, 0x35, 0x36, 0xC1 - }, - { - 0xC7, 0x22, 0x8B, 0x6F, 0x00, 0x00, 0x17, 0xD2, - 0xBE, 0x4B, 0xF2, 0xAE, 0x48, 0xAD, 0xDB, 0x78, - 0x5E, 0x27, 0x35, 0xBF, 0x3C, 0x61, 0x4D, 0x3C, - 0x34, 0x23, 0x1F, 0x1D, 0x0C, 0x88, 0x7D, 0x3A, - 0x8E, 0x88, 0x88, 0x0B, 0x67, 0xAD, 0x3B, 0x2F, - 0x65, 0x23, 0xDD, 0x67, 0x19, 0x34, 0x2C, 0xD4, - 0xF0, 0x59, 0x35, 0xD2, 0xE5, 0x26, 0x7F, 0x36, - 0x80, 0xE7, 0x73, 0xBD, 0x5E, 0xAD, 0xFE, 0x1D - }, - { - 0x12, 0x27, 0x44, 0xFE, 0x3F, 0xFF, 0x9A, 0x05, - 0x5F, 0x0F, 0x3B, 0xDE, 0x01, 0xEB, 0x2F, 0x44, - 0x6B, 0x0C, 0xDA, 0xF3, 0xAE, 0xD7, 0x2C, 0xAA, - 0x29, 0x40, 0x74, 0x19, 0x20, 0x12, 0x0A, 0x96, - 0x4F, 0xCF, 0xF8, 0x70, 0x99, 0xB0, 0x8E, 0xF3, - 0x34, 0x96, 0xE3, 0x99, 0x03, 0x2A, 0x82, 0xDA, - 0xAD, 0x4F, 0xED, 0x30, 0x31, 0x17, 0x2F, 0x77, - 0x47, 0x92, 0x58, 0xFA, 0x39, 0xDB, 0x92, 0xFD - }, - { - 0x1F, 0xB4, 0xE3, 0x67, 0xEA, 0xB6, 0x42, 0xB7, - 0x2E, 0x43, 0xAD, 0x4A, 0xBD, 0xFC, 0xAD, 0x74, - 0x62, 0x0C, 0x3F, 0x6C, 0x63, 0xA8, 0x91, 0x31, - 0x28, 0xD2, 0x22, 0x6E, 0xB1, 0x92, 0xF9, 0x99, - 0x2E, 0xB9, 0xC8, 0xF7, 0x6A, 0xE2, 0x06, 0xD3, - 0xF5, 0xDE, 0xC7, 0x26, 0xA5, 0xA6, 0x86, 0xB4, - 0xAE, 0x37, 0xB5, 0x57, 0xAB, 0x57, 0xF9, 0x56, - 0x48, 0x53, 0x34, 0xF7, 0x3D, 0xCE, 0x02, 0xE0 - }, - { - 0x04, 0x25, 0xCA, 0xAA, 0x92, 0x3B, 0x47, 0xB3, - 0x50, 0x45, 0xEB, 0x50, 0x82, 0x9C, 0x04, 0x8B, - 0xC8, 0x90, 0x44, 0x4A, 0xFE, 0xEF, 0xC0, 0xAF, - 0xC9, 0xD1, 0x87, 0x7B, 0x82, 0x1E, 0x04, 0x3C, - 0x9C, 0x7B, 0x9D, 0x6D, 0xC3, 0x3F, 0xBB, 0xDF, - 0xA5, 0x37, 0xC1, 0xEC, 0xE3, 0x11, 0x96, 0x5B, - 0x2F, 0xEE, 0x89, 0x82, 0xBC, 0x46, 0xA2, 0xA7, - 0x50, 0xBF, 0xC7, 0x1D, 0x79, 0xDB, 0xEA, 0x04 - }, - { - 0x6B, 0x9D, 0x86, 0xF1, 0x5C, 0x09, 0x0A, 0x00, - 0xFC, 0x3D, 0x90, 0x7F, 0x90, 0x6C, 0x5E, 0xB7, - 0x92, 0x65, 0xE5, 0x8B, 0x88, 0xEB, 0x64, 0x29, - 0x4B, 0x4C, 0xC4, 0xE2, 0xB8, 0x9B, 0x1A, 0x7C, - 0x5E, 0xE3, 0x12, 0x7E, 0xD2, 0x1B, 0x45, 0x68, - 0x62, 0xDE, 0x6B, 0x2A, 0xBD, 0xA5, 0x9E, 0xAA, - 0xCF, 0x2D, 0xCB, 0xE9, 0x22, 0xCA, 0x75, 0x5E, - 0x40, 0x73, 0x5B, 0xE8, 0x1D, 0x9C, 0x88, 0xA5 - }, - { - 0x14, 0x6A, 0x18, 0x7A, 0x99, 0xE8, 0xA2, 0xD2, - 0x33, 0xE0, 0xEB, 0x37, 0x3D, 0x43, 0x7B, 0x02, - 0xBF, 0xA8, 0xD6, 0x51, 0x5B, 0x3C, 0xA1, 0xDE, - 0x48, 0xA6, 0xB6, 0xAC, 0xF7, 0x43, 0x7E, 0xB7, - 0xE7, 0xAC, 0x3F, 0x2D, 0x19, 0xEF, 0x3B, 0xB9, - 0xB8, 0x33, 0xCC, 0x57, 0x61, 0xDB, 0xA2, 0x2D, - 0x1A, 0xD0, 0x60, 0xBE, 0x76, 0xCD, 0xCB, 0x81, - 0x2D, 0x64, 0xD5, 0x78, 0xE9, 0x89, 0xA5, 0xA4 - }, - { - 0x25, 0x75, 0x4C, 0xA6, 0x66, 0x9C, 0x48, 0x70, - 0x84, 0x03, 0x88, 0xEA, 0x64, 0xE9, 0x5B, 0xD2, - 0xE0, 0x81, 0x0D, 0x36, 0x3C, 0x4C, 0xF6, 0xA1, - 0x6E, 0xA1, 0xBD, 0x06, 0x68, 0x6A, 0x93, 0xC8, - 0xA1, 0x25, 0xF2, 0x30, 0x22, 0x9D, 0x94, 0x84, - 0x85, 0xE1, 0xA8, 0x2D, 0xE4, 0x82, 0x00, 0x35, - 0x8F, 0x3E, 0x02, 0xB5, 0x05, 0xDA, 0xBC, 0x4F, - 0x13, 0x9C, 0x03, 0x79, 0xDC, 0x2B, 0x30, 0x80 - }, - { - 0x0E, 0x26, 0xCB, 0xC7, 0x8D, 0xC7, 0x54, 0xEC, - 0xA0, 0x6C, 0xF8, 0xCB, 0x31, 0xFC, 0xBA, 0xBB, - 0x18, 0x88, 0x92, 0xC1, 0x04, 0x50, 0x89, 0x05, - 0x49, 0xB2, 0xD4, 0x03, 0xA2, 0xA3, 0xC4, 0x57, - 0x70, 0x01, 0xF7, 0x4A, 0x76, 0xBD, 0x38, 0x99, - 0x0D, 0x75, 0x5B, 0xAE, 0x05, 0x26, 0x64, 0x83, - 0x29, 0xF6, 0x35, 0x45, 0xED, 0x16, 0x99, 0x5C, - 0xB1, 0xE6, 0x34, 0x3F, 0x18, 0x9F, 0x8E, 0x6F - }, - { - 0x58, 0xE7, 0x98, 0x0B, 0x8B, 0x1A, 0x0B, 0x88, - 0xDA, 0x9D, 0xA8, 0x64, 0x0F, 0x2B, 0x96, 0xE3, - 0xE0, 0x48, 0x36, 0x61, 0x30, 0xC2, 0x66, 0x21, - 0x7D, 0xDC, 0x79, 0x53, 0x50, 0x8F, 0x4A, 0x40, - 0xD1, 0x67, 0x4D, 0xAB, 0xD3, 0x92, 0x89, 0xE3, - 0xF1, 0x0C, 0x61, 0x19, 0x68, 0xCC, 0xD1, 0xE9, - 0xCC, 0xC1, 0x8C, 0xAD, 0xC7, 0x77, 0x4A, 0x99, - 0x7D, 0xD1, 0xFA, 0x94, 0xE8, 0x35, 0x47, 0x07 - }, - { - 0x69, 0x6F, 0xB8, 0x47, 0x63, 0xE0, 0x23, 0x58, - 0x4B, 0x35, 0x90, 0x7A, 0x8B, 0x8A, 0xAA, 0x9E, - 0x0E, 0x78, 0x6F, 0x2C, 0xA5, 0x91, 0x45, 0x41, - 0x91, 0x58, 0x48, 0xFB, 0x6D, 0xDA, 0xB8, 0xD3, - 0xD2, 0xEA, 0xB6, 0x00, 0xC1, 0x38, 0xCE, 0x67, - 0x17, 0xB0, 0xC7, 0x02, 0x59, 0xD3, 0x19, 0x3E, - 0xA1, 0x56, 0x95, 0xC8, 0x50, 0x53, 0x7F, 0x2C, - 0x70, 0x6C, 0xA4, 0xAF, 0x15, 0x8E, 0x95, 0x7E - }, - { - 0x23, 0xDE, 0x6E, 0x73, 0x07, 0x9C, 0x8C, 0x20, - 0x47, 0xA7, 0x84, 0x6A, 0x83, 0xCC, 0xAC, 0xAB, - 0xD3, 0x71, 0x16, 0x3B, 0x7B, 0x6D, 0x54, 0xEB, - 0x03, 0x2B, 0xC4, 0x9B, 0x66, 0x97, 0x42, 0xBE, - 0x71, 0x7B, 0x99, 0xDA, 0x12, 0xC6, 0x46, 0xAD, - 0x52, 0x57, 0x06, 0xF2, 0x22, 0xE1, 0xDF, 0x4A, - 0x91, 0xDD, 0x0C, 0xC6, 0x4D, 0xF1, 0x82, 0xDA, - 0x00, 0x73, 0x1D, 0x43, 0x9C, 0x46, 0xF8, 0xD2 - }, - { - 0xBB, 0x74, 0xF3, 0x6A, 0x9D, 0xB6, 0x96, 0xC9, - 0x33, 0x35, 0xE6, 0xC4, 0x6A, 0xAB, 0x58, 0xDB, - 0x10, 0xCB, 0x07, 0xEA, 0x4F, 0x1B, 0x71, 0x93, - 0x63, 0x05, 0x22, 0x83, 0x90, 0x95, 0x94, 0x78, - 0xF8, 0x73, 0x4E, 0x21, 0x54, 0x90, 0xE9, 0xAE, - 0x2A, 0x3E, 0xC8, 0xF7, 0xF7, 0x67, 0x33, 0xAE, - 0x3F, 0x8B, 0x9A, 0x3F, 0xD7, 0xC4, 0x06, 0xC6, - 0xCA, 0xC7, 0x09, 0x97, 0x5C, 0x40, 0xF8, 0x56 - }, - { - 0xEC, 0x63, 0x04, 0xD3, 0x8E, 0x23, 0x2C, 0x09, - 0x6A, 0xB5, 0x86, 0xCA, 0xDF, 0x27, 0x02, 0x6D, - 0xC5, 0xE5, 0x32, 0x17, 0xD0, 0xE8, 0xB0, 0xC6, - 0x0A, 0xDA, 0xAE, 0x22, 0xF4, 0xE8, 0xC2, 0x2D, - 0x30, 0xBC, 0x51, 0x77, 0xF1, 0xC8, 0x3A, 0xCD, - 0x92, 0x5E, 0x02, 0xA2, 0xDA, 0x89, 0x59, 0x5F, - 0xC1, 0x06, 0x09, 0x0E, 0x2E, 0x53, 0xED, 0xB3, - 0x1C, 0xDB, 0x76, 0xFF, 0x37, 0xEB, 0x61, 0x80 - }, - { - 0x92, 0xF9, 0xFC, 0x6B, 0xC5, 0x9A, 0x54, 0x3F, - 0x0D, 0xC9, 0xA1, 0x79, 0x8F, 0xB1, 0xE5, 0xD5, - 0x23, 0x47, 0x4E, 0x48, 0xFF, 0x3E, 0x29, 0x49, - 0x7F, 0x72, 0x80, 0xD1, 0xC4, 0x08, 0xC8, 0x66, - 0x33, 0x48, 0xFE, 0x2A, 0xF7, 0x8F, 0x6C, 0x4E, - 0x5E, 0xF5, 0xC0, 0xA0, 0x17, 0xF3, 0xD3, 0xF2, - 0x15, 0xEC, 0xDD, 0x7A, 0x40, 0x0A, 0xC5, 0x77, - 0x3B, 0x9E, 0x25, 0x60, 0x68, 0x84, 0x5A, 0x92 - }, - { - 0x4A, 0x25, 0xB5, 0x62, 0xF2, 0xFA, 0x01, 0xDD, - 0xEE, 0x7E, 0xA2, 0xE9, 0xFB, 0xF5, 0x2F, 0x8C, - 0x75, 0x6D, 0x28, 0xDB, 0x4A, 0x8B, 0xF7, 0x0E, - 0x74, 0x0E, 0x90, 0x27, 0x42, 0x6E, 0x51, 0x63, - 0x9D, 0xF8, 0x78, 0x8D, 0x13, 0x38, 0x56, 0x85, - 0x8D, 0x01, 0xFD, 0xDB, 0xDD, 0x5B, 0x98, 0x79, - 0x44, 0xC3, 0x00, 0xDC, 0x7F, 0x82, 0x41, 0xFB, - 0xCE, 0xFA, 0x4F, 0x12, 0x94, 0x8A, 0xFE, 0xAE - }, - { - 0x34, 0x21, 0x2D, 0xD9, 0xF0, 0x65, 0x1F, 0x81, - 0x80, 0x9A, 0x14, 0xED, 0xBC, 0xF7, 0xF3, 0xAC, - 0xDE, 0xDE, 0x78, 0x72, 0xC7, 0xA4, 0x84, 0x7B, - 0xEA, 0x9F, 0x7A, 0xB7, 0x59, 0x73, 0x82, 0x47, - 0x7A, 0x4C, 0xB8, 0x47, 0x9A, 0x27, 0x63, 0x21, - 0x23, 0x5E, 0x90, 0x21, 0x57, 0x94, 0x46, 0xA4, - 0x38, 0x8A, 0x99, 0xE5, 0x60, 0xA3, 0x90, 0x7A, - 0xEE, 0xF2, 0xB4, 0x38, 0xFE, 0x6B, 0x90, 0xC4 - }, - { - 0xD6, 0x2C, 0xF7, 0xAB, 0xBC, 0x7D, 0x7B, 0xCD, - 0x5B, 0xEB, 0x1E, 0xE4, 0x8C, 0x43, 0xB8, 0x04, - 0xFD, 0x0D, 0xB4, 0x55, 0xE7, 0xF4, 0xFE, 0xBB, - 0xCF, 0xF1, 0x4B, 0x05, 0xBE, 0x90, 0x47, 0xE2, - 0x7E, 0x51, 0x8D, 0x6D, 0x3A, 0x6A, 0xDA, 0x4D, - 0x58, 0x63, 0xB7, 0xEC, 0x7F, 0x84, 0x92, 0x45, - 0x89, 0x40, 0xAC, 0x6B, 0xDD, 0xB5, 0x06, 0x59, - 0x2C, 0xCB, 0xC8, 0x96, 0xAF, 0xBB, 0x77, 0xA3 - }, - { - 0x33, 0xA3, 0xA2, 0x63, 0x6F, 0x91, 0x98, 0xD3, - 0x7A, 0x5F, 0xF1, 0xBF, 0xF9, 0xEB, 0x10, 0x02, - 0x4B, 0x28, 0x46, 0x80, 0x39, 0xF4, 0x91, 0x40, - 0x2D, 0x39, 0xB7, 0x08, 0xC5, 0x5D, 0x27, 0xE5, - 0xE8, 0xDF, 0x5E, 0x3E, 0x19, 0x49, 0x95, 0x82, - 0x35, 0xCA, 0xD9, 0x80, 0x74, 0x20, 0x96, 0xF2, - 0x77, 0x9A, 0x1D, 0x71, 0xDA, 0xD5, 0x8F, 0xAF, - 0xA3, 0xCD, 0x02, 0xCB, 0x5E, 0xAA, 0x98, 0xC5 - }, - { - 0xB7, 0xA3, 0x89, 0x90, 0xE6, 0xF4, 0x56, 0x4A, - 0xA3, 0xD9, 0x3A, 0x79, 0x37, 0x10, 0x0C, 0x29, - 0xF9, 0x40, 0xAF, 0xF7, 0xCB, 0x20, 0x86, 0x5A, - 0x1C, 0x21, 0x89, 0x81, 0xA5, 0x42, 0x04, 0x86, - 0x08, 0x17, 0x81, 0xF8, 0xD5, 0x0C, 0x86, 0x62, - 0x5C, 0xC5, 0xD7, 0x6D, 0x0F, 0x5C, 0xCC, 0x4E, - 0xB6, 0x5D, 0x43, 0x66, 0x09, 0x62, 0x4F, 0x21, - 0xD0, 0x53, 0x39, 0xAB, 0x0C, 0xF7, 0x9F, 0x4C - }, - { - 0x9D, 0x66, 0x5A, 0x3F, 0xDD, 0x10, 0x45, 0x9E, - 0x77, 0xF0, 0x3A, 0xC8, 0xC0, 0xE2, 0x39, 0x01, - 0x94, 0x89, 0x69, 0x3C, 0xC9, 0x31, 0x5A, 0xA3, - 0xFF, 0x11, 0x29, 0x11, 0xD2, 0xAC, 0xF0, 0xB7, - 0xD2, 0x76, 0xAC, 0x76, 0x9B, 0xED, 0xFD, 0x85, - 0x2D, 0x28, 0x89, 0xDD, 0x12, 0xDB, 0x91, 0x39, - 0x8B, 0x01, 0xC4, 0xF4, 0xA5, 0xDA, 0x27, 0x80, - 0xB1, 0xDE, 0xFE, 0x0D, 0x95, 0xB6, 0x32, 0x70 - }, - { - 0x70, 0xFB, 0x9E, 0xFD, 0x5B, 0xCA, 0x7F, 0x19, - 0xB6, 0xE3, 0x1D, 0x64, 0x0D, 0xCF, 0x88, 0xD7, - 0x7E, 0x76, 0x8A, 0xE2, 0x27, 0xEC, 0xB3, 0xFD, - 0x6B, 0x47, 0x13, 0x78, 0x94, 0xF5, 0x49, 0xBF, - 0x1C, 0xF0, 0x6E, 0x5D, 0xB4, 0x54, 0x60, 0x44, - 0xDD, 0x9F, 0x46, 0x5C, 0x9C, 0x85, 0xF7, 0x28, - 0x4F, 0xE5, 0x4D, 0x2B, 0x71, 0x52, 0x69, 0x9B, - 0xE4, 0xBD, 0x55, 0x5A, 0x90, 0x9A, 0x88, 0xA9 - }, - { - 0x7A, 0xFD, 0xB0, 0x19, 0x30, 0x87, 0xE0, 0xC9, - 0xF8, 0xB4, 0xDD, 0x8B, 0x48, 0xD9, 0xF2, 0x0A, - 0xCE, 0x27, 0x13, 0xAF, 0xC7, 0x1B, 0xCC, 0x93, - 0x82, 0xB5, 0x42, 0x90, 0xAE, 0xBF, 0xFE, 0xB2, - 0xD1, 0x38, 0xF4, 0xDC, 0xF0, 0x28, 0xF9, 0xC4, - 0x3C, 0xC1, 0x80, 0x89, 0x84, 0x77, 0xA3, 0x9E, - 0x3F, 0x53, 0xA8, 0xD1, 0xBF, 0x67, 0xCE, 0xB6, - 0x08, 0x26, 0x1F, 0xAE, 0x6D, 0xDB, 0x1A, 0xBC - }, - { - 0x05, 0x99, 0x0D, 0x7D, 0x7D, 0xF1, 0xD4, 0x84, - 0xF5, 0xB1, 0xCA, 0xE9, 0xEE, 0x5D, 0xFC, 0xB4, - 0x3F, 0x2C, 0xBE, 0x18, 0x6C, 0x1A, 0x5B, 0x18, - 0x1A, 0x37, 0x31, 0xD4, 0xB1, 0x54, 0x8E, 0xBF, - 0xF5, 0xBF, 0x61, 0xCB, 0x0F, 0x6D, 0x9F, 0xC2, - 0x30, 0xF2, 0x5E, 0x86, 0x78, 0xB7, 0x99, 0xE0, - 0xE8, 0x30, 0x26, 0xA0, 0x86, 0x6B, 0xF0, 0xAC, - 0xAB, 0x08, 0x9E, 0x10, 0x2E, 0x67, 0xAB, 0x6B - }, - { - 0x1A, 0xF7, 0xA5, 0xCE, 0x58, 0x7C, 0x8D, 0x87, - 0xC7, 0xB7, 0x9F, 0xA3, 0xE7, 0x23, 0xD7, 0x4C, - 0xE0, 0x26, 0xB5, 0x28, 0x67, 0x52, 0xFD, 0x0C, - 0x37, 0x42, 0xC6, 0xF0, 0x41, 0x8E, 0xD7, 0x85, - 0x99, 0x0D, 0x21, 0xF2, 0x8D, 0xA8, 0x39, 0xCE, - 0x82, 0x12, 0xED, 0x55, 0x0C, 0x37, 0x3E, 0x6D, - 0x3A, 0x75, 0xD5, 0x5C, 0x31, 0x77, 0x04, 0x41, - 0xEE, 0xAF, 0xF2, 0xD5, 0x0F, 0x6E, 0x61, 0xB6 - }, - { - 0xDD, 0xEE, 0x0C, 0x76, 0xC9, 0xBD, 0xD3, 0x2D, - 0x70, 0x49, 0x35, 0x4C, 0xFC, 0x85, 0xDC, 0x68, - 0x67, 0xE2, 0x49, 0x2E, 0x47, 0xFE, 0xB0, 0x8E, - 0x39, 0x83, 0xD0, 0xB6, 0x78, 0x84, 0x5D, 0x7E, - 0xC6, 0xC9, 0x79, 0x3C, 0x33, 0x26, 0xBF, 0xDC, - 0x1E, 0x11, 0x32, 0x76, 0xD1, 0x77, 0xFE, 0x38, - 0x82, 0x52, 0x04, 0xDD, 0x00, 0x07, 0x39, 0x89, - 0xC0, 0x81, 0xCC, 0x3B, 0x71, 0xC6, 0x8D, 0x5F - }, - { - 0xDE, 0x07, 0x06, 0x48, 0xB3, 0x7C, 0x47, 0xDC, - 0x9F, 0x2F, 0x6D, 0x2A, 0xB2, 0x07, 0x73, 0xCD, - 0x82, 0xFA, 0x57, 0x25, 0xA6, 0x90, 0x0E, 0xB7, - 0x1C, 0xDD, 0xB0, 0xC9, 0xF3, 0x9B, 0x31, 0xDF, - 0x6D, 0x07, 0x73, 0x24, 0x6E, 0x8E, 0xF9, 0x03, - 0x49, 0x67, 0x75, 0x2D, 0xB7, 0xED, 0x22, 0x73, - 0x3F, 0x43, 0x79, 0x94, 0x8D, 0xC3, 0x96, 0xDC, - 0x35, 0xAD, 0xBB, 0xE9, 0xF6, 0x53, 0x77, 0x40 - }, - { - 0xA6, 0x45, 0x6F, 0xBC, 0xFF, 0x9E, 0x3D, 0x5B, - 0x11, 0x6A, 0x0E, 0x33, 0x1A, 0x1F, 0x97, 0x4F, - 0x07, 0x0E, 0x95, 0x56, 0x09, 0x78, 0x1F, 0xA5, - 0x99, 0xD6, 0x08, 0xA3, 0x1D, 0xA7, 0x6A, 0xD8, - 0xAB, 0xFE, 0x34, 0x66, 0x17, 0xC2, 0x57, 0x86, - 0x51, 0x3B, 0x2C, 0x44, 0xBF, 0xE2, 0xCB, 0x45, - 0x7C, 0x43, 0xFA, 0x6F, 0x45, 0x36, 0x1C, 0xA9, - 0xC6, 0x34, 0x13, 0x11, 0xB7, 0xDD, 0xFB, 0xD5 - }, - { - 0x5C, 0x95, 0xD3, 0x82, 0x02, 0x18, 0x91, 0x04, - 0x8B, 0x5E, 0xC8, 0x1C, 0xC8, 0x8E, 0x66, 0xB1, - 0xB4, 0xD8, 0x0A, 0x00, 0xB5, 0xEE, 0x66, 0xB3, - 0xC0, 0x30, 0x77, 0x49, 0xE6, 0xF2, 0x4D, 0x17, - 0x0D, 0x23, 0xFA, 0xCC, 0x8E, 0xB2, 0x53, 0xB3, - 0x56, 0x2B, 0xF8, 0xA4, 0x5C, 0x37, 0x99, 0x0C, - 0xD2, 0xD3, 0xE4, 0x43, 0xB1, 0x8C, 0x68, 0xBB, - 0xCC, 0x6C, 0x83, 0x1D, 0xFD, 0xE2, 0xF8, 0xE5 - }, - { - 0xE3, 0x74, 0x00, 0xDB, 0xD9, 0x21, 0x0F, 0x31, - 0x37, 0xAC, 0xAF, 0x49, 0x24, 0x2F, 0xA1, 0x23, - 0xA0, 0x52, 0x95, 0x8A, 0x4C, 0x0D, 0x98, 0x90, - 0x62, 0x47, 0xD5, 0x35, 0xA3, 0x51, 0xFD, 0x52, - 0x29, 0x6E, 0x70, 0x10, 0x32, 0x5B, 0xDA, 0x84, - 0x1F, 0xA2, 0xAA, 0xB4, 0x47, 0x63, 0x76, 0x3C, - 0x55, 0x04, 0xD7, 0xB3, 0x0C, 0x6D, 0x79, 0xFC, - 0x1D, 0xC8, 0xCF, 0x10, 0x24, 0x46, 0x6D, 0xB0 - }, - { - 0x52, 0x73, 0xA3, 0xA1, 0x3C, 0xF0, 0xEC, 0x72, - 0x00, 0x44, 0x2C, 0xBD, 0x7B, 0x37, 0x44, 0x66, - 0xA7, 0x19, 0x0D, 0xDC, 0xA1, 0x31, 0xD9, 0x63, - 0xF8, 0xF8, 0x39, 0x65, 0xAE, 0xD3, 0xDD, 0x86, - 0xE9, 0xD4, 0x5A, 0xB4, 0x89, 0xB9, 0xC5, 0x62, - 0x47, 0xC9, 0xF2, 0xAA, 0x69, 0xFD, 0x7E, 0x31, - 0x87, 0xB8, 0xFA, 0x0D, 0xAC, 0x77, 0xC4, 0x7C, - 0xB2, 0x95, 0xBA, 0x62, 0x96, 0x78, 0x43, 0x94 - }, - { - 0x2A, 0xDB, 0x93, 0x49, 0xA9, 0xEC, 0x37, 0xFF, - 0x49, 0x62, 0xF4, 0x21, 0x7E, 0x80, 0xEB, 0xDC, - 0xD3, 0x60, 0x96, 0x7B, 0x51, 0x3D, 0x12, 0x02, - 0xD9, 0x98, 0x28, 0x31, 0x15, 0x5D, 0x2F, 0x43, - 0xEB, 0x9A, 0xDD, 0x63, 0xB5, 0xEC, 0x10, 0xD3, - 0xD0, 0x43, 0x0D, 0xC9, 0xCF, 0x76, 0x48, 0x11, - 0x7F, 0xC6, 0x0B, 0xAB, 0xBF, 0x8E, 0xBF, 0x19, - 0xFA, 0xCE, 0xE5, 0x50, 0x45, 0x5B, 0x60, 0xC9 - }, - { - 0xAC, 0xAA, 0xDA, 0x3E, 0x47, 0x37, 0xC6, 0x63, - 0xEB, 0xF0, 0x3C, 0x02, 0x49, 0xCC, 0xA6, 0xF3, - 0x17, 0x9A, 0x03, 0x84, 0xEA, 0x2A, 0xB1, 0x35, - 0xD4, 0xD7, 0xA2, 0xBB, 0x8A, 0x2F, 0x40, 0x53, - 0x9C, 0xDC, 0xE8, 0xA3, 0x76, 0x0F, 0xD1, 0x3D, - 0xEE, 0xEC, 0xD1, 0x60, 0x61, 0x7F, 0x72, 0xDE, - 0x63, 0x75, 0x4E, 0x21, 0x57, 0xCA, 0xDC, 0xF0, - 0x67, 0x32, 0x9C, 0x2A, 0x51, 0x98, 0xF8, 0xE0 - }, - { - 0xEF, 0x15, 0xE6, 0xDB, 0x96, 0xE6, 0xD0, 0xC1, - 0x8C, 0x70, 0xAD, 0xC3, 0xCD, 0xB3, 0x2B, 0x28, - 0x67, 0x74, 0x02, 0xE8, 0xEA, 0x44, 0x11, 0xEA, - 0x2F, 0x34, 0x68, 0xED, 0x93, 0x82, 0xE1, 0x9B, - 0xFE, 0xCA, 0xF5, 0xAC, 0xB8, 0x28, 0xA5, 0x2B, - 0xE1, 0x6B, 0x98, 0x1E, 0x48, 0x7E, 0x5B, 0xB4, - 0xA1, 0x43, 0x08, 0x65, 0x35, 0x8E, 0x97, 0x9F, - 0xB1, 0x07, 0x1F, 0xB9, 0x51, 0x14, 0xFF, 0xDD - }, - { - 0x05, 0x7E, 0xAB, 0x8F, 0xA6, 0x1C, 0x23, 0x09, - 0x67, 0xD9, 0x5D, 0xFB, 0x75, 0x45, 0x57, 0x0E, - 0x34, 0x1A, 0xE3, 0xC6, 0x73, 0x7C, 0x7D, 0xB2, - 0xA2, 0x27, 0xD9, 0x0F, 0xF3, 0x15, 0xD0, 0x98, - 0xD4, 0x76, 0xF7, 0x15, 0x77, 0x9E, 0x67, 0x72, - 0xB4, 0xED, 0x37, 0x54, 0x82, 0x66, 0xE6, 0x59, - 0x8C, 0x6F, 0x09, 0x69, 0x13, 0xC2, 0xFD, 0xD8, - 0xD6, 0xE4, 0x4F, 0xE2, 0xB5, 0x4D, 0x97, 0x80 - }, - { - 0xED, 0xE6, 0x8D, 0x1B, 0x13, 0xE7, 0xEF, 0x78, - 0xD9, 0xC4, 0xEE, 0x10, 0xEC, 0xEB, 0x1D, 0x2A, - 0xEE, 0xC3, 0xB8, 0x15, 0x7F, 0xDB, 0x91, 0x41, - 0x8C, 0x22, 0x19, 0xF6, 0x41, 0x49, 0x74, 0x70, - 0x17, 0xAC, 0xA7, 0xD4, 0x65, 0xB8, 0xB4, 0x7F, - 0xFA, 0x53, 0x64, 0x4B, 0x8B, 0xC6, 0xDA, 0x12, - 0xDD, 0x45, 0xD1, 0x05, 0x5E, 0x47, 0xB4, 0xD8, - 0x39, 0x0E, 0xB2, 0xBD, 0x60, 0x2B, 0xA0, 0x30 - }, - { - 0x27, 0xF8, 0x56, 0xE6, 0x3E, 0xB9, 0x4D, 0x08, - 0xFB, 0xBE, 0x50, 0x22, 0xB0, 0xED, 0xDB, 0xC7, - 0xD8, 0xDB, 0x86, 0x5E, 0xF4, 0xFE, 0xC2, 0x05, - 0x86, 0xDF, 0x3D, 0xD9, 0x02, 0xA0, 0x5B, 0x26, - 0x35, 0x9E, 0x26, 0x7C, 0x78, 0x8D, 0x7C, 0x88, - 0x03, 0x2E, 0x76, 0x6B, 0x11, 0x87, 0x40, 0x20, - 0x0F, 0x49, 0xCB, 0x4D, 0x6E, 0xDB, 0x15, 0x61, - 0xB2, 0xDE, 0x7D, 0xC6, 0x5E, 0xE6, 0x42, 0x3B - }, - { - 0xE9, 0xE9, 0x8D, 0x6D, 0xE0, 0xEF, 0x53, 0xFD, - 0x24, 0x27, 0x66, 0x1E, 0x1A, 0xCF, 0x10, 0x3D, - 0x4C, 0xAA, 0x4D, 0xC6, 0x10, 0x03, 0x62, 0x09, - 0xEC, 0x99, 0x74, 0x19, 0xC1, 0x20, 0x63, 0x1C, - 0x2C, 0x09, 0x4A, 0x8E, 0xE7, 0x82, 0x2D, 0x43, - 0xF8, 0x77, 0x80, 0x11, 0xC6, 0x03, 0x11, 0x1F, - 0x26, 0x28, 0xF8, 0x97, 0xC9, 0xB4, 0x31, 0x31, - 0x54, 0x77, 0x75, 0x6B, 0x03, 0x2E, 0x1F, 0x8D - }, - { - 0x52, 0xEB, 0x1E, 0x6C, 0x8A, 0x54, 0x49, 0x2C, - 0xA7, 0x60, 0xB5, 0x6C, 0xA8, 0x7D, 0xA3, 0xE1, - 0xA9, 0xA6, 0xD8, 0xA4, 0x21, 0x92, 0x19, 0x35, - 0x1D, 0x18, 0x71, 0x5A, 0x9A, 0x2C, 0x26, 0x70, - 0x8B, 0xB7, 0x12, 0xCD, 0xAC, 0x04, 0x34, 0x48, - 0x2E, 0x55, 0x1C, 0xB0, 0x9E, 0x3F, 0x16, 0x33, - 0x8D, 0xE2, 0x9B, 0xE2, 0xC6, 0x67, 0x40, 0xC3, - 0x44, 0xDF, 0x54, 0x88, 0xC5, 0xC2, 0xBB, 0x26 - }, - { - 0x47, 0x3F, 0xA6, 0xC5, 0x1A, 0x48, 0x10, 0x5F, - 0x72, 0x1C, 0x5C, 0xB8, 0xDB, 0xA6, 0x1C, 0x64, - 0xA1, 0xE3, 0xDD, 0xCC, 0xC3, 0x25, 0x0E, 0x68, - 0x22, 0x62, 0xF2, 0x12, 0xC0, 0x1A, 0xB4, 0x87, - 0x4A, 0xFF, 0x68, 0x8F, 0xEA, 0x96, 0x37, 0x73, - 0x9E, 0x2A, 0x25, 0xD2, 0xEE, 0x88, 0xDB, 0xDC, - 0xC4, 0xF0, 0x4D, 0x01, 0x47, 0x9B, 0x30, 0x17, - 0x17, 0x53, 0x3A, 0x64, 0x32, 0xB8, 0x50, 0xCD - }, - { - 0x6B, 0x76, 0x60, 0xD4, 0x10, 0xEA, 0xE5, 0xF3, - 0x5A, 0xD0, 0xAE, 0x85, 0xE6, 0x3D, 0xA4, 0x53, - 0xEB, 0xB0, 0x57, 0xE4, 0x3F, 0x42, 0xE8, 0x42, - 0xCB, 0xF6, 0x25, 0x0D, 0xA6, 0x78, 0x66, 0xB4, - 0x24, 0x0D, 0x57, 0xC8, 0x3B, 0x77, 0x1B, 0x0F, - 0x70, 0x66, 0x3E, 0x17, 0xFB, 0xD9, 0x08, 0x7F, - 0x76, 0xB4, 0xCE, 0x6B, 0xCD, 0x0B, 0x50, 0x2E, - 0x33, 0x74, 0xB1, 0x50, 0x9B, 0xBA, 0x55, 0xA8 - }, - { - 0xA4, 0xD0, 0x8A, 0xCA, 0x7A, 0x9E, 0xA6, 0x43, - 0x99, 0x99, 0xEA, 0x21, 0xE4, 0xCF, 0xE9, 0x86, - 0x9B, 0xB9, 0x0E, 0x3A, 0x01, 0x48, 0x71, 0xAD, - 0x88, 0xED, 0x3A, 0x97, 0xAA, 0x89, 0x15, 0x95, - 0x1C, 0x3F, 0xD0, 0xB3, 0x93, 0x3A, 0x50, 0x85, - 0x88, 0x93, 0x8A, 0xF7, 0x54, 0x49, 0x44, 0xEF, - 0x43, 0xC4, 0x40, 0xAA, 0x8F, 0xF1, 0xE5, 0xA8, - 0x18, 0xA4, 0x66, 0x43, 0x5D, 0xE7, 0x0F, 0xA8 - }, - { - 0x85, 0xE0, 0xE9, 0xB5, 0x0D, 0x2D, 0xB0, 0x22, - 0xC2, 0x39, 0xD7, 0x23, 0x2A, 0xE4, 0x7C, 0x02, - 0x59, 0x22, 0xE4, 0xF0, 0x7E, 0x2A, 0xFC, 0x65, - 0x6C, 0xDC, 0x55, 0x53, 0xA2, 0x7D, 0x95, 0xBF, - 0xA5, 0x8A, 0x57, 0x4D, 0x4E, 0xC3, 0xA9, 0x73, - 0x28, 0x1A, 0x8F, 0x4E, 0x46, 0xA7, 0x1A, 0xB0, - 0x34, 0x1C, 0x25, 0x77, 0x28, 0x74, 0x63, 0xE2, - 0x51, 0x04, 0x4D, 0xB2, 0x39, 0x8D, 0x55, 0xE2 - }, - { - 0x81, 0xA0, 0xD0, 0x24, 0x42, 0x90, 0x51, 0x91, - 0x16, 0x33, 0x70, 0xAE, 0x29, 0xC7, 0xF8, 0x9C, - 0x0F, 0x48, 0xBC, 0x1A, 0x1E, 0xB2, 0x94, 0x70, - 0x47, 0xDA, 0x1C, 0x62, 0x2B, 0x86, 0x77, 0xE9, - 0xEA, 0x9B, 0xEC, 0xED, 0x55, 0xD3, 0x3A, 0xDB, - 0x15, 0x53, 0xBD, 0x58, 0x4A, 0xD2, 0xF8, 0x6A, - 0x62, 0x07, 0xE8, 0x4E, 0x40, 0xE4, 0x60, 0x7E, - 0x11, 0x65, 0x0E, 0xE2, 0x87, 0x9F, 0x4E, 0x0B - }, - { - 0x87, 0x79, 0x0D, 0xF6, 0xCF, 0x73, 0x94, 0x45, - 0x1B, 0xCC, 0x73, 0x0E, 0x53, 0xFC, 0x57, 0xBE, - 0x56, 0x45, 0x22, 0x77, 0x1E, 0x14, 0x43, 0x2A, - 0x80, 0xAB, 0x0B, 0x06, 0xB7, 0xB1, 0xD2, 0x09, - 0xAD, 0x69, 0x89, 0x95, 0x12, 0x53, 0x85, 0xDB, - 0x8B, 0x3C, 0x09, 0x59, 0xB8, 0xA5, 0x33, 0x9E, - 0xDA, 0x0A, 0xE6, 0x78, 0x59, 0xD8, 0x47, 0xF4, - 0x4C, 0x81, 0x59, 0x72, 0x72, 0xCB, 0xF1, 0x95 - }, - { - 0xCC, 0x06, 0x4E, 0xA8, 0x53, 0xDC, 0x01, 0x52, - 0xCC, 0x03, 0xFE, 0xB5, 0xFB, 0x5D, 0xE7, 0x8B, - 0x9B, 0x88, 0xE9, 0x61, 0x55, 0xD5, 0x35, 0x8B, - 0xCE, 0x84, 0xA5, 0x4C, 0x0E, 0x0C, 0x42, 0xFB, - 0xDA, 0x09, 0x2F, 0x22, 0xD0, 0x56, 0xDF, 0x99, - 0x93, 0x26, 0x2E, 0x2B, 0xA4, 0x4A, 0x5B, 0x2D, - 0x53, 0xC3, 0x75, 0x9D, 0x09, 0x45, 0xFE, 0xBA, - 0xA6, 0xFD, 0x51, 0xB8, 0xFF, 0x38, 0xD8, 0x39 - }, - { - 0x7E, 0x51, 0x7F, 0xC3, 0x83, 0xEE, 0x8C, 0x9F, - 0x0A, 0x01, 0x68, 0x1D, 0x39, 0xE7, 0x3B, 0xEB, - 0xA5, 0x96, 0x95, 0x95, 0xCE, 0x77, 0x92, 0x7F, - 0x91, 0x69, 0x1F, 0x33, 0xBB, 0x3E, 0x13, 0x07, - 0xEE, 0x03, 0x61, 0x6C, 0x27, 0xE6, 0x79, 0x51, - 0x86, 0xF6, 0x94, 0x0F, 0xED, 0xD9, 0xD5, 0xC7, - 0xF2, 0x1B, 0x6D, 0x2A, 0xAF, 0x70, 0x29, 0x9C, - 0xDD, 0x83, 0x51, 0x25, 0x05, 0x0A, 0x8B, 0x3C - }, - { - 0x84, 0x5F, 0xCF, 0xA6, 0x7F, 0x6E, 0x06, 0x55, - 0x10, 0xD2, 0x62, 0xF1, 0xDD, 0x69, 0x39, 0xEA, - 0x4C, 0x0A, 0x4A, 0x59, 0xC8, 0xEE, 0x39, 0x77, - 0xDB, 0x70, 0x05, 0xE1, 0xAE, 0xE4, 0x20, 0xBD, - 0x3F, 0x38, 0x26, 0xEC, 0xFE, 0x59, 0x01, 0x5B, - 0x4D, 0xFA, 0x0B, 0xD5, 0xBB, 0xF8, 0xD8, 0xA4, - 0x34, 0x48, 0x5D, 0xC1, 0x1C, 0xB9, 0xCC, 0x85, - 0x97, 0xCB, 0x8C, 0x95, 0x66, 0x11, 0x5F, 0x31 - }, - { - 0x17, 0xCF, 0x2C, 0x23, 0x21, 0x5B, 0xCD, 0xFC, - 0x24, 0x3D, 0x8A, 0x94, 0x5F, 0x3C, 0x5C, 0x25, - 0x1D, 0x27, 0x18, 0xA3, 0xF7, 0x5F, 0xED, 0x6F, - 0x33, 0x20, 0xBC, 0xC6, 0xFD, 0x92, 0x73, 0x86, - 0xD5, 0x6F, 0x87, 0x19, 0xCC, 0xA0, 0x2E, 0xC5, - 0xE9, 0x9C, 0xDA, 0xC4, 0xEA, 0x10, 0x95, 0xB4, - 0x65, 0xBA, 0x9A, 0x29, 0x8B, 0x1D, 0x23, 0x8E, - 0x38, 0xB3, 0xFA, 0x15, 0xE8, 0xB1, 0x4E, 0xE4 - }, - { - 0xD7, 0x89, 0xCE, 0xC7, 0xD7, 0x52, 0x0F, 0x10, - 0xE8, 0xB8, 0xB6, 0xC8, 0x40, 0x95, 0x89, 0xDF, - 0x57, 0xB8, 0x56, 0xB8, 0x24, 0x55, 0x68, 0xF6, - 0x4E, 0x2D, 0x21, 0x83, 0xE3, 0x59, 0xA7, 0x84, - 0xC8, 0xD2, 0x6C, 0xF9, 0xB7, 0x20, 0xF5, 0xDF, - 0x56, 0x7B, 0x01, 0xF3, 0xF4, 0x8D, 0xE6, 0x4D, - 0x4F, 0x0D, 0xB1, 0x56, 0xBE, 0x52, 0x5D, 0x7C, - 0x7A, 0x66, 0x5A, 0xAD, 0xC5, 0x91, 0xF0, 0xB6 - }, - { - 0xB5, 0xE2, 0x46, 0xA9, 0x02, 0x77, 0x10, 0xC0, - 0xB0, 0x55, 0xC7, 0x1F, 0x11, 0x67, 0xE0, 0xEE, - 0x36, 0xEB, 0xC4, 0x32, 0xCF, 0x5D, 0x14, 0x27, - 0x75, 0xA7, 0xAE, 0xCC, 0xCE, 0xA7, 0x83, 0x25, - 0xED, 0x8C, 0x12, 0xF5, 0x0F, 0xBE, 0x64, 0x8A, - 0xDD, 0xF0, 0x59, 0xB8, 0xC0, 0x2A, 0x61, 0x49, - 0x2F, 0x83, 0x57, 0xBE, 0xE1, 0x42, 0xE7, 0xF7, - 0xDE, 0x04, 0x33, 0x78, 0xDB, 0xCF, 0x2D, 0x33 - }, - { - 0xB5, 0x23, 0xFD, 0x77, 0xAB, 0x9E, 0xEE, 0x42, - 0x48, 0x72, 0xBC, 0x2E, 0x83, 0xFC, 0x0A, 0x77, - 0xFF, 0x8A, 0x90, 0xC9, 0xA0, 0xCE, 0x9E, 0x8C, - 0x87, 0x68, 0x0A, 0x0F, 0x62, 0x86, 0x33, 0x1F, - 0x15, 0xC9, 0x3A, 0x2A, 0xFE, 0xCF, 0x75, 0x66, - 0x65, 0x3F, 0x24, 0xD9, 0x30, 0xC3, 0x23, 0x19, - 0x2D, 0x30, 0x43, 0xB9, 0x05, 0x72, 0x1C, 0xBD, - 0xB6, 0x31, 0x11, 0xCA, 0x42, 0xF2, 0x8F, 0x4E - }, - { - 0x43, 0x59, 0xA4, 0x58, 0x76, 0xBF, 0x6A, 0xCC, - 0x0A, 0xEC, 0xE7, 0xB9, 0xB4, 0xB4, 0xA8, 0x38, - 0xB9, 0xDB, 0xA5, 0x77, 0x6A, 0x3B, 0x14, 0xDA, - 0x2F, 0xBA, 0x91, 0x02, 0xE7, 0x8B, 0xF6, 0x48, - 0xFF, 0xB4, 0xD8, 0x67, 0xBA, 0xE8, 0x5F, 0xD9, - 0xB7, 0x13, 0x12, 0xDC, 0x46, 0x02, 0xD0, 0xD4, - 0x9C, 0x90, 0x7B, 0xB9, 0x28, 0x9B, 0x22, 0x95, - 0x96, 0x1E, 0x54, 0x13, 0x81, 0x23, 0xF5, 0x4A - }, - { - 0xD3, 0xF2, 0xC8, 0xE7, 0x4F, 0x34, 0x3A, 0x4E, - 0x71, 0x90, 0xD4, 0x75, 0xCF, 0x9A, 0xF7, 0x54, - 0xEE, 0xD5, 0x57, 0x72, 0x62, 0xB3, 0x5B, 0xD9, - 0xA9, 0xC4, 0x2B, 0x58, 0xCE, 0x88, 0x26, 0x2E, - 0x31, 0x14, 0x91, 0x7F, 0xB9, 0xE6, 0x83, 0xC6, - 0x2D, 0x9F, 0x89, 0x47, 0xB5, 0x8A, 0x29, 0x4D, - 0xA5, 0x06, 0xFB, 0x86, 0xB3, 0xED, 0xF2, 0x5C, - 0xB9, 0xE2, 0xD2, 0xDF, 0x61, 0x1C, 0xD4, 0x48 - }, - { - 0x41, 0xB8, 0x90, 0xF8, 0xE8, 0x45, 0x0D, 0xAD, - 0xB6, 0x95, 0x9A, 0xCC, 0xBA, 0x19, 0x49, 0x17, - 0xE0, 0x2F, 0x30, 0x67, 0x82, 0x1D, 0x4E, 0x99, - 0x5A, 0x37, 0xAC, 0x18, 0xBA, 0x3E, 0x47, 0xC7, - 0x50, 0x6E, 0x7A, 0x3D, 0xD1, 0xE1, 0x12, 0xE6, - 0xEC, 0x41, 0xBE, 0xF5, 0x30, 0x85, 0x11, 0x20, - 0x89, 0x4A, 0x7B, 0x34, 0xB3, 0xDB, 0xCD, 0xAE, - 0x40, 0x73, 0x27, 0xF0, 0xC5, 0x73, 0x6E, 0xDF - }, - { - 0x19, 0xD7, 0x14, 0x4F, 0x0C, 0x85, 0x1E, 0xB8, - 0xB0, 0x53, 0xA3, 0xA4, 0x35, 0x86, 0x52, 0x6D, - 0xC5, 0xC7, 0x73, 0xE4, 0x97, 0x97, 0x51, 0x64, - 0xD1, 0x11, 0x51, 0x36, 0x43, 0x68, 0xDF, 0x24, - 0xBC, 0x44, 0xD5, 0x36, 0x07, 0x23, 0x04, 0xD7, - 0x06, 0x31, 0xA8, 0x40, 0xB6, 0x36, 0xB9, 0x66, - 0xFD, 0x02, 0x8F, 0x61, 0x06, 0x2B, 0xFC, 0x52, - 0x85, 0x67, 0x01, 0x53, 0xA6, 0x36, 0x3A, 0x0A - }, - { - 0xC2, 0x18, 0x4C, 0x1A, 0x81, 0xE9, 0x83, 0xBE, - 0x2C, 0x96, 0xE4, 0xCF, 0xD6, 0x5A, 0xFB, 0xDA, - 0x1A, 0xC6, 0xEF, 0x35, 0x26, 0x6E, 0xE4, 0xB3, - 0xAB, 0x1F, 0xB0, 0x3A, 0xBA, 0xDD, 0xFD, 0xD4, - 0x03, 0xFF, 0xFC, 0xAF, 0xB4, 0xAD, 0xE0, 0xE9, - 0x2D, 0xA3, 0x82, 0xDA, 0x8C, 0x40, 0x22, 0x2E, - 0x10, 0xE9, 0xFD, 0xE8, 0x56, 0xC5, 0x1B, 0xDA, - 0xCD, 0xE7, 0x41, 0xA6, 0x49, 0xF7, 0x33, 0x5D - }, - { - 0x48, 0x8C, 0x0D, 0x65, 0x2E, 0x42, 0xFD, 0x78, - 0xAB, 0x3A, 0x2D, 0xC2, 0x8C, 0xF3, 0xEB, 0x35, - 0xFC, 0xDD, 0xC8, 0xDE, 0xF7, 0xEA, 0xD4, 0x81, - 0x7B, 0xFF, 0xB6, 0x4C, 0x1A, 0xE0, 0xF2, 0x08, - 0xF7, 0x8C, 0xF4, 0x09, 0x76, 0xF7, 0xE2, 0xA2, - 0xCB, 0x2D, 0xD3, 0x0F, 0x1C, 0x99, 0x13, 0x02, - 0x08, 0xCE, 0xB6, 0x92, 0xC6, 0x68, 0x80, 0xD9, - 0x52, 0x8C, 0xD6, 0xD3, 0x8A, 0xD2, 0x9D, 0xB2 - }, - { - 0x51, 0x5B, 0x65, 0xBF, 0x65, 0x68, 0x83, 0x99, - 0x57, 0x5F, 0x0E, 0x06, 0x77, 0xBB, 0x6A, 0x91, - 0x9B, 0x66, 0x33, 0x55, 0x46, 0xD6, 0xCA, 0xE3, - 0x36, 0xF5, 0xC6, 0xFE, 0xAE, 0x5E, 0x2B, 0xF7, - 0x45, 0xE3, 0xA7, 0xB1, 0x3C, 0x32, 0x05, 0xDD, - 0x8B, 0x5B, 0x92, 0xCF, 0x05, 0x3B, 0xE9, 0x69, - 0xDF, 0x71, 0x20, 0xFC, 0xEF, 0x77, 0xE3, 0x89, - 0x5F, 0x56, 0x0F, 0xD2, 0x32, 0xFB, 0x89, 0x50 - }, - { - 0x3F, 0xDB, 0xC7, 0xD6, 0x9F, 0x4B, 0x53, 0xC2, - 0x25, 0x66, 0x3D, 0xA3, 0x0D, 0x80, 0xF7, 0x2E, - 0x54, 0x28, 0x10, 0x44, 0xA2, 0x2B, 0x98, 0x82, - 0xC6, 0x63, 0x8F, 0x55, 0x26, 0x83, 0x4B, 0xD3, - 0x16, 0x01, 0xCA, 0x5E, 0xB2, 0xCC, 0xA4, 0xF5, - 0xFF, 0xCF, 0x67, 0x5D, 0xCB, 0xCF, 0xCA, 0x60, - 0xC8, 0xA3, 0x61, 0x2D, 0x1A, 0xA9, 0xDA, 0xB6, - 0x93, 0xB2, 0x35, 0x60, 0x69, 0x60, 0x3A, 0x0E - }, - { - 0x4F, 0xF6, 0xC3, 0x1A, 0x8F, 0xC0, 0x01, 0xAC, - 0x3B, 0x7A, 0xE0, 0x20, 0xC5, 0xF7, 0xC4, 0x5E, - 0xFB, 0x62, 0x71, 0xA2, 0xD7, 0xCC, 0xAB, 0x87, - 0x13, 0xE5, 0x48, 0xB7, 0x29, 0xF0, 0xFF, 0xF9, - 0xC8, 0x2F, 0xD4, 0xDB, 0x5C, 0xF6, 0x56, 0x43, - 0xD4, 0x07, 0x6A, 0x3F, 0xB1, 0x7B, 0x3E, 0x89, - 0x3C, 0x30, 0x2D, 0xC7, 0x5B, 0x61, 0x22, 0xFF, - 0x86, 0x81, 0xD0, 0x37, 0x12, 0x0E, 0x27, 0x6A - }, - { - 0x43, 0xDF, 0xF2, 0x60, 0xDF, 0xEF, 0x1C, 0xB2, - 0xD6, 0x16, 0x00, 0xE2, 0x40, 0xAA, 0xD6, 0xB7, - 0x20, 0xE5, 0xF4, 0xF8, 0x30, 0x86, 0xE2, 0x6A, - 0x49, 0xA0, 0xCE, 0x3E, 0x0C, 0xA4, 0x4B, 0x9A, - 0x60, 0xFC, 0xF4, 0x6A, 0x8C, 0x3F, 0x1B, 0xB1, - 0xA6, 0xF5, 0x76, 0x2B, 0x66, 0x51, 0x3F, 0xE3, - 0xF7, 0xC5, 0xB0, 0xBC, 0x15, 0x0C, 0x08, 0x49, - 0x1A, 0xCB, 0xC4, 0x36, 0x1C, 0xAB, 0xCF, 0xDF - }, - { - 0xB4, 0xDE, 0xA9, 0x4C, 0x9D, 0x36, 0x75, 0xBE, - 0x05, 0x12, 0xEF, 0xDE, 0xA8, 0x16, 0x38, 0x70, - 0xFE, 0x34, 0x25, 0xDC, 0xD7, 0x61, 0xF3, 0x63, - 0xC4, 0x3A, 0x0C, 0xA5, 0x71, 0x6B, 0x76, 0x54, - 0x06, 0x63, 0xFB, 0x2B, 0xE4, 0x9E, 0x2D, 0xB1, - 0x06, 0x48, 0x5C, 0x9C, 0xDD, 0x3C, 0x16, 0x48, - 0x98, 0xA9, 0x54, 0xB5, 0x87, 0x48, 0xC4, 0x2F, - 0xEA, 0x16, 0xA4, 0x0F, 0xC4, 0x53, 0xD2, 0x10 - }, - { - 0xE5, 0x27, 0x7B, 0x6F, 0x93, 0xEA, 0x1D, 0xE3, - 0xE2, 0xD9, 0xFC, 0xD8, 0xC6, 0x79, 0x79, 0x3C, - 0x6C, 0xCB, 0x8A, 0x3B, 0xE2, 0x6E, 0x8E, 0x31, - 0x14, 0xF3, 0x5D, 0xA4, 0xF2, 0xAC, 0x01, 0x4F, - 0x55, 0xC2, 0xF1, 0x5E, 0x09, 0xE9, 0x4A, 0xA0, - 0x71, 0x29, 0x81, 0x67, 0xA2, 0xFB, 0x9B, 0xE3, - 0x11, 0x70, 0x1F, 0xFB, 0xA9, 0xD3, 0xEE, 0xFF, - 0x8F, 0xFC, 0x79, 0x93, 0xA3, 0xCE, 0xCE, 0x18 - }, - { - 0xF0, 0x95, 0xA7, 0xC6, 0xE2, 0xB9, 0x16, 0x64, - 0x73, 0x4F, 0x3E, 0x23, 0xF1, 0x8E, 0xB2, 0xBA, - 0x9B, 0x00, 0xE7, 0x1F, 0xBF, 0xCB, 0x99, 0x31, - 0xC0, 0xA6, 0x14, 0x79, 0x2A, 0x9D, 0x86, 0x75, - 0x62, 0x2A, 0x87, 0x4C, 0x1B, 0xF5, 0x24, 0x1A, - 0x2A, 0x87, 0x41, 0xED, 0x1C, 0x89, 0x3B, 0xDF, - 0xA8, 0xE2, 0x8C, 0x2E, 0x20, 0xBB, 0x1C, 0x58, - 0xEB, 0x4D, 0xE7, 0xD8, 0x01, 0x11, 0x6C, 0x78 - }, - { - 0xDF, 0xA1, 0xFD, 0x80, 0x3A, 0x1D, 0x4A, 0x3E, - 0x66, 0x1D, 0xF0, 0x1F, 0x49, 0x43, 0xEA, 0x66, - 0x26, 0x0A, 0x18, 0xFE, 0xCE, 0x13, 0x4D, 0x62, - 0xF9, 0x7D, 0xAC, 0xDB, 0x8B, 0x3B, 0xF9, 0xC8, - 0x00, 0xAF, 0xE5, 0x79, 0xCF, 0xD1, 0x3F, 0xC0, - 0x14, 0x8B, 0xDE, 0xFB, 0xFF, 0x4E, 0x76, 0x83, - 0x56, 0x1C, 0x06, 0xA6, 0xF7, 0x22, 0x5E, 0x47, - 0x81, 0x99, 0x3B, 0x4F, 0x4F, 0x2B, 0xCB, 0xFA - }, - { - 0x2B, 0x86, 0xCE, 0xB2, 0x70, 0xF6, 0x90, 0x8D, - 0x8B, 0x16, 0x00, 0x75, 0xEA, 0x7F, 0x57, 0x16, - 0x3A, 0xF5, 0xD5, 0xC6, 0xF8, 0xAA, 0xC5, 0x20, - 0x40, 0xCC, 0x68, 0x7C, 0x17, 0xAB, 0xF3, 0xC7, - 0x78, 0xC1, 0x39, 0x06, 0xE0, 0xE6, 0xF2, 0x9A, - 0x6A, 0xB1, 0x23, 0xDE, 0xEB, 0xCE, 0x39, 0x1F, - 0x90, 0x7D, 0x75, 0xD3, 0xA2, 0xCE, 0xFA, 0x0E, - 0xFC, 0xB8, 0x80, 0xA0, 0xE7, 0x0D, 0x71, 0x96 - }, - { - 0x32, 0x46, 0x6B, 0xCB, 0xDE, 0xD5, 0x38, 0xE5, - 0x68, 0x79, 0x54, 0x30, 0x35, 0x25, 0x36, 0xFE, - 0xB9, 0x19, 0xBF, 0x4D, 0x97, 0xCC, 0x44, 0xAB, - 0x1D, 0x80, 0x50, 0x40, 0xF4, 0xBC, 0x4C, 0x2E, - 0x79, 0x52, 0x72, 0x10, 0x18, 0x95, 0x8B, 0x4E, - 0xE7, 0x83, 0x03, 0x59, 0x0E, 0xF6, 0xAC, 0x45, - 0x0D, 0xF9, 0x2E, 0xC7, 0x7F, 0x47, 0x70, 0x54, - 0xBF, 0xF8, 0x67, 0xB8, 0x89, 0x71, 0xD4, 0x21 - }, - { - 0xEA, 0x64, 0xB0, 0x03, 0xA1, 0x35, 0x76, 0x61, - 0x21, 0xCF, 0xBC, 0xCB, 0xDC, 0x08, 0xDC, 0xA2, - 0x40, 0x29, 0x26, 0xBE, 0x78, 0xCE, 0xA3, 0xD0, - 0xA7, 0x25, 0x3D, 0x9E, 0xC9, 0xE6, 0x3B, 0x8A, - 0xCD, 0xD9, 0x94, 0x55, 0x99, 0x17, 0xE0, 0xE0, - 0x3B, 0x5E, 0x15, 0x5F, 0x94, 0x4D, 0x71, 0x98, - 0xD9, 0x92, 0x45, 0xA7, 0x94, 0xCE, 0x19, 0xC9, - 0xB4, 0xDF, 0x4D, 0xA4, 0xA3, 0x39, 0x93, 0x34 - }, - { - 0x05, 0xAD, 0x0F, 0x27, 0x1F, 0xAF, 0x7E, 0x36, - 0x13, 0x20, 0x51, 0x84, 0x52, 0x81, 0x3F, 0xF9, - 0xFB, 0x99, 0x76, 0xAC, 0x37, 0x80, 0x50, 0xB6, - 0xEE, 0xFB, 0x05, 0xF7, 0x86, 0x7B, 0x57, 0x7B, - 0x8F, 0x14, 0x47, 0x57, 0x94, 0xCF, 0xF6, 0x1B, - 0x2B, 0xC0, 0x62, 0xD3, 0x46, 0xA7, 0xC6, 0x5C, - 0x6E, 0x00, 0x67, 0xC6, 0x0A, 0x37, 0x4A, 0xF7, - 0x94, 0x0F, 0x10, 0xAA, 0x44, 0x9D, 0x5F, 0xB9 - }, - { - 0xB5, 0x45, 0x88, 0x02, 0x94, 0xAF, 0xA1, 0x53, - 0xF8, 0xB9, 0xF4, 0x9C, 0x73, 0xD9, 0x52, 0xB5, - 0xD1, 0x22, 0x8F, 0x1A, 0x1A, 0xB5, 0xEB, 0xCB, - 0x05, 0xFF, 0x79, 0xE5, 0x60, 0xC0, 0x30, 0xF7, - 0x50, 0x0F, 0xE2, 0x56, 0xA4, 0x0B, 0x6A, 0x0E, - 0x6C, 0xB3, 0xD4, 0x2A, 0xCD, 0x4B, 0x98, 0x59, - 0x5C, 0x5B, 0x51, 0xEA, 0xEC, 0x5A, 0xD6, 0x9C, - 0xD4, 0x0F, 0x1F, 0xC1, 0x6D, 0x2D, 0x5F, 0x50 - }, - { - 0xBB, 0xFB, 0x94, 0x77, 0xEC, 0x6A, 0x9F, 0x0C, - 0x25, 0x40, 0x5A, 0xCD, 0x8A, 0x30, 0xD5, 0xDD, - 0x7C, 0x73, 0x57, 0x1F, 0x1D, 0x1A, 0x6E, 0x8C, - 0xE7, 0x2F, 0x8B, 0x9C, 0x94, 0x1C, 0xF7, 0x79, - 0xB7, 0x64, 0x03, 0xAC, 0x7F, 0x04, 0x50, 0x05, - 0x25, 0x84, 0x39, 0x0A, 0x14, 0xEA, 0xA3, 0x7C, - 0x20, 0xB5, 0xBD, 0xB0, 0x38, 0x10, 0x54, 0xA9, - 0xA4, 0x95, 0x34, 0xF8, 0x14, 0x66, 0xBA, 0x9D - }, - { - 0xC8, 0x28, 0x7E, 0x93, 0x3D, 0x95, 0x04, 0xBF, - 0xFD, 0x7B, 0xE2, 0xAC, 0x02, 0x2B, 0x32, 0xF3, - 0xF4, 0x6D, 0x87, 0xA7, 0xA0, 0xE7, 0x9B, 0xB2, - 0xA1, 0xCB, 0xAA, 0xCC, 0x2E, 0x84, 0xCD, 0x70, - 0x84, 0x5D, 0x0D, 0x42, 0x78, 0x48, 0xA6, 0xD7, - 0x88, 0xD3, 0x96, 0x22, 0xE1, 0x0F, 0x43, 0x42, - 0x23, 0x7E, 0xEF, 0xA6, 0xD3, 0xC0, 0x12, 0xDA, - 0xE9, 0x6C, 0xC8, 0xA6, 0x50, 0xCC, 0x2E, 0x30 - }, - { - 0xC4, 0x59, 0x6F, 0xCB, 0x0A, 0x28, 0xD2, 0x4A, - 0xAD, 0x70, 0xCF, 0x18, 0x53, 0xEC, 0x29, 0xDA, - 0xC0, 0xFB, 0x20, 0x2D, 0x8E, 0xC1, 0x40, 0xDA, - 0x30, 0x00, 0x88, 0xBB, 0x85, 0xB9, 0x2C, 0x30, - 0x29, 0x19, 0x46, 0xAD, 0x30, 0x7C, 0x09, 0x6E, - 0x3B, 0x28, 0x66, 0x33, 0x5C, 0x93, 0x17, 0xAF, - 0xE2, 0x8C, 0xAD, 0xAB, 0x5D, 0x62, 0xC3, 0x54, - 0x32, 0x9C, 0x98, 0xD9, 0x93, 0xC5, 0xBE, 0x1C - }, - { - 0xE8, 0x8C, 0x38, 0xE6, 0x7E, 0x8D, 0x19, 0x83, - 0x58, 0x08, 0x85, 0x46, 0x70, 0x77, 0x9E, 0xCA, - 0x60, 0xBA, 0xD8, 0x54, 0xC5, 0x77, 0x87, 0x90, - 0xA0, 0x72, 0x54, 0xA3, 0x0A, 0x14, 0xAE, 0x82, - 0xB6, 0x1B, 0xB1, 0x69, 0x11, 0xFE, 0x57, 0x77, - 0x1D, 0x19, 0xE9, 0xB7, 0xF5, 0x02, 0x3C, 0x0D, - 0x4E, 0x8A, 0x8D, 0x37, 0x2E, 0x3D, 0x85, 0xE4, - 0x3B, 0x03, 0xE5, 0xE0, 0x0E, 0x6E, 0xBA, 0x4B - }, - { - 0x2D, 0x66, 0x3E, 0x03, 0xE6, 0xF3, 0x55, 0x2C, - 0xCD, 0xFB, 0xA4, 0x96, 0xA1, 0x4C, 0xC6, 0x22, - 0x4C, 0xEB, 0x1E, 0xB6, 0x1A, 0xA2, 0x65, 0xE6, - 0xA7, 0xD4, 0xA2, 0x6E, 0x54, 0x10, 0x61, 0x04, - 0xA9, 0x6E, 0x33, 0x09, 0x59, 0xF9, 0x71, 0x3B, - 0x34, 0x87, 0xC1, 0xB9, 0x49, 0x7C, 0xCF, 0x82, - 0x61, 0x1D, 0xBF, 0xA3, 0x4F, 0xF1, 0x1D, 0x31, - 0x33, 0xB5, 0xB5, 0xD1, 0xF1, 0xE4, 0xF8, 0xD0 - }, - { - 0x70, 0x7D, 0x6A, 0x58, 0x42, 0x1B, 0x8F, 0x7E, - 0x44, 0xFF, 0x1F, 0x83, 0x62, 0xBC, 0x70, 0x0F, - 0x71, 0xEF, 0x7C, 0x39, 0x35, 0xE0, 0x76, 0x4B, - 0xD1, 0x4D, 0x39, 0x0C, 0x1C, 0x72, 0x79, 0x2A, - 0xF9, 0xC2, 0xC0, 0x2F, 0xB7, 0x2A, 0x2B, 0x9D, - 0x9A, 0x07, 0x29, 0xCB, 0x3E, 0x99, 0x62, 0x6C, - 0xF0, 0x34, 0xDF, 0x54, 0xB5, 0x06, 0xB5, 0xB1, - 0x64, 0x64, 0xF4, 0x75, 0x86, 0x4F, 0x25, 0x90 - }, - { - 0x9D, 0x88, 0xF8, 0xBA, 0xA4, 0xEB, 0x0F, 0x9A, - 0xB2, 0x29, 0x2E, 0x49, 0x82, 0xAC, 0x80, 0x44, - 0x53, 0x58, 0x22, 0x7D, 0x7F, 0x9C, 0xE7, 0xA4, - 0xA6, 0x29, 0xF1, 0x80, 0xF7, 0x14, 0x1E, 0x08, - 0xFE, 0x63, 0x55, 0xC6, 0x45, 0x21, 0xA6, 0x9B, - 0xA2, 0xBF, 0xBD, 0x1C, 0x4A, 0x3E, 0xA0, 0x48, - 0xD0, 0xBC, 0x8A, 0xB3, 0x70, 0x1F, 0x30, 0xEA, - 0x83, 0xFB, 0xE0, 0x24, 0x74, 0xD8, 0x92, 0xBF - }, - { - 0x65, 0xEA, 0x4D, 0xB0, 0x4A, 0x75, 0x81, 0xC1, - 0x81, 0x94, 0xA8, 0x92, 0x1A, 0xFD, 0xFA, 0x4F, - 0x8D, 0x9A, 0xF6, 0x29, 0xDE, 0xD2, 0x77, 0x2C, - 0x65, 0x8E, 0x08, 0x48, 0x5F, 0x67, 0xAD, 0x2C, - 0xE2, 0x1A, 0x98, 0xCD, 0x29, 0x3F, 0xF2, 0x8D, - 0x4D, 0xFC, 0xDF, 0x65, 0x8C, 0xDC, 0x7A, 0xE6, - 0x70, 0x27, 0x84, 0x8E, 0x71, 0xCC, 0xC1, 0x15, - 0xA3, 0xFF, 0xBA, 0xC4, 0xFA, 0x61, 0xBB, 0x73 - }, - { - 0x0B, 0x4A, 0x68, 0x92, 0x9E, 0x7F, 0x15, 0xCA, - 0x91, 0xBB, 0x44, 0x39, 0xF2, 0x40, 0x37, 0x02, - 0x03, 0x4C, 0xD4, 0x74, 0x8E, 0x46, 0x92, 0x7A, - 0xBA, 0x95, 0xCB, 0xEF, 0x80, 0x04, 0x8B, 0x25, - 0xA6, 0x75, 0x97, 0x0F, 0xAC, 0x33, 0xC8, 0x74, - 0xAB, 0xD3, 0xD8, 0x3A, 0xA0, 0xF3, 0x7B, 0xE2, - 0x30, 0x83, 0x10, 0xE8, 0xDD, 0x79, 0x4F, 0x81, - 0x92, 0x93, 0x0E, 0xD5, 0x6E, 0x70, 0xA8, 0xE4 - }, - { - 0xC1, 0xC5, 0xD8, 0xAC, 0xFE, 0x3F, 0xDE, 0x67, - 0x4E, 0xDD, 0x36, 0x20, 0x15, 0x7A, 0x8B, 0x6B, - 0x4C, 0x8E, 0x67, 0xC6, 0xA7, 0xA9, 0x72, 0x67, - 0x41, 0xD9, 0xC3, 0x05, 0xE2, 0xA5, 0x2A, 0x87, - 0x97, 0xFD, 0xA0, 0xB2, 0xF1, 0x3A, 0xC7, 0x87, - 0x34, 0xDB, 0x2F, 0x4F, 0xC8, 0x3E, 0xF3, 0x24, - 0x14, 0xD9, 0x31, 0xEB, 0xAE, 0xAE, 0xCD, 0x82, - 0x6D, 0x7C, 0x2B, 0xE2, 0x03, 0xBD, 0xC2, 0xD1 - }, - { - 0x2D, 0xAD, 0xC8, 0xC9, 0xF7, 0x42, 0x5A, 0x01, - 0x14, 0x49, 0x12, 0x87, 0xBD, 0xC6, 0x8E, 0xAE, - 0x4F, 0xB6, 0x19, 0x4D, 0x1A, 0x10, 0x9D, 0xB9, - 0xB6, 0xE8, 0xA2, 0xAC, 0x94, 0xD4, 0xE4, 0x40, - 0x90, 0x99, 0x85, 0xC4, 0x29, 0x1F, 0xE8, 0x9F, - 0xD8, 0x28, 0x1F, 0x8F, 0xCE, 0xF6, 0xF6, 0xBC, - 0x32, 0x55, 0x0E, 0x53, 0xCB, 0x7A, 0x49, 0x42, - 0x89, 0x81, 0xE8, 0xD5, 0x3C, 0xF5, 0xA2, 0x12 - }, - { - 0xE5, 0x55, 0xF2, 0xA5, 0x8A, 0xCA, 0xC5, 0x50, - 0x3F, 0x9E, 0x2D, 0x97, 0xB2, 0x46, 0x87, 0x2B, - 0x4C, 0xA7, 0x8B, 0xD5, 0x6D, 0x47, 0xB7, 0x65, - 0xF0, 0x52, 0xAA, 0xB3, 0xDC, 0x77, 0xDB, 0xE9, - 0x93, 0x93, 0x6F, 0x22, 0x52, 0xF0, 0xAB, 0x2E, - 0x01, 0xFB, 0x08, 0x74, 0x72, 0xCC, 0xB5, 0xA1, - 0x21, 0xDD, 0xFF, 0xDE, 0x53, 0x1D, 0x3D, 0xC4, - 0x02, 0x2A, 0x7D, 0x19, 0x56, 0xCE, 0x0E, 0x20 - }, - { - 0x9B, 0x4E, 0xAE, 0x12, 0x95, 0x00, 0x0A, 0xEA, - 0x79, 0x83, 0xEC, 0x3B, 0xCB, 0x48, 0x57, 0xCC, - 0x71, 0x25, 0xFD, 0x73, 0x06, 0x78, 0x7C, 0x63, - 0x13, 0x24, 0x73, 0xCF, 0xE8, 0xF4, 0xEB, 0x45, - 0x31, 0x8A, 0x60, 0xDA, 0xAD, 0x64, 0x6D, 0x63, - 0xA2, 0x7C, 0x4B, 0x9D, 0x1F, 0x50, 0x73, 0x70, - 0x0A, 0x30, 0x57, 0xDE, 0x22, 0xA7, 0xFD, 0xF0, - 0x9A, 0x87, 0xAA, 0xC6, 0x6E, 0xBE, 0x47, 0x58 - }, - { - 0x96, 0x64, 0xAC, 0xC2, 0xDC, 0x72, 0x98, 0xB9, - 0x86, 0x8D, 0xB4, 0x95, 0xEE, 0xBC, 0x6B, 0x59, - 0x65, 0x7D, 0x13, 0x9A, 0x6A, 0xF0, 0x60, 0xA7, - 0x2F, 0xB6, 0x91, 0x24, 0xBD, 0xD3, 0xA6, 0x59, - 0x18, 0x88, 0xF0, 0x35, 0x4F, 0x70, 0x2B, 0x1B, - 0x88, 0x86, 0x84, 0x41, 0x10, 0x58, 0xA3, 0x75, - 0x9F, 0x7F, 0xD3, 0x7F, 0x06, 0xEA, 0xFB, 0x3B, - 0x58, 0xEC, 0xF2, 0x6F, 0x45, 0x53, 0xBE, 0x27 - }, - { - 0xFC, 0x16, 0xE0, 0x92, 0x5A, 0x35, 0xAA, 0xD4, - 0x7A, 0xD6, 0x95, 0x54, 0xB2, 0x57, 0x96, 0xFC, - 0xF9, 0x26, 0x0C, 0xB5, 0x0E, 0x6C, 0xC3, 0x74, - 0x75, 0x35, 0x55, 0x9E, 0x99, 0xC8, 0x58, 0x81, - 0xC7, 0x58, 0x89, 0xAC, 0x79, 0x3A, 0xB7, 0x8B, - 0x88, 0xB0, 0x5F, 0xB1, 0x60, 0x89, 0x56, 0x55, - 0xE4, 0xD6, 0x63, 0xA2, 0xA0, 0x9B, 0xA9, 0xFA, - 0x61, 0x4A, 0x10, 0xC2, 0x29, 0x47, 0x21, 0x0D - }, - { - 0x22, 0x5E, 0x73, 0x41, 0xF8, 0x57, 0x52, 0x4F, - 0x78, 0x90, 0x37, 0x6C, 0x50, 0xE6, 0x35, 0x4B, - 0x16, 0xC1, 0xCD, 0xFB, 0xF5, 0x8F, 0xE5, 0xF3, - 0xA4, 0x03, 0x94, 0x93, 0xB5, 0xDD, 0x40, 0x8D, - 0x79, 0xD4, 0x8C, 0x56, 0xE1, 0xF8, 0x9B, 0x68, - 0x7F, 0xBE, 0x33, 0x62, 0xA7, 0x7F, 0xA7, 0x5A, - 0x54, 0x37, 0x4B, 0x7A, 0x48, 0x5E, 0x91, 0xB1, - 0x89, 0xAF, 0x2E, 0x2F, 0x74, 0x9E, 0x2A, 0xDB - }, - { - 0xA0, 0x7A, 0x4C, 0x02, 0x3A, 0xC7, 0x04, 0xCE, - 0x7C, 0x09, 0xDD, 0x6C, 0x92, 0xC6, 0xF1, 0x84, - 0xF5, 0x3E, 0x8D, 0xD9, 0x6F, 0xE3, 0xBE, 0x9E, - 0x93, 0xC3, 0x9C, 0x53, 0x44, 0x85, 0xB6, 0x4B, - 0x39, 0xD5, 0xBE, 0x7F, 0x7B, 0x71, 0x70, 0x60, - 0x4D, 0xE7, 0x7C, 0xE5, 0xA4, 0x37, 0xA9, 0x8E, - 0x71, 0x2C, 0xC4, 0x4F, 0x19, 0xE2, 0x1D, 0x41, - 0xF0, 0xE6, 0xE3, 0xEC, 0x1E, 0x00, 0xAC, 0x55 - }, - { - 0x62, 0x85, 0x84, 0x63, 0x58, 0x2D, 0x22, 0xE6, - 0x8E, 0x52, 0x27, 0xBF, 0xBA, 0xB5, 0x40, 0x04, - 0x8F, 0x65, 0xED, 0xD6, 0xA6, 0x75, 0x5F, 0x6F, - 0xAB, 0x53, 0xC0, 0x25, 0xB6, 0x63, 0xCA, 0x37, - 0x7A, 0x0E, 0xD5, 0xEF, 0xD6, 0xAF, 0x16, 0x6C, - 0xA5, 0x5A, 0x9C, 0x73, 0x3F, 0xCA, 0x80, 0x5A, - 0xC4, 0xE4, 0x09, 0xCA, 0x56, 0x17, 0x7A, 0xA7, - 0x49, 0x40, 0xDB, 0x9F, 0x40, 0xC3, 0xB9, 0xFF - }, - { - 0xA1, 0xAC, 0x53, 0x9D, 0x1A, 0xBB, 0xC2, 0xB0, - 0x96, 0xFF, 0xAB, 0x81, 0x3B, 0x64, 0x45, 0x7F, - 0xE6, 0xEB, 0x3B, 0x50, 0xFC, 0xD8, 0x89, 0x53, - 0xD0, 0xCD, 0x9F, 0x65, 0x02, 0xF6, 0x89, 0x62, - 0x0A, 0xD4, 0x42, 0xB5, 0x51, 0x70, 0x90, 0xB5, - 0x0C, 0xFF, 0xB9, 0x58, 0x86, 0x6D, 0x7C, 0x16, - 0x1D, 0x8A, 0x7D, 0x75, 0x60, 0xC8, 0x93, 0xE1, - 0xDE, 0xF6, 0xAE, 0xC4, 0x37, 0xAD, 0x6D, 0x06 - }, - { - 0xB5, 0x86, 0xB7, 0x5D, 0xA7, 0x0F, 0x6C, 0xC0, - 0x62, 0x7E, 0xF3, 0xCF, 0x12, 0x37, 0xC9, 0x4B, - 0x12, 0xD0, 0xF7, 0x4D, 0xCB, 0xA2, 0x6A, 0x9E, - 0x7C, 0x7B, 0xC6, 0xC2, 0x1A, 0x33, 0x53, 0x37, - 0xBF, 0x9F, 0x5B, 0x83, 0x0C, 0x63, 0x24, 0xAF, - 0xA6, 0xEF, 0x64, 0x9E, 0x95, 0xAF, 0x87, 0x90, - 0x87, 0x52, 0x34, 0xC6, 0xE6, 0x61, 0xD3, 0xF5, - 0xE9, 0x8C, 0xA0, 0x12, 0xAE, 0x81, 0x48, 0x8A - }, - { - 0x56, 0x68, 0xA2, 0x98, 0x21, 0x37, 0xCB, 0xC6, - 0x22, 0xEF, 0x8D, 0x06, 0xCF, 0x4E, 0x86, 0x16, - 0x8C, 0xDD, 0x4A, 0x89, 0x9C, 0xD4, 0x46, 0x2A, - 0xF6, 0xC3, 0xD4, 0x15, 0x42, 0x61, 0x56, 0xA5, - 0xD8, 0xDD, 0x67, 0xC9, 0x60, 0x4F, 0x31, 0xB5, - 0x7D, 0x6C, 0x9D, 0x59, 0x72, 0x50, 0x45, 0x7E, - 0x4A, 0xB5, 0x2A, 0x58, 0x11, 0x55, 0x42, 0xAC, - 0xF2, 0x7F, 0x92, 0x59, 0x30, 0xF6, 0xA1, 0x12 - }, - { - 0xF2, 0xB1, 0xBD, 0x16, 0xD8, 0x8E, 0x37, 0xF3, - 0xA5, 0x18, 0xD1, 0x93, 0xED, 0x06, 0x1A, 0x1D, - 0xF7, 0xB4, 0x43, 0xA1, 0x8C, 0xE9, 0xF8, 0x44, - 0x45, 0xEF, 0x86, 0xEF, 0xFB, 0xDF, 0xF1, 0x60, - 0x55, 0x02, 0x3C, 0xD4, 0xE7, 0x8D, 0x03, 0x4D, - 0xE4, 0x03, 0x2A, 0x77, 0xDD, 0xC1, 0xD3, 0x43, - 0x52, 0xFE, 0x61, 0x7F, 0x82, 0x56, 0x24, 0x45, - 0x9B, 0xC3, 0x26, 0x9F, 0x70, 0x4F, 0x34, 0x5B - }, - { - 0xF0, 0x85, 0xF3, 0xD8, 0xBD, 0x13, 0x8E, 0x05, - 0x69, 0x24, 0x3F, 0x74, 0x52, 0x3E, 0x87, 0xFF, - 0x37, 0x6F, 0x04, 0xEA, 0xBD, 0x5A, 0x2F, 0x6E, - 0x53, 0xDF, 0x38, 0x99, 0x00, 0x0E, 0x2E, 0x94, - 0xAF, 0x0D, 0x2B, 0xC7, 0x1C, 0x3F, 0x71, 0x10, - 0x25, 0xC5, 0x38, 0xA6, 0xC8, 0xB1, 0x0B, 0x09, - 0x04, 0xDF, 0xC3, 0x46, 0xAD, 0xAD, 0x7E, 0xF3, - 0x6B, 0x1A, 0xE8, 0x8A, 0x6C, 0xFE, 0xAB, 0xBD - }, - { - 0x82, 0x91, 0xA4, 0xAF, 0xD2, 0xE4, 0xB7, 0x16, - 0x61, 0x77, 0x3A, 0x46, 0xB3, 0xD4, 0x45, 0x5A, - 0x8D, 0x33, 0xA7, 0x26, 0xD9, 0xD3, 0x87, 0x30, - 0x83, 0xAB, 0x33, 0x70, 0x20, 0xC2, 0x7B, 0x4D, - 0xD6, 0x43, 0xE2, 0x8C, 0x2F, 0xE4, 0x7A, 0xB2, - 0xFB, 0xF5, 0xD1, 0x40, 0x81, 0xA3, 0xFC, 0x1C, - 0x83, 0x9B, 0x12, 0xEA, 0x31, 0xD1, 0x3C, 0xF4, - 0x9E, 0xEE, 0x97, 0xEF, 0x2E, 0xD7, 0xFA, 0x3E - }, - { - 0xB1, 0x26, 0xAE, 0x46, 0xA7, 0xA4, 0x59, 0x5E, - 0x31, 0x60, 0x7E, 0xF8, 0x07, 0xA5, 0x60, 0x1F, - 0x4E, 0xCD, 0x9E, 0x7D, 0x66, 0xC8, 0x2D, 0xAE, - 0xB9, 0x71, 0x5F, 0x8D, 0xA1, 0xC1, 0x7D, 0x7D, - 0x71, 0xC3, 0xE6, 0x82, 0x50, 0xC9, 0xDC, 0x01, - 0xAC, 0x40, 0xA3, 0x6D, 0x2E, 0x63, 0x8B, 0xEF, - 0x3D, 0x7B, 0xC7, 0x0E, 0xA2, 0xD0, 0xE3, 0x31, - 0xE3, 0xD3, 0x3E, 0x17, 0x04, 0xEB, 0xA9, 0x2D - }, - { - 0x63, 0xB1, 0x4D, 0x8E, 0xD2, 0x47, 0x9C, 0xAA, - 0x17, 0xC3, 0xE4, 0xCF, 0x20, 0x3B, 0x23, 0x3A, - 0x7E, 0x37, 0x3E, 0xDB, 0x0C, 0x2F, 0x19, 0x71, - 0x29, 0xA9, 0xA3, 0x6C, 0x5B, 0x3E, 0x1F, 0x38, - 0x38, 0xF2, 0xE8, 0x2A, 0xC2, 0xC2, 0xAD, 0x9D, - 0x52, 0xB3, 0x35, 0x79, 0x0B, 0xFF, 0x57, 0x73, - 0x04, 0xA3, 0x78, 0xE3, 0x8E, 0xB6, 0xBB, 0x41, - 0x62, 0x03, 0x0C, 0xE2, 0xA8, 0xBA, 0x29, 0x3C - }, - { - 0x34, 0x42, 0x2A, 0x32, 0x29, 0x66, 0x99, 0x28, - 0xC4, 0x90, 0xF5, 0x7B, 0x8E, 0x76, 0x88, 0x52, - 0xE5, 0xB7, 0xC0, 0x0D, 0xCA, 0xD6, 0x0B, 0x01, - 0x2A, 0x5D, 0xB3, 0x9A, 0x2D, 0x59, 0x7C, 0x3D, - 0x0A, 0x63, 0xBE, 0x6A, 0x26, 0x3E, 0xA5, 0x36, - 0x08, 0xB7, 0x06, 0x92, 0xD7, 0x8E, 0x1B, 0x42, - 0x7E, 0xAC, 0xEC, 0x01, 0xF4, 0xBE, 0xE0, 0xBD, - 0xBB, 0x8F, 0x08, 0x81, 0x48, 0x8E, 0xFC, 0x28 - }, - { - 0xE2, 0x6B, 0x7E, 0xD6, 0xB9, 0x07, 0xB5, 0x4C, - 0xA2, 0x65, 0x67, 0xF1, 0x1E, 0xE5, 0xBB, 0x6D, - 0x73, 0x9A, 0x00, 0x08, 0xA5, 0x34, 0x37, 0xAD, - 0x75, 0x90, 0xA3, 0x13, 0x4C, 0xEB, 0x95, 0x19, - 0x6E, 0x49, 0xB3, 0x44, 0x3F, 0x32, 0x49, 0x22, - 0x51, 0x75, 0x23, 0xC0, 0xCD, 0x5A, 0x00, 0xD7, - 0x7E, 0x4C, 0x4D, 0xE7, 0xA0, 0xDE, 0x96, 0x8A, - 0x84, 0xFB, 0x1B, 0x3B, 0xE7, 0xB3, 0xB9, 0x63 - }, - { - 0x26, 0x01, 0x97, 0xCA, 0xFB, 0xF4, 0x56, 0xB4, - 0x11, 0xFA, 0x26, 0xD3, 0x83, 0xD6, 0x4D, 0x61, - 0xE8, 0x1E, 0x5E, 0x52, 0xF8, 0x4C, 0xD9, 0xD5, - 0x73, 0x86, 0xC7, 0x76, 0x23, 0x0C, 0x65, 0xA2, - 0x68, 0x1C, 0xD2, 0xFD, 0xFD, 0x28, 0x67, 0x9F, - 0x67, 0xFE, 0x1B, 0xD7, 0x46, 0x9C, 0xF7, 0x26, - 0x95, 0x85, 0xFC, 0xCB, 0xAE, 0xCC, 0x22, 0xF5, - 0x03, 0xD6, 0xE3, 0xFC, 0x39, 0x30, 0x14, 0x36 - }, - { - 0xCB, 0xD5, 0xAB, 0xE3, 0x7B, 0xCC, 0x4F, 0x9A, - 0x12, 0x70, 0xAD, 0xD0, 0xA5, 0x27, 0x0F, 0x42, - 0x83, 0x9C, 0x7D, 0x24, 0x93, 0x20, 0xD1, 0xF1, - 0xD8, 0x85, 0x53, 0xD0, 0x5F, 0xAF, 0x9A, 0x26, - 0x79, 0xF4, 0x9B, 0x49, 0xC9, 0xE2, 0x0C, 0x1C, - 0x85, 0xC6, 0x29, 0xAA, 0x0F, 0x09, 0x0C, 0xAE, - 0x8F, 0x6E, 0x32, 0xC6, 0xCA, 0xD7, 0x17, 0x21, - 0xFD, 0x06, 0x23, 0xE4, 0xED, 0x25, 0xB2, 0x56 - }, - { - 0x78, 0x0E, 0x31, 0x4F, 0xD6, 0x97, 0xD2, 0xA9, - 0x7D, 0x22, 0x1A, 0x22, 0xC3, 0x90, 0x11, 0xE2, - 0x50, 0x69, 0x16, 0x3C, 0xD0, 0x8F, 0x00, 0x70, - 0xD0, 0x67, 0xE8, 0xCD, 0xB0, 0xBC, 0x86, 0x73, - 0xFD, 0xB0, 0xEC, 0x4F, 0x46, 0xE3, 0x1D, 0x74, - 0x8C, 0xD3, 0xBB, 0x3D, 0x61, 0xB9, 0x01, 0x0A, - 0x66, 0x12, 0xF3, 0x41, 0xD4, 0x71, 0xD9, 0xC5, - 0xA2, 0xDE, 0x6B, 0x6D, 0xD5, 0x38, 0xA6, 0xB5 - }, - { - 0x40, 0x8F, 0x16, 0xCE, 0x86, 0xF8, 0x01, 0xD0, - 0x8B, 0xD0, 0x51, 0x36, 0x4B, 0x3E, 0xCD, 0x9A, - 0x39, 0x45, 0x71, 0x58, 0x88, 0xDF, 0x46, 0x63, - 0x21, 0x9A, 0x19, 0x0B, 0x35, 0x04, 0xE4, 0x61, - 0x8E, 0x7B, 0xF5, 0x51, 0x71, 0x17, 0x8B, 0x04, - 0x00, 0xFB, 0xEB, 0xFA, 0xA0, 0x1F, 0x6E, 0xEA, - 0xB5, 0x4F, 0xF5, 0xE3, 0x1E, 0x6D, 0x7A, 0x55, - 0xB8, 0x4A, 0xDB, 0x9E, 0x03, 0xDF, 0x48, 0x36 - }, - { - 0x0B, 0xF9, 0x88, 0x69, 0xEC, 0x05, 0x80, 0x19, - 0x9C, 0xA3, 0x70, 0x8E, 0xC9, 0xC4, 0x2C, 0x37, - 0x6C, 0x5C, 0x36, 0xE0, 0xFB, 0x74, 0x92, 0x42, - 0x57, 0x23, 0x98, 0xA0, 0xDA, 0x57, 0xF9, 0x8D, - 0x1C, 0x4C, 0xD2, 0x96, 0x3B, 0x37, 0xC3, 0xC6, - 0x5A, 0x10, 0xF1, 0x06, 0xB5, 0x6D, 0xCB, 0x96, - 0xDC, 0xDD, 0x32, 0x57, 0x96, 0x29, 0x7A, 0xDB, - 0xF6, 0xEE, 0x62, 0x70, 0xED, 0xD4, 0x59, 0x2A - }, - { - 0x05, 0x2C, 0x32, 0x98, 0x43, 0x87, 0xB1, 0x93, - 0x0D, 0x3A, 0x96, 0xBE, 0x72, 0x36, 0x85, 0x35, - 0x44, 0x4F, 0x13, 0x07, 0x57, 0xBF, 0x87, 0xE0, - 0x76, 0x2D, 0x8B, 0x1C, 0x4F, 0x65, 0x70, 0xF4, - 0xDC, 0x67, 0x4C, 0x4E, 0x6F, 0x5E, 0x21, 0xAB, - 0xD0, 0xB3, 0x5E, 0x1C, 0xA1, 0x9D, 0xB8, 0x40, - 0x68, 0x8D, 0x1B, 0x6E, 0x9E, 0xC9, 0x1F, 0x37, - 0x30, 0xE8, 0xB2, 0x88, 0x0E, 0xC2, 0xC3, 0xDF - }, - { - 0x4B, 0xB7, 0x14, 0x09, 0xC1, 0x5A, 0x0D, 0x39, - 0x32, 0xC5, 0x99, 0xEF, 0x0F, 0xF3, 0xEF, 0xF5, - 0xC7, 0x60, 0x2D, 0x70, 0x00, 0xCD, 0xA9, 0x74, - 0x08, 0x2C, 0x4A, 0x46, 0x82, 0x24, 0x9A, 0x19, - 0xD4, 0x3A, 0x5C, 0x14, 0xE0, 0xAE, 0xEF, 0x89, - 0x78, 0x21, 0x05, 0x63, 0x80, 0xAF, 0xF2, 0x75, - 0x20, 0x1D, 0x74, 0x59, 0x14, 0x84, 0x96, 0xEA, - 0xE9, 0x42, 0x0E, 0x71, 0x82, 0x88, 0xB4, 0x14 - }, - { - 0x47, 0x95, 0xB2, 0x51, 0xCC, 0x7B, 0x35, 0xE6, - 0x96, 0x92, 0xDB, 0x7F, 0xB4, 0x0E, 0xFD, 0x34, - 0xF2, 0x94, 0xF5, 0x1A, 0xEC, 0x15, 0xD6, 0xC8, - 0x67, 0x3E, 0x59, 0xF2, 0x04, 0xBE, 0xCF, 0x4C, - 0xF9, 0xDF, 0x84, 0x95, 0x23, 0xF1, 0xDB, 0x73, - 0xBE, 0x2A, 0x66, 0xC8, 0x39, 0xD8, 0x01, 0x97, - 0x4D, 0x43, 0x3B, 0x47, 0x80, 0x67, 0x01, 0xA1, - 0x63, 0xA7, 0x94, 0xB2, 0x6A, 0x84, 0x6B, 0x06 - }, - { - 0xDD, 0x50, 0xF9, 0x65, 0xB6, 0x0B, 0xAF, 0x16, - 0x8F, 0x5E, 0xA0, 0x5A, 0xC2, 0x0B, 0x8A, 0x78, - 0xF4, 0x47, 0x5C, 0x18, 0x61, 0x0B, 0x9D, 0x9F, - 0xC2, 0xB7, 0xC3, 0xAD, 0x5C, 0x6F, 0x97, 0xA4, - 0xCF, 0x5E, 0xA4, 0x8E, 0xE4, 0x0A, 0x3C, 0xA2, - 0x29, 0x3C, 0xC4, 0x21, 0x40, 0x82, 0xCF, 0x0F, - 0x8E, 0xC8, 0x95, 0x55, 0x32, 0x69, 0xE1, 0x4D, - 0xA9, 0xBD, 0x1A, 0x19, 0x65, 0x62, 0xCA, 0x59 - }, - { - 0xE0, 0xB5, 0x4B, 0x61, 0x7F, 0x44, 0x92, 0x2C, - 0x7F, 0x61, 0xC6, 0xA5, 0x4C, 0x98, 0xC6, 0x1E, - 0x93, 0x2D, 0xED, 0x1F, 0xA9, 0x34, 0x02, 0x66, - 0xEE, 0xA2, 0x5F, 0x01, 0xE8, 0x18, 0x0D, 0x1D, - 0xDC, 0x6A, 0xD8, 0xDD, 0x6A, 0x0B, 0x8F, 0xAB, - 0x8C, 0x73, 0xAE, 0xBB, 0x97, 0x73, 0x17, 0x1B, - 0xBA, 0x04, 0xA7, 0x81, 0xB1, 0x13, 0x14, 0xD5, - 0xA3, 0x0A, 0x9D, 0x1C, 0x28, 0x12, 0xCA, 0x7C - }, - { - 0x2D, 0xC4, 0xAD, 0x06, 0x89, 0xA4, 0x46, 0x0B, - 0x5B, 0x39, 0x9E, 0x91, 0x1B, 0xDB, 0x41, 0x58, - 0x6A, 0xC8, 0xAD, 0x36, 0x7B, 0x7A, 0xA3, 0x9E, - 0x3E, 0xAE, 0xC8, 0x89, 0x9A, 0x2D, 0x3C, 0xE3, - 0x8E, 0x34, 0xAB, 0x46, 0x08, 0x23, 0x4D, 0x75, - 0xEB, 0x67, 0x37, 0xFE, 0x21, 0x58, 0x24, 0xC2, - 0xA9, 0x78, 0x83, 0x59, 0x6F, 0x6F, 0x18, 0xDD, - 0xEB, 0xBF, 0x16, 0x27, 0xDE, 0xD9, 0x1D, 0x84 - }, - { - 0xF5, 0x6A, 0x11, 0xCB, 0xBF, 0x8A, 0x99, 0x7E, - 0x14, 0x77, 0xEC, 0x76, 0xE5, 0x3C, 0x89, 0x4B, - 0x14, 0x8D, 0x69, 0x25, 0xA4, 0x33, 0x6F, 0x0C, - 0xB7, 0xAA, 0xB9, 0xD8, 0x02, 0xAC, 0x9B, 0x45, - 0x36, 0xF4, 0x80, 0x10, 0x1F, 0x3F, 0x9A, 0x77, - 0xEE, 0xCD, 0xCB, 0xAE, 0x7A, 0xA6, 0xEA, 0x44, - 0x7A, 0x85, 0xDA, 0x90, 0xB5, 0x01, 0xF7, 0xDB, - 0x2E, 0xF8, 0xDD, 0xF5, 0xDE, 0x17, 0x33, 0x63 - }, - { - 0x6E, 0x17, 0x1D, 0x19, 0x6D, 0x0F, 0xC8, 0x2F, - 0xB4, 0x73, 0xE2, 0x9D, 0xA8, 0xF4, 0x0F, 0x37, - 0xEE, 0x97, 0x41, 0xAC, 0x3E, 0xAF, 0x17, 0x5D, - 0xD4, 0x9F, 0xDB, 0x56, 0x53, 0x0D, 0xB5, 0x98, - 0x98, 0xBA, 0xF3, 0xCE, 0xE7, 0x2E, 0xEF, 0x5E, - 0x77, 0x27, 0x6C, 0xAD, 0xAB, 0xCD, 0x75, 0x2C, - 0xA3, 0xA1, 0xB8, 0x64, 0xC1, 0x0A, 0xD2, 0x8D, - 0x27, 0xEA, 0xAD, 0x86, 0xE3, 0xF2, 0x1D, 0x33 - }, - { - 0x95, 0x20, 0x12, 0x33, 0x0D, 0x92, 0xBB, 0x9C, - 0x18, 0x92, 0xF2, 0x5B, 0x7B, 0x5A, 0xA0, 0xFE, - 0xD3, 0xC0, 0x39, 0x8A, 0x17, 0x08, 0x50, 0x9A, - 0x66, 0x14, 0x74, 0xA3, 0xF5, 0xE5, 0x11, 0xD0, - 0x9F, 0x21, 0xC3, 0x00, 0x08, 0x00, 0x2F, 0x10, - 0x42, 0xD8, 0x3D, 0x2F, 0x7B, 0x11, 0x33, 0x6B, - 0x8C, 0x2F, 0xE1, 0xD9, 0x79, 0xC1, 0xE3, 0x86, - 0xE0, 0x20, 0x97, 0x48, 0x9B, 0x2D, 0xFC, 0xF5 - }, - { - 0x2D, 0xCE, 0x47, 0xC3, 0x3A, 0x7E, 0x7F, 0x21, - 0x5D, 0x34, 0xA5, 0x47, 0x1B, 0xCD, 0x11, 0x10, - 0x60, 0x6C, 0x77, 0x13, 0x8F, 0x19, 0xD4, 0x17, - 0x41, 0xED, 0x5D, 0x1B, 0x89, 0xE8, 0xF7, 0xC7, - 0x74, 0xEE, 0xC4, 0xBB, 0xC1, 0x02, 0x76, 0x6E, - 0xA1, 0x53, 0x2F, 0x2E, 0x43, 0x13, 0x4A, 0xD3, - 0x66, 0xBD, 0xCC, 0x27, 0xD1, 0xA0, 0xCC, 0x95, - 0x9E, 0x16, 0x48, 0x65, 0x9E, 0x44, 0xCB, 0xBE - }, - { - 0x7F, 0x06, 0x59, 0x59, 0x7E, 0x7A, 0xD1, 0x22, - 0xD1, 0xC9, 0xED, 0x91, 0x93, 0x0B, 0x07, 0xDE, - 0x40, 0xE2, 0x55, 0x20, 0x1A, 0x33, 0xEB, 0x2B, - 0x31, 0x81, 0x37, 0x6E, 0x36, 0x8D, 0xF7, 0x76, - 0x4C, 0x0C, 0x14, 0xBF, 0x79, 0x9F, 0x16, 0x1B, - 0x9B, 0x00, 0x79, 0x57, 0x8B, 0x47, 0x09, 0x71, - 0x3E, 0x24, 0xE4, 0x2F, 0xE7, 0xDD, 0x71, 0xB5, - 0x09, 0x43, 0xF4, 0x40, 0xE2, 0x3C, 0xD1, 0xBE - }, - { - 0x1E, 0x66, 0xF7, 0xB3, 0x58, 0x80, 0x5D, 0xDD, - 0xFF, 0xC5, 0x82, 0x68, 0x3E, 0x0B, 0xAD, 0x81, - 0x8C, 0x87, 0x34, 0x03, 0xD4, 0xBA, 0x15, 0x06, - 0xB9, 0x2F, 0xB3, 0x20, 0xCA, 0x8C, 0xF9, 0xCE, - 0xE8, 0x15, 0x47, 0x15, 0xD6, 0xDB, 0x6F, 0x04, - 0x09, 0x3D, 0x4B, 0x3F, 0xD8, 0xA6, 0xFC, 0x8E, - 0x7E, 0xDD, 0xEA, 0xF2, 0x79, 0x5B, 0x3D, 0x22, - 0xDE, 0x7C, 0x75, 0xEC, 0xFF, 0x6F, 0x92, 0xAF - }, - { - 0x1F, 0x60, 0xC1, 0x8D, 0xB1, 0x68, 0xD9, 0x0D, - 0x2B, 0x46, 0x60, 0xE7, 0x58, 0xA3, 0xCD, 0x28, - 0x02, 0x3D, 0x4C, 0x0B, 0x84, 0x8B, 0x5E, 0x33, - 0xEA, 0x5C, 0xC1, 0x56, 0x29, 0xFD, 0x35, 0x2E, - 0xAC, 0xB1, 0x4F, 0x05, 0xFD, 0xEC, 0x07, 0xAC, - 0x23, 0xDA, 0x92, 0x04, 0x74, 0x5F, 0xA9, 0x73, - 0xC3, 0x29, 0x55, 0x13, 0x5F, 0x8E, 0xC7, 0x41, - 0x0A, 0x1C, 0xB5, 0x3B, 0xC7, 0x58, 0x06, 0x84 - }, - { - 0xB9, 0xDF, 0x57, 0xB3, 0x45, 0xEE, 0x6F, 0x87, - 0x0E, 0xE0, 0xE6, 0x3C, 0x55, 0x8B, 0x81, 0xC1, - 0xBC, 0x38, 0x42, 0x97, 0x6F, 0xD3, 0xCF, 0xB1, - 0xB5, 0x3B, 0x76, 0x6B, 0xF4, 0x36, 0xD1, 0xD1, - 0x75, 0xF4, 0xD4, 0xC5, 0xF1, 0xBD, 0x8D, 0x7A, - 0xF6, 0x5B, 0x5D, 0x18, 0xA7, 0x2F, 0x95, 0x71, - 0xF2, 0x34, 0x70, 0x19, 0x32, 0xAF, 0xB7, 0xC3, - 0xC9, 0x4A, 0x8C, 0x8F, 0xA0, 0x23, 0xDB, 0x4F - }, - { - 0xD8, 0xC8, 0x24, 0x95, 0xA2, 0xB5, 0xF6, 0x64, - 0x51, 0xF8, 0xC5, 0xB2, 0xE8, 0xA1, 0x73, 0x33, - 0xC2, 0xBE, 0x32, 0x20, 0xCE, 0x06, 0xA8, 0x14, - 0xC2, 0xCE, 0xA9, 0x5C, 0xC8, 0x65, 0x92, 0xAA, - 0x02, 0x15, 0xBF, 0x29, 0x46, 0x14, 0xA3, 0x28, - 0xCF, 0x07, 0x22, 0x2B, 0x73, 0xF9, 0x3F, 0x24, - 0x2A, 0x94, 0x8B, 0xCA, 0xE9, 0x56, 0x5F, 0xC9, - 0x70, 0x57, 0xB5, 0x2E, 0x02, 0x80, 0xEB, 0x82 - }, - { - 0x81, 0x34, 0xCE, 0x66, 0xD9, 0x5C, 0x40, 0x88, - 0xA5, 0x66, 0xD4, 0xE4, 0x35, 0x99, 0x06, 0x9A, - 0xD0, 0x45, 0x53, 0xB0, 0xFE, 0xA3, 0xD7, 0x48, - 0x19, 0xA6, 0xFD, 0x76, 0x6F, 0x43, 0x67, 0x42, - 0xF6, 0xB6, 0xEC, 0xC8, 0x27, 0x93, 0x98, 0x60, - 0x9F, 0x60, 0xB4, 0xE4, 0xBB, 0x44, 0xFD, 0x72, - 0xCD, 0xFB, 0xFF, 0x18, 0xD8, 0x03, 0x8A, 0xA7, - 0x12, 0x30, 0x83, 0x8B, 0x12, 0x6B, 0xC3, 0x00 - }, - { - 0x3D, 0xA8, 0x9F, 0x5C, 0x52, 0xB0, 0x52, 0xE0, - 0x42, 0xE5, 0x11, 0x7B, 0x96, 0x80, 0x6E, 0xDB, - 0x1C, 0x55, 0x22, 0x7E, 0x85, 0x14, 0xB3, 0x9E, - 0x8B, 0x22, 0xBE, 0xA4, 0xC9, 0x53, 0x30, 0x80, - 0xA4, 0xD7, 0xA9, 0x24, 0x92, 0xB7, 0x51, 0x76, - 0x9B, 0x0E, 0x11, 0x9E, 0xF4, 0xDB, 0x2B, 0xB8, - 0x8D, 0x5C, 0x1E, 0x75, 0xB4, 0x03, 0x10, 0x74, - 0xD7, 0xF2, 0x1A, 0x78, 0x01, 0x4A, 0x1F, 0x96 - }, - { - 0x9B, 0xDC, 0xB4, 0x69, 0xC2, 0x66, 0x5D, 0xD8, - 0x46, 0x83, 0xE5, 0x81, 0x01, 0xFD, 0xAE, 0x5C, - 0x88, 0x29, 0x2A, 0x4E, 0x05, 0xC4, 0x00, 0xCA, - 0x08, 0x26, 0xDA, 0x79, 0x38, 0x2B, 0x8A, 0x28, - 0x26, 0xFF, 0x24, 0xFC, 0xD5, 0x56, 0xC9, 0xD5, - 0xB5, 0xAA, 0x89, 0x2F, 0x02, 0xB1, 0x67, 0x04, - 0x77, 0x27, 0x9B, 0xD7, 0x5F, 0x1B, 0x2B, 0x7B, - 0x67, 0x5E, 0xFA, 0xC3, 0x80, 0x60, 0x70, 0x36 - }, - { - 0x6C, 0x77, 0x85, 0x7B, 0x38, 0x53, 0x3E, 0x41, - 0x4A, 0xF7, 0x38, 0x7C, 0x98, 0x56, 0x8D, 0x71, - 0xC8, 0xF0, 0xE3, 0x5E, 0x22, 0xB0, 0x2E, 0x2A, - 0x1C, 0x0D, 0xC6, 0xD5, 0x7E, 0x37, 0xD8, 0x68, - 0x72, 0x5A, 0xD8, 0x23, 0x58, 0x6A, 0x0B, 0xEE, - 0xF3, 0x98, 0x89, 0xCC, 0x31, 0xF1, 0xF7, 0xFA, - 0xD0, 0x96, 0x0A, 0x12, 0x5E, 0x29, 0xDF, 0xEA, - 0x74, 0x55, 0x12, 0xD1, 0x79, 0xE5, 0xF5, 0x89 - }, - { - 0x88, 0xC9, 0x83, 0x3A, 0x6D, 0x44, 0xFC, 0x25, - 0xBB, 0x64, 0xF3, 0xE9, 0x8E, 0x83, 0x8F, 0xB4, - 0xFF, 0x56, 0x48, 0x96, 0xDC, 0xD3, 0x58, 0x3A, - 0x8B, 0x57, 0xC9, 0x46, 0x6E, 0x74, 0x0C, 0x62, - 0x8B, 0x2D, 0x26, 0xEA, 0x14, 0x7C, 0xB3, 0x11, - 0x10, 0xFB, 0xAD, 0xCF, 0x9D, 0x01, 0x08, 0xAC, - 0xCE, 0xBE, 0x04, 0x31, 0x7D, 0x19, 0xFC, 0x03, - 0x66, 0xDE, 0x0C, 0x28, 0xA1, 0xA4, 0x5E, 0x2A - }, - { - 0x0A, 0xAB, 0xB3, 0xA1, 0x78, 0x46, 0x4A, 0x01, - 0x47, 0x64, 0x5F, 0x05, 0x71, 0x2A, 0x0A, 0x15, - 0x55, 0xC5, 0xB9, 0xA3, 0xE9, 0x99, 0xAB, 0x25, - 0x5A, 0xCA, 0x35, 0xC5, 0x03, 0x81, 0xF4, 0x90, - 0x55, 0x1A, 0x40, 0x89, 0x31, 0xAA, 0x6B, 0xE9, - 0xA4, 0xEF, 0x49, 0x7A, 0x16, 0x5B, 0x36, 0x66, - 0x3B, 0x1E, 0x1F, 0x05, 0x13, 0x48, 0x02, 0xB1, - 0x78, 0xB7, 0xC7, 0x04, 0x68, 0xCB, 0x98, 0xE8 - }, - { - 0x58, 0x50, 0xD8, 0x93, 0x70, 0x6B, 0x3B, 0xC2, - 0xDB, 0xBA, 0x9C, 0xFA, 0xB0, 0x28, 0xBE, 0xD8, - 0x19, 0xA2, 0x83, 0x11, 0xD2, 0xD6, 0xF0, 0xCD, - 0x8E, 0x27, 0x2E, 0xE6, 0x77, 0xBC, 0x87, 0x8A, - 0x0C, 0xED, 0x6C, 0x0D, 0xEA, 0x9E, 0x5C, 0xC9, - 0x4B, 0x2B, 0x4F, 0x59, 0x1A, 0x40, 0xEC, 0x9F, - 0xB1, 0x82, 0x22, 0xD6, 0xDE, 0xAC, 0xE1, 0xF9, - 0xC0, 0x83, 0xDC, 0x05, 0xDE, 0x11, 0x7A, 0x53 - }, - { - 0xBE, 0xE6, 0x96, 0xA4, 0x76, 0x4F, 0x94, 0x25, - 0xD9, 0x1B, 0x14, 0x17, 0x38, 0x62, 0x5A, 0x04, - 0x47, 0xA8, 0x22, 0xBB, 0xA7, 0xA8, 0x47, 0x78, - 0xCC, 0x3A, 0x77, 0xA3, 0x86, 0xCB, 0x18, 0x24, - 0x87, 0xDB, 0x51, 0x3B, 0xB8, 0xF3, 0x6F, 0xC2, - 0xF7, 0xE6, 0xD2, 0x89, 0x6E, 0x44, 0x56, 0xA5, - 0x23, 0x46, 0xC4, 0x94, 0x8E, 0x3E, 0xC6, 0x34, - 0xCB, 0xF1, 0x8F, 0x39, 0xC4, 0x46, 0xCB, 0xAB - }, - { - 0x3D, 0x9F, 0x75, 0xD3, 0xE5, 0x0D, 0x9B, 0xA3, - 0xBC, 0xAC, 0x4A, 0x4E, 0x11, 0x6B, 0x9B, 0x30, - 0x8D, 0xC6, 0x45, 0x99, 0xA3, 0x86, 0x4A, 0x9D, - 0xAF, 0xD7, 0x5C, 0xB7, 0x1F, 0x2D, 0xE3, 0x10, - 0x9F, 0x79, 0x56, 0xA7, 0xD2, 0xDD, 0x37, 0x4F, - 0x84, 0x06, 0xD7, 0x7F, 0x79, 0x63, 0x11, 0xE3, - 0xD3, 0x00, 0x89, 0xE5, 0x4D, 0xD6, 0xCE, 0x8A, - 0xBB, 0x02, 0xA8, 0x5A, 0x85, 0xAE, 0x92, 0xE4 - }, - { - 0xEF, 0x39, 0x51, 0x47, 0x5A, 0x16, 0xDF, 0x64, - 0x98, 0x32, 0x24, 0x04, 0x65, 0x30, 0xDC, 0x7C, - 0xB0, 0x53, 0xD2, 0x93, 0x94, 0x75, 0x39, 0x11, - 0xC4, 0x94, 0x99, 0x50, 0xF2, 0x3E, 0x8A, 0x92, - 0xC7, 0x09, 0xF4, 0x63, 0x69, 0xB2, 0x3A, 0x0D, - 0x70, 0x3A, 0x6F, 0x36, 0x49, 0x0F, 0x75, 0xBE, - 0x1E, 0x3E, 0x81, 0x29, 0xA8, 0x29, 0xF3, 0xDC, - 0xD7, 0x2D, 0x0E, 0x55, 0x49, 0x7B, 0x81, 0x33 - }, - { - 0xD4, 0x19, 0x7D, 0x2A, 0x68, 0x5B, 0xCA, 0x6B, - 0xFB, 0xDD, 0x0E, 0x3D, 0x84, 0xC7, 0x48, 0x01, - 0x35, 0x48, 0xBC, 0x84, 0x9F, 0xE6, 0x49, 0xDA, - 0xE7, 0xC4, 0xA2, 0x77, 0xFC, 0xBD, 0x8F, 0x81, - 0x8A, 0x9E, 0xDF, 0xA6, 0xCA, 0x14, 0xD7, 0xFE, - 0xEA, 0x72, 0x6B, 0x23, 0xB4, 0xA3, 0x3A, 0xA8, - 0xA3, 0xF5, 0xA6, 0x61, 0x67, 0x21, 0x5C, 0x61, - 0x48, 0xC0, 0x6B, 0x94, 0xCD, 0x8B, 0xFE, 0x37 - }, - { - 0x7A, 0x24, 0x40, 0x33, 0x35, 0xB8, 0x64, 0x10, - 0xD8, 0xD6, 0x93, 0xF1, 0x63, 0xD6, 0x19, 0x8A, - 0x68, 0x0F, 0x7E, 0x3A, 0xC0, 0x25, 0xEC, 0x44, - 0x74, 0x24, 0x9B, 0x01, 0x16, 0x77, 0xFE, 0x1C, - 0x86, 0x6A, 0xAF, 0x45, 0x3D, 0xB0, 0xE8, 0xF6, - 0x54, 0x33, 0x51, 0x50, 0x86, 0x3A, 0xCE, 0x57, - 0x66, 0x50, 0x80, 0x31, 0x91, 0x27, 0x8E, 0x9D, - 0x4B, 0x54, 0x7A, 0x43, 0x4C, 0x56, 0x54, 0xE2 - }, - { - 0xAF, 0x07, 0xC6, 0x7D, 0x58, 0x74, 0x3A, 0xEB, - 0x18, 0x50, 0xEB, 0x53, 0xB2, 0xDA, 0x78, 0xEC, - 0xF7, 0x09, 0x58, 0x18, 0x32, 0x5B, 0xEB, 0x86, - 0x6F, 0xF3, 0x13, 0xE3, 0x94, 0xC0, 0x07, 0xE0, - 0xC0, 0xB5, 0xA1, 0xCD, 0x7A, 0xE6, 0xBB, 0x37, - 0xCD, 0x27, 0x81, 0xB5, 0x2D, 0x15, 0x4D, 0x18, - 0x86, 0x5D, 0x5E, 0x37, 0xDB, 0xAA, 0x5F, 0x96, - 0x73, 0x9B, 0xF7, 0x69, 0x59, 0x96, 0xAE, 0x30 - }, - { - 0x28, 0xB3, 0xC2, 0x60, 0xFA, 0x7F, 0x23, 0xB9, - 0xCC, 0xAD, 0xD6, 0x15, 0xA1, 0x14, 0x69, 0x49, - 0x8A, 0xDB, 0x18, 0xD7, 0xA9, 0xF6, 0x84, 0xFD, - 0xE4, 0x35, 0xC0, 0x65, 0x33, 0xF5, 0xF5, 0x08, - 0xB2, 0x9B, 0x5E, 0xCD, 0x0E, 0xCD, 0x57, 0x36, - 0x9F, 0x22, 0xF1, 0xC5, 0x4E, 0x61, 0xBE, 0x6C, - 0xD1, 0x04, 0xC8, 0xF7, 0xD3, 0xE1, 0x84, 0x7A, - 0xAD, 0x67, 0x07, 0x3A, 0x47, 0x86, 0xE1, 0xDB - }, - { - 0xD6, 0x43, 0x23, 0x33, 0x25, 0x23, 0x9E, 0x2E, - 0xBD, 0x41, 0x1F, 0x0E, 0x00, 0x23, 0x30, 0x56, - 0x2E, 0xB1, 0xBB, 0x08, 0xE6, 0x88, 0x24, 0xB7, - 0x1B, 0x98, 0x19, 0x9C, 0x76, 0xD5, 0x31, 0x58, - 0xD9, 0x1D, 0xDD, 0x6F, 0x4F, 0x82, 0x61, 0xEC, - 0x1D, 0x72, 0xFC, 0x77, 0xC2, 0xCC, 0x23, 0x7E, - 0xDA, 0x15, 0xF0, 0x25, 0x7C, 0xF0, 0x7B, 0x84, - 0xCF, 0x1F, 0xBD, 0x1D, 0xBA, 0xFA, 0x1D, 0xFC - }, - { - 0x3D, 0x7B, 0x44, 0xCC, 0x82, 0xEF, 0xCA, 0xFC, - 0xAB, 0xA6, 0xB1, 0x91, 0x05, 0x48, 0x95, 0x8C, - 0x18, 0x0A, 0x0E, 0x8D, 0x84, 0xBC, 0x66, 0x3E, - 0x8E, 0xF9, 0x53, 0x3B, 0xD8, 0x0C, 0x4B, 0xBA, - 0xAA, 0x25, 0x5B, 0x19, 0x81, 0xF7, 0x56, 0xEB, - 0x10, 0x79, 0xAD, 0x0F, 0x34, 0x71, 0xA1, 0xFC, - 0x9D, 0x7A, 0x43, 0x23, 0x39, 0x30, 0x3A, 0x57, - 0x81, 0xA3, 0x45, 0x35, 0x30, 0x9E, 0x5A, 0x24 - }, - { - 0xEB, 0x08, 0x12, 0xC9, 0x67, 0x06, 0x46, 0xD5, - 0x63, 0x19, 0x8B, 0x11, 0x7A, 0xAF, 0xC5, 0x6F, - 0xA1, 0xB6, 0x56, 0x0F, 0x88, 0xB5, 0x75, 0x4E, - 0xBF, 0xC3, 0x1B, 0x35, 0x52, 0x16, 0xD8, 0xD7, - 0x4D, 0x34, 0x1E, 0x35, 0xB2, 0x43, 0xBC, 0x93, - 0x8C, 0xF5, 0x46, 0xAF, 0x1F, 0x73, 0xC1, 0xB0, - 0x04, 0x55, 0xDC, 0x06, 0xB2, 0xC6, 0xC5, 0x35, - 0x27, 0x9E, 0x87, 0x67, 0x49, 0x8F, 0x14, 0xE6 - }, - { - 0x7B, 0xBA, 0x7D, 0x73, 0x04, 0x02, 0x1C, 0x75, - 0xB5, 0xD6, 0xCE, 0x66, 0xB4, 0xEF, 0xA5, 0x50, - 0x19, 0xD9, 0x42, 0xD2, 0x08, 0xAF, 0xAC, 0x82, - 0x11, 0xAA, 0x7E, 0x5E, 0x11, 0x1E, 0x27, 0x69, - 0x76, 0x70, 0xE4, 0xEC, 0x91, 0xBA, 0x30, 0x8E, - 0xBD, 0xFB, 0x19, 0x15, 0x4C, 0x3B, 0xAD, 0x05, - 0x26, 0xA6, 0x25, 0x41, 0xAE, 0x5D, 0x43, 0xD0, - 0xF5, 0x47, 0xB9, 0xD9, 0x8E, 0x07, 0x36, 0x60 - }, - { - 0xA8, 0xE2, 0xA9, 0x46, 0x8D, 0xA3, 0xE3, 0x54, - 0x3A, 0x23, 0xA5, 0x78, 0x78, 0x0E, 0x25, 0x62, - 0xC7, 0xCE, 0x57, 0xFD, 0x11, 0x20, 0xE1, 0xC0, - 0x24, 0xD7, 0xEA, 0x32, 0x90, 0x31, 0x70, 0x46, - 0x61, 0x6E, 0x14, 0xCD, 0x0F, 0x15, 0xA8, 0x6B, - 0x99, 0x39, 0x54, 0x9B, 0x14, 0x76, 0x11, 0xB6, - 0xA5, 0x5D, 0x85, 0xAB, 0xC2, 0x5F, 0x63, 0x95, - 0x46, 0xB8, 0x9D, 0xD2, 0x3D, 0x39, 0xA9, 0x85 - }, - { - 0xCE, 0x87, 0x4C, 0xD6, 0xE1, 0x95, 0x8B, 0x9D, - 0x7F, 0x11, 0xFF, 0x44, 0xAB, 0x08, 0x32, 0xE8, - 0x48, 0x70, 0x2C, 0x8F, 0x26, 0x65, 0x6B, 0xA1, - 0x0B, 0xF5, 0x72, 0x0A, 0x7C, 0xAA, 0x1F, 0x59, - 0x08, 0xC9, 0x9A, 0x96, 0x03, 0xA9, 0x8B, 0x41, - 0x6C, 0x57, 0x22, 0x8C, 0x81, 0x9C, 0xEA, 0xF8, - 0x27, 0x01, 0x3B, 0x2E, 0x6D, 0x6B, 0x2D, 0xAE, - 0x59, 0xDF, 0xF1, 0x04, 0xB9, 0x02, 0xC3, 0x1B - }, - { - 0x30, 0xFF, 0xFE, 0x37, 0x21, 0x8D, 0xB1, 0x94, - 0xB2, 0x32, 0x73, 0x49, 0x8F, 0x45, 0x44, 0xD3, - 0x84, 0x14, 0xBE, 0xE4, 0x1B, 0x17, 0x55, 0xA0, - 0xC6, 0xC2, 0xDB, 0xCB, 0x41, 0x19, 0x42, 0xD5, - 0xEC, 0xB9, 0xD4, 0x52, 0x3F, 0xB4, 0x79, 0x4B, - 0xA3, 0x6E, 0x57, 0x9A, 0xF2, 0xF8, 0xDD, 0x85, - 0x19, 0x99, 0x23, 0x31, 0x83, 0xFA, 0xB2, 0x7B, - 0x47, 0xAD, 0xD8, 0x7D, 0xF3, 0x59, 0x14, 0xBB - }, - { - 0xCE, 0xF4, 0x43, 0x1D, 0xCE, 0x9F, 0xF5, 0x5A, - 0x00, 0x30, 0x0E, 0xC8, 0x64, 0x9E, 0x27, 0x58, - 0x36, 0x18, 0x22, 0x43, 0x69, 0xF6, 0x0A, 0x5C, - 0x89, 0x6B, 0x2A, 0x31, 0x10, 0xB0, 0x32, 0xB8, - 0x7C, 0x9E, 0xE4, 0xF2, 0x6C, 0x5F, 0x0B, 0xDB, - 0x50, 0x3E, 0xA7, 0x44, 0x7A, 0x5D, 0xB3, 0xF7, - 0x07, 0xFE, 0x34, 0x10, 0xDA, 0xCD, 0xD7, 0x57, - 0x22, 0x19, 0xBD, 0xEA, 0x8E, 0x17, 0xDC, 0x04 - }, - { - 0x8F, 0xF0, 0xBC, 0xB7, 0x5F, 0x00, 0x61, 0xB5, - 0xF9, 0x09, 0x29, 0x8F, 0x56, 0x9E, 0x45, 0xC7, - 0x5E, 0xD2, 0xD6, 0x4A, 0x81, 0x89, 0xCE, 0xBD, - 0x4E, 0x02, 0x56, 0x6E, 0x1A, 0x1B, 0x8B, 0xE5, - 0x3A, 0x78, 0x32, 0x28, 0x55, 0x8E, 0x28, 0xB5, - 0xF8, 0x7C, 0xCC, 0x2F, 0x42, 0x8F, 0x7F, 0x87, - 0x97, 0x44, 0xB5, 0x25, 0xB2, 0x49, 0x62, 0xB3, - 0x60, 0x4B, 0x12, 0x0F, 0x06, 0x77, 0x9F, 0x2E - }, - { - 0x7F, 0x8D, 0xDF, 0xFB, 0x4D, 0xC1, 0x51, 0x91, - 0xDE, 0x3D, 0xDB, 0xE4, 0xA0, 0xF8, 0x8B, 0x7A, - 0xB0, 0x2D, 0x48, 0xE2, 0x5C, 0xFC, 0x1F, 0xE9, - 0x1D, 0xA5, 0x57, 0xE8, 0x85, 0xD0, 0x12, 0xB8, - 0xF6, 0x55, 0x26, 0xC5, 0xB7, 0xB1, 0x01, 0x3F, - 0xC8, 0x16, 0x58, 0x50, 0x43, 0xA3, 0x45, 0x60, - 0x5A, 0x39, 0xD8, 0xDA, 0xD7, 0x0D, 0x8A, 0x64, - 0x48, 0x51, 0x32, 0x50, 0xAA, 0xC4, 0xF3, 0xD5 - }, - { - 0xB1, 0xFE, 0x8C, 0x68, 0xAE, 0xF6, 0xB4, 0xD4, - 0xB2, 0x33, 0x54, 0xEB, 0x8C, 0x1D, 0x8F, 0x5A, - 0x56, 0xE3, 0x2E, 0x76, 0xB9, 0x6A, 0xC8, 0x44, - 0x3B, 0x2A, 0xB8, 0x35, 0xE4, 0xC8, 0xB6, 0x74, - 0xB3, 0x3E, 0x4C, 0x6C, 0x6D, 0xC1, 0x21, 0xD7, - 0xC2, 0xD3, 0x4B, 0x59, 0xB3, 0x7A, 0x56, 0x8A, - 0x1C, 0x98, 0xD5, 0x00, 0x32, 0x4E, 0x53, 0x08, - 0x87, 0x85, 0xB6, 0xB0, 0x80, 0x63, 0x47, 0xD1 - }, - { - 0x8E, 0x87, 0x34, 0xFC, 0xF9, 0x25, 0x9E, 0xE3, - 0x7F, 0xE9, 0xC6, 0xCD, 0xA2, 0x82, 0xC2, 0xD5, - 0xEB, 0x83, 0xD0, 0xCF, 0x43, 0x9C, 0x86, 0x19, - 0xD4, 0xB0, 0x42, 0xFF, 0x69, 0x96, 0x6B, 0x03, - 0x56, 0x5B, 0xE4, 0xDF, 0x96, 0x39, 0x3F, 0xE6, - 0xBF, 0x35, 0xAF, 0xA1, 0x6E, 0x02, 0x73, 0xB6, - 0xD3, 0x39, 0xC0, 0x09, 0x95, 0xBF, 0x6F, 0x60, - 0xA7, 0x14, 0xEF, 0x18, 0x0E, 0xBB, 0x93, 0x15 - }, - { - 0xAE, 0x15, 0x6D, 0x43, 0xA7, 0x2C, 0x04, 0x29, - 0x42, 0x59, 0x58, 0x78, 0xA7, 0x83, 0x07, 0x97, - 0x60, 0xF5, 0x21, 0xED, 0xB8, 0xB2, 0xC3, 0xD4, - 0x1A, 0x56, 0x6B, 0x7C, 0xF7, 0x4A, 0x4A, 0x08, - 0xEA, 0x0F, 0x11, 0x9D, 0x24, 0x0A, 0x62, 0xEC, - 0x73, 0xB9, 0x50, 0x97, 0x88, 0xFA, 0x3A, 0xED, - 0xF1, 0x20, 0xEE, 0x88, 0xCB, 0x95, 0x1B, 0x69, - 0x3F, 0x8F, 0x7C, 0xAF, 0x8C, 0xBA, 0x37, 0x7F - }, - { - 0x93, 0x30, 0xAA, 0xCA, 0x8C, 0x08, 0x84, 0x46, - 0x58, 0xC2, 0x95, 0x06, 0xB1, 0xC3, 0x42, 0x72, - 0xE2, 0xB3, 0xC7, 0xB4, 0xE7, 0x5E, 0x6F, 0xE9, - 0x9A, 0x01, 0x07, 0xEC, 0x5D, 0xA4, 0x53, 0x0F, - 0xB1, 0xC8, 0x8C, 0xAA, 0x66, 0xDD, 0x9C, 0x47, - 0x1E, 0x01, 0xCA, 0x21, 0xA1, 0x3A, 0x5D, 0x6F, - 0x82, 0x15, 0xDE, 0xD3, 0x14, 0x7E, 0x94, 0xDE, - 0x20, 0x88, 0x57, 0x1F, 0xD1, 0xBF, 0x23, 0xB6 - }, - { - 0xC1, 0x29, 0xF2, 0x2C, 0x50, 0xF5, 0x99, 0x72, - 0x32, 0xE2, 0xB9, 0xF9, 0x3D, 0xFA, 0xA0, 0x0A, - 0xD8, 0xA5, 0x34, 0x29, 0xF9, 0xD1, 0x5B, 0x98, - 0x42, 0xE3, 0xAE, 0x08, 0xD8, 0x49, 0xEB, 0xDD, - 0x45, 0x23, 0x8C, 0x85, 0xF9, 0x2C, 0x6F, 0x91, - 0x7E, 0x0F, 0x8F, 0x6F, 0x94, 0xE2, 0x34, 0xBE, - 0x07, 0x61, 0x68, 0xE0, 0xDF, 0x43, 0xD0, 0x28, - 0x45, 0x52, 0x79, 0xA6, 0xFF, 0x65, 0xDC, 0x84 - }, - { - 0x0E, 0x2B, 0x4B, 0xC2, 0xF6, 0xA7, 0x5B, 0xE4, - 0xB7, 0xC9, 0xD4, 0xB5, 0x3D, 0x10, 0x4D, 0xA0, - 0x65, 0x85, 0x8D, 0x38, 0x7B, 0x34, 0x0B, 0xC1, - 0x63, 0x4F, 0x3A, 0x83, 0x32, 0xD5, 0x4C, 0xAA, - 0x94, 0x30, 0x24, 0xB2, 0x13, 0xDC, 0x8D, 0x4F, - 0x21, 0x9E, 0xC8, 0xE1, 0xDE, 0xCA, 0xC7, 0xD5, - 0xC6, 0xAE, 0x69, 0xC9, 0xEF, 0xD8, 0x81, 0x49, - 0x36, 0x78, 0x38, 0x20, 0x5D, 0x0D, 0xC7, 0xC0 - }, - { - 0x83, 0xB5, 0x43, 0x85, 0x3B, 0x81, 0x42, 0xA8, - 0x3B, 0xEF, 0xF0, 0x73, 0x5F, 0x20, 0x18, 0x91, - 0xE7, 0xFF, 0xC6, 0x7D, 0xBD, 0xCD, 0x21, 0xA4, - 0x22, 0xBB, 0x33, 0x6D, 0xE3, 0x29, 0x72, 0xAE, - 0x03, 0x92, 0x64, 0x6F, 0x68, 0x27, 0xD8, 0x0C, - 0xDA, 0x65, 0x4F, 0xD3, 0xA0, 0x77, 0x4C, 0xD2, - 0xF9, 0x95, 0x51, 0x7C, 0xF0, 0x64, 0xC6, 0x17, - 0xF2, 0x1A, 0x54, 0x27, 0x5F, 0xE5, 0x0C, 0x8D - }, - { - 0x09, 0xBE, 0x15, 0xEB, 0x6A, 0x5C, 0x22, 0x6F, - 0x6D, 0x95, 0x08, 0xCB, 0xA4, 0xA2, 0x51, 0x9F, - 0xBA, 0x17, 0x2A, 0xF8, 0x37, 0x58, 0x27, 0xD7, - 0x54, 0xA7, 0xA1, 0xBC, 0x19, 0x25, 0xD1, 0x3F, - 0x5E, 0x63, 0x43, 0xF3, 0xE1, 0x4D, 0x08, 0xA0, - 0x6E, 0x8D, 0x37, 0xF8, 0xEC, 0x56, 0xFB, 0x43, - 0x8E, 0x62, 0x36, 0x66, 0xB6, 0xFB, 0x0E, 0x23, - 0xFB, 0x50, 0x47, 0x7D, 0x41, 0x1B, 0x0C, 0x3A - }, - { - 0xC3, 0x57, 0x97, 0xE9, 0x83, 0x2D, 0x3E, 0x23, - 0x23, 0x33, 0x5B, 0x8C, 0x19, 0xC5, 0xFA, 0x74, - 0x91, 0x60, 0x2D, 0xBF, 0x6B, 0xEA, 0x77, 0xFA, - 0xEE, 0xC9, 0x51, 0x0B, 0xC2, 0xE8, 0x91, 0xC8, - 0xC3, 0x46, 0x21, 0x99, 0xF6, 0x04, 0x18, 0xD2, - 0xE0, 0xAB, 0xFF, 0xE3, 0x1B, 0x61, 0x3B, 0xB9, - 0x80, 0xEA, 0x32, 0xB7, 0x6C, 0x82, 0x43, 0x8D, - 0x02, 0x5F, 0x67, 0x8C, 0xAF, 0x48, 0x24, 0xA4 - }, - { - 0xCF, 0xC0, 0x57, 0xFD, 0xA7, 0x8A, 0x50, 0x31, - 0x8F, 0x49, 0x78, 0xFF, 0xFF, 0xAF, 0x77, 0x17, - 0x98, 0xE1, 0x2C, 0x3E, 0xA8, 0xC7, 0x98, 0x19, - 0x5B, 0xC5, 0xB4, 0xE6, 0x89, 0x1E, 0x61, 0xAA, - 0x25, 0xF7, 0xAF, 0x4A, 0xA7, 0x28, 0x6A, 0xC8, - 0x50, 0x76, 0x62, 0xC9, 0x07, 0xED, 0x91, 0x3E, - 0xDA, 0x65, 0x8F, 0x63, 0xFC, 0x47, 0x99, 0x7C, - 0x59, 0xB8, 0x59, 0x70, 0xF8, 0x78, 0xCA, 0x18 - }, - { - 0xD8, 0xEB, 0xE0, 0xE6, 0x38, 0xFC, 0x53, 0x5B, - 0x52, 0xCB, 0x0A, 0xFC, 0xE0, 0xF8, 0x2D, 0xDE, - 0x28, 0x57, 0x01, 0xAF, 0xF3, 0x29, 0xA5, 0x4B, - 0xA0, 0x6D, 0xFD, 0x3D, 0x1B, 0x4B, 0x31, 0xF9, - 0xF4, 0xB2, 0x4D, 0x9D, 0x68, 0x36, 0xF1, 0x22, - 0x3D, 0x6D, 0xE6, 0x6B, 0xAE, 0x78, 0x88, 0xFE, - 0xBC, 0x20, 0x40, 0xCF, 0xE9, 0x30, 0xE6, 0x9C, - 0xED, 0x59, 0xDA, 0x6D, 0xA8, 0xA0, 0xA6, 0xA6 - }, - { - 0x16, 0xB8, 0xC5, 0x5C, 0xF2, 0xF1, 0x35, 0xA4, - 0x32, 0x59, 0x0D, 0x2D, 0x4C, 0xFA, 0x38, 0x59, - 0x2F, 0x59, 0x35, 0xF8, 0xE7, 0x1C, 0xE0, 0x8A, - 0x02, 0x06, 0xA0, 0xE5, 0xAB, 0xEA, 0x90, 0xB2, - 0xE1, 0x07, 0xEB, 0x86, 0xB9, 0x18, 0x82, 0x3B, - 0xDD, 0x3B, 0xD2, 0x66, 0x07, 0x22, 0xC8, 0xDB, - 0xFA, 0x66, 0xAB, 0xB9, 0xF8, 0x63, 0x8E, 0x46, - 0x34, 0x02, 0xF6, 0x57, 0xA1, 0x68, 0x64, 0x0A - }, - { - 0x6A, 0x6E, 0x89, 0x38, 0x4F, 0x53, 0x5F, 0x02, - 0x17, 0x6C, 0x48, 0xA9, 0x93, 0xD3, 0x68, 0x7B, - 0x38, 0x9B, 0xFC, 0x03, 0x05, 0x0C, 0x77, 0x70, - 0x86, 0x35, 0x5C, 0x1A, 0x55, 0x59, 0x77, 0x42, - 0xF0, 0xB7, 0x48, 0x34, 0xA7, 0x1D, 0x05, 0x2A, - 0xE8, 0xA8, 0x3D, 0xC3, 0x4A, 0x8F, 0xD7, 0xBA, - 0x5A, 0xA6, 0x9D, 0xBD, 0x61, 0x2A, 0x4C, 0x22, - 0xDF, 0x4F, 0x74, 0xE2, 0x52, 0x8F, 0xB7, 0xA3 - }, - { - 0x1E, 0x40, 0x38, 0xCF, 0xA5, 0x0D, 0x8B, 0x13, - 0xEF, 0x68, 0xBE, 0xC3, 0xB0, 0xFF, 0xD5, 0x62, - 0xA0, 0x7A, 0xD6, 0x34, 0xB5, 0x82, 0x82, 0x57, - 0xDB, 0xA8, 0x73, 0x04, 0xF8, 0x23, 0xA9, 0x00, - 0x49, 0x2A, 0x31, 0x37, 0x19, 0x8B, 0x60, 0x5C, - 0xC7, 0xF7, 0x7C, 0x33, 0xB8, 0xCA, 0x3D, 0x94, - 0x0F, 0xD9, 0xB3, 0x38, 0xCF, 0x6B, 0x7B, 0x36, - 0xE7, 0xD9, 0xD9, 0x27, 0x20, 0x97, 0x93, 0xD0 - }, - { - 0x5B, 0xA6, 0xCD, 0x98, 0x8F, 0xF9, 0xA4, 0x81, - 0x91, 0x42, 0x21, 0x7E, 0xD6, 0x5D, 0x43, 0x7B, - 0x41, 0x3B, 0xA5, 0x02, 0x6B, 0x55, 0x4D, 0x8D, - 0x94, 0xEA, 0x27, 0x02, 0xC0, 0x96, 0xD1, 0x01, - 0x47, 0x75, 0xDB, 0xA2, 0xCA, 0xE9, 0x6F, 0x1E, - 0x2E, 0x72, 0x29, 0xC3, 0x78, 0xF2, 0x0B, 0x03, - 0x89, 0xE1, 0x19, 0x54, 0x7F, 0xDD, 0x35, 0x22, - 0x4A, 0x61, 0x7F, 0xCD, 0xCD, 0x0C, 0xB3, 0xAF - }, - { - 0x2D, 0x20, 0x96, 0x12, 0x30, 0xE2, 0x50, 0xF8, - 0x1D, 0xDC, 0xD2, 0xD2, 0xAB, 0x3E, 0xF0, 0xDA, - 0xCF, 0x96, 0x85, 0x1E, 0xBA, 0xE5, 0x96, 0x34, - 0x47, 0x19, 0x2C, 0xDB, 0x89, 0xE4, 0x8E, 0x84, - 0xF3, 0x96, 0xEC, 0x9A, 0x09, 0x25, 0x27, 0x84, - 0xE1, 0x73, 0xAD, 0xA5, 0x2A, 0x9C, 0x81, 0xAC, - 0xDA, 0xB3, 0xD8, 0xD6, 0x83, 0x80, 0x24, 0x7A, - 0xE9, 0x75, 0x23, 0x9B, 0x01, 0x7D, 0xC1, 0xCE - }, - { - 0x35, 0x38, 0x3E, 0xA7, 0x76, 0x2B, 0x55, 0x31, - 0x0A, 0x7D, 0x57, 0xFB, 0xD5, 0xA5, 0x49, 0x97, - 0x57, 0x9B, 0x0B, 0xA3, 0x9A, 0x4E, 0xB8, 0x87, - 0x94, 0x2B, 0xD1, 0x4F, 0xD8, 0x48, 0x31, 0x88, - 0xE5, 0x00, 0x48, 0x83, 0x8D, 0x6C, 0x02, 0xDC, - 0x75, 0x89, 0x59, 0xA9, 0xF7, 0x4D, 0x83, 0x37, - 0x27, 0x43, 0xE8, 0x64, 0xC6, 0x01, 0xED, 0x70, - 0x40, 0xA9, 0xE8, 0x71, 0x52, 0xD4, 0xCF, 0xFB - }, - { - 0x0B, 0x22, 0x3B, 0x6A, 0x1C, 0x2D, 0x3A, 0xB3, - 0xF9, 0x07, 0x7A, 0x31, 0x7B, 0x7F, 0xE3, 0x2F, - 0x6F, 0x95, 0x7B, 0x7B, 0x17, 0x41, 0xF2, 0x71, - 0x77, 0x71, 0x83, 0x4D, 0x37, 0x96, 0xA1, 0x9B, - 0xA3, 0x62, 0x73, 0xC9, 0xEE, 0xD6, 0x4C, 0x07, - 0xFA, 0x4E, 0x9A, 0xF7, 0xA9, 0x8A, 0xCE, 0x9C, - 0x78, 0x9A, 0x79, 0xA5, 0xA0, 0xF9, 0x4D, 0x04, - 0x05, 0xAA, 0xF0, 0x4A, 0xF3, 0x1E, 0xD7, 0x97 - }, - { - 0x5A, 0x00, 0x7F, 0x58, 0x95, 0x52, 0x4A, 0x5E, - 0x80, 0x37, 0x03, 0x6E, 0x0F, 0x26, 0x39, 0xFD, - 0xA8, 0xC5, 0xC1, 0x51, 0x2D, 0x76, 0xE9, 0xD1, - 0x9B, 0x3D, 0xD2, 0xD5, 0xBA, 0x43, 0xF5, 0x07, - 0x97, 0x41, 0xA4, 0x58, 0x31, 0x3C, 0x5E, 0x02, - 0x40, 0x0C, 0xE0, 0x2C, 0xB6, 0x56, 0x80, 0xBE, - 0x28, 0x2E, 0xAC, 0xD9, 0xA2, 0x54, 0xEF, 0x1C, - 0xDD, 0xEE, 0xBD, 0xCE, 0xE8, 0x5D, 0x41, 0x87 - }, - { - 0xBE, 0x4D, 0xD1, 0xCC, 0xBD, 0xE1, 0x67, 0x00, - 0x04, 0xD0, 0xEF, 0xAB, 0x65, 0x43, 0xE9, 0x1C, - 0x4E, 0x46, 0x64, 0xE5, 0xA2, 0xA8, 0x8B, 0xAC, - 0x6D, 0xD2, 0x7D, 0x27, 0x64, 0x8D, 0x30, 0x2A, - 0x06, 0x5B, 0xE6, 0x07, 0x8B, 0x22, 0xE4, 0xC4, - 0xAB, 0x4F, 0x7F, 0x7C, 0xBF, 0xAF, 0xC1, 0xAD, - 0x86, 0xEC, 0x2A, 0x50, 0x4F, 0xE5, 0x85, 0x17, - 0x66, 0xF7, 0xA3, 0x24, 0x47, 0x57, 0xCB, 0x6F - }, - { - 0x0F, 0xB4, 0x48, 0x3F, 0x96, 0x59, 0x29, 0x6C, - 0xB9, 0x24, 0x5B, 0x57, 0x79, 0x2A, 0x1E, 0x6A, - 0x99, 0xF2, 0x87, 0x90, 0x07, 0x72, 0x87, 0x96, - 0x8A, 0xB3, 0xEF, 0x35, 0x89, 0xE6, 0x90, 0x24, - 0x06, 0xF1, 0xF3, 0x9D, 0xCC, 0xE0, 0x06, 0x1D, - 0xEA, 0x94, 0x0F, 0xC8, 0xC1, 0xC4, 0x9F, 0x4B, - 0x54, 0x5E, 0xED, 0x59, 0xE9, 0x6D, 0xDA, 0xE9, - 0x6A, 0x6C, 0x35, 0xB5, 0x59, 0x3C, 0x29, 0x77 - }, - { - 0x41, 0xD1, 0xFA, 0xDC, 0x60, 0xA4, 0x6C, 0x9A, - 0xD0, 0x12, 0x0A, 0x3F, 0x54, 0xD0, 0x05, 0xF5, - 0xA1, 0x07, 0x5E, 0x2F, 0x71, 0xEE, 0x0D, 0xA6, - 0x18, 0xBA, 0xC1, 0x46, 0x1E, 0xFA, 0xE9, 0x69, - 0xEC, 0xCD, 0x7A, 0xA5, 0x75, 0xC4, 0xCD, 0xAE, - 0x97, 0x1D, 0xED, 0x13, 0xAE, 0x13, 0xC5, 0x06, - 0x87, 0x2C, 0xEC, 0xB5, 0xB2, 0x08, 0xFA, 0x72, - 0xA9, 0x48, 0x40, 0x02, 0x3E, 0xDB, 0x3E, 0xFE - }, - { - 0x2F, 0x7F, 0xDC, 0x1D, 0xA4, 0x4B, 0x6E, 0x5D, - 0x2D, 0xEC, 0xDE, 0x82, 0x1A, 0xAF, 0x4B, 0x49, - 0x16, 0x8C, 0x02, 0xE8, 0xD5, 0xF2, 0x5D, 0x5C, - 0x69, 0x98, 0x71, 0x08, 0x3A, 0xEB, 0xD9, 0x28, - 0xB7, 0x4D, 0xC2, 0x2D, 0xCB, 0xED, 0xFA, 0xBA, - 0x93, 0x16, 0xAE, 0xFC, 0xA8, 0x48, 0xD1, 0x5F, - 0x05, 0x17, 0x32, 0x99, 0x03, 0xD3, 0x4B, 0x83, - 0x70, 0xDD, 0xF9, 0xBD, 0x58, 0xC6, 0xD0, 0xCD - }, - { - 0x88, 0x55, 0x8A, 0x46, 0x4E, 0xE1, 0xA8, 0x80, - 0x3B, 0x23, 0x95, 0xAF, 0x6A, 0x64, 0x90, 0x84, - 0x2B, 0x5C, 0xD4, 0x3D, 0x41, 0xF6, 0xC0, 0x7C, - 0xD6, 0xC5, 0xF8, 0x5F, 0x82, 0xF5, 0x84, 0x32, - 0xA0, 0xB1, 0x62, 0xB4, 0x38, 0xBF, 0x0C, 0xB7, - 0x08, 0x2A, 0x76, 0x73, 0xE2, 0x87, 0xD6, 0xB9, - 0x0F, 0x8D, 0x0D, 0xC8, 0xAA, 0x5C, 0xEB, 0xA3, - 0x6B, 0xFA, 0x77, 0xB1, 0x5B, 0xA0, 0x69, 0x16 - }, - { - 0xEC, 0xC1, 0x49, 0x91, 0x7B, 0x26, 0x63, 0x98, - 0xB6, 0xF3, 0x29, 0x7E, 0x96, 0x96, 0x73, 0xB1, - 0x4E, 0xAE, 0x69, 0xCE, 0x43, 0x67, 0x1F, 0xD3, - 0xC6, 0xC2, 0x15, 0xC7, 0xCF, 0x42, 0xDE, 0xA1, - 0x02, 0xFC, 0x6B, 0xD9, 0x0C, 0x87, 0xDB, 0xD4, - 0x29, 0x02, 0x51, 0x12, 0x9C, 0xC1, 0x9B, 0x38, - 0xCC, 0xF0, 0x0C, 0xBD, 0xB1, 0x6D, 0xD8, 0xDE, - 0x51, 0x58, 0x60, 0x1A, 0x41, 0x6B, 0x1F, 0x00 - }, - { - 0xED, 0x30, 0x12, 0xF8, 0x9D, 0x71, 0xED, 0x13, - 0xBB, 0x82, 0x72, 0xEC, 0xDC, 0x3D, 0x0F, 0x51, - 0xE1, 0x4A, 0x37, 0xC1, 0xEF, 0x77, 0x57, 0x77, - 0x7A, 0xDA, 0x67, 0x12, 0x78, 0x4B, 0xE1, 0x6E, - 0xCF, 0xD3, 0xE6, 0x40, 0x58, 0x30, 0xF5, 0x1D, - 0xB3, 0x3D, 0xCB, 0x85, 0x52, 0x92, 0x93, 0xE2, - 0x3E, 0x47, 0x3A, 0xBF, 0x8C, 0x5C, 0x76, 0x55, - 0xD0, 0xC4, 0xF1, 0x52, 0xD0, 0x48, 0xBA, 0xB2 - }, - { - 0x09, 0x7A, 0x81, 0x19, 0x1E, 0x10, 0x05, 0x67, - 0x6D, 0x6E, 0x22, 0xA9, 0x63, 0x48, 0xFA, 0x4A, - 0x7C, 0x95, 0x61, 0xFD, 0x4D, 0x22, 0x8E, 0xB2, - 0x5F, 0x29, 0x47, 0x56, 0xBB, 0x87, 0xA2, 0xBA, - 0x88, 0x47, 0x5B, 0x03, 0x6F, 0x79, 0xFE, 0x37, - 0x3D, 0x75, 0x40, 0x87, 0x05, 0x52, 0x00, 0x1D, - 0x54, 0x79, 0x5F, 0x25, 0x92, 0x39, 0xBE, 0x6D, - 0x32, 0xC4, 0x87, 0xD1, 0x94, 0x4F, 0x1F, 0xE7 - }, - { - 0x3F, 0xC7, 0x98, 0xE4, 0x69, 0xD3, 0x90, 0x86, - 0xBA, 0x0B, 0xB4, 0x06, 0x3E, 0x80, 0x5F, 0xDF, - 0xB2, 0x20, 0x8D, 0xE4, 0x99, 0x18, 0x41, 0x73, - 0xF9, 0xA2, 0x36, 0x4D, 0x56, 0xBC, 0xD5, 0x63, - 0xED, 0x61, 0x9B, 0xB6, 0x87, 0x32, 0x24, 0x25, - 0x01, 0x4A, 0x1A, 0xAD, 0x3B, 0xCF, 0x50, 0xD2, - 0x2D, 0x83, 0xA9, 0x9D, 0x09, 0x73, 0x0A, 0x92, - 0xEC, 0x65, 0x46, 0xB3, 0xFC, 0x40, 0xA2, 0xC6 - }, - { - 0x69, 0x12, 0xB4, 0xB3, 0x41, 0xC7, 0xDD, 0x70, - 0x68, 0x37, 0x38, 0xBA, 0x0E, 0x7D, 0xEB, 0xBA, - 0xBF, 0xCA, 0x5F, 0x4F, 0xB0, 0x76, 0x0C, 0x84, - 0x97, 0x76, 0xE9, 0x20, 0x75, 0x0B, 0xF1, 0x37, - 0x89, 0xA6, 0x99, 0x97, 0x96, 0x23, 0x4E, 0x9E, - 0x24, 0x07, 0x15, 0xB2, 0x67, 0x67, 0x78, 0x2B, - 0x85, 0xA6, 0x4D, 0x68, 0x0C, 0x6D, 0x4C, 0xD4, - 0x26, 0xAD, 0x72, 0xB2, 0xFC, 0xE0, 0x81, 0xE8 - }, - { - 0xCE, 0xCD, 0x14, 0x01, 0x50, 0x15, 0x7D, 0xC9, - 0x06, 0xC0, 0xFF, 0x7F, 0x87, 0xC0, 0x08, 0x8F, - 0x31, 0x64, 0x80, 0x78, 0x3B, 0x4F, 0xE0, 0xA5, - 0x94, 0x45, 0x10, 0xC6, 0x4A, 0x87, 0xE3, 0xED, - 0x06, 0x67, 0x97, 0xA2, 0x7C, 0xE9, 0xD0, 0xF2, - 0x84, 0xDC, 0xA5, 0x18, 0x44, 0x18, 0x08, 0xAC, - 0x18, 0x29, 0x0A, 0xFD, 0xC0, 0x31, 0x29, 0x4B, - 0x31, 0xAA, 0x8B, 0x4A, 0x9F, 0xCD, 0x78, 0xF8 - }, - { - 0x2A, 0x2B, 0xED, 0x5D, 0x6A, 0xC0, 0x89, 0x28, - 0x11, 0xA4, 0x09, 0xD9, 0xF1, 0xFF, 0x63, 0x03, - 0xCC, 0xF9, 0x55, 0x44, 0x57, 0x46, 0x99, 0xCD, - 0xA7, 0xF7, 0x35, 0x03, 0x01, 0xF6, 0xD0, 0xC4, - 0xE8, 0x6E, 0x63, 0x5C, 0x80, 0x87, 0x56, 0x66, - 0xE2, 0xBB, 0x39, 0x07, 0x51, 0x0D, 0x0E, 0x72, - 0x12, 0x0F, 0x04, 0x86, 0x5E, 0xDC, 0x4C, 0x6C, - 0xEE, 0xCB, 0x44, 0x62, 0xD6, 0xAF, 0x60, 0xFB - }, - { - 0x03, 0x85, 0xAE, 0x9B, 0x73, 0x5D, 0xC5, 0x9F, - 0x30, 0x4D, 0x41, 0x4C, 0xA0, 0x43, 0x74, 0x9A, - 0xB5, 0x1A, 0xB6, 0x65, 0xEE, 0x01, 0xBE, 0x5E, - 0x52, 0xDC, 0xF7, 0x25, 0xEE, 0x7D, 0xFE, 0xFE, - 0xA6, 0xAD, 0x73, 0xF3, 0x35, 0xEE, 0xCF, 0x2A, - 0x51, 0x02, 0xE8, 0x88, 0x07, 0xFD, 0xC7, 0x5A, - 0xE6, 0xDC, 0x49, 0x0D, 0x7B, 0x8B, 0x5F, 0x11, - 0x63, 0x03, 0xEF, 0x60, 0xA5, 0xF1, 0x7C, 0x06 - }, - { - 0x0C, 0xA3, 0xFF, 0x03, 0x89, 0x65, 0xC0, 0x3B, - 0xC6, 0x5B, 0xBE, 0x2D, 0x86, 0x6C, 0xE9, 0xE0, - 0xE4, 0xE7, 0xD0, 0x3D, 0xC7, 0xF8, 0x6B, 0xA5, - 0x65, 0x0F, 0x82, 0xDD, 0xB3, 0xA9, 0xAA, 0x84, - 0x6B, 0x2B, 0x1F, 0x55, 0x3B, 0xD8, 0x9F, 0xB4, - 0xF9, 0xB6, 0x2E, 0x3C, 0x7F, 0xAF, 0x9E, 0xC3, - 0x10, 0x9F, 0xA9, 0x0E, 0xE5, 0x6C, 0x24, 0x63, - 0xE6, 0xEF, 0xD1, 0xAB, 0xAD, 0x8E, 0x28, 0xE6 - }, - { - 0x6D, 0xFD, 0x4F, 0x22, 0x18, 0x4E, 0xD0, 0x91, - 0xFD, 0x5A, 0xBA, 0x03, 0x9F, 0xCD, 0x3D, 0xB9, - 0x22, 0xF5, 0xE5, 0x9B, 0xF8, 0x38, 0xC0, 0x37, - 0x35, 0x7F, 0xAD, 0x93, 0x4B, 0x45, 0x10, 0x60, - 0x3F, 0x43, 0xA7, 0x31, 0x9F, 0xFF, 0xA6, 0x23, - 0x86, 0xF8, 0x78, 0x8F, 0xDF, 0x9D, 0xED, 0x40, - 0xC6, 0x66, 0xB4, 0xBD, 0xCA, 0x86, 0xD9, 0x32, - 0x8F, 0xE5, 0x5A, 0xD8, 0x6B, 0x37, 0x2F, 0xC8 - }, - { - 0xA3, 0x18, 0x97, 0x61, 0x02, 0x74, 0x7D, 0x80, - 0x0F, 0x58, 0x4D, 0xF6, 0x5B, 0xFB, 0x44, 0x3B, - 0x85, 0x6F, 0x00, 0x9E, 0x74, 0xF7, 0x29, 0x46, - 0xD0, 0x07, 0x6C, 0xED, 0xAC, 0x04, 0x37, 0x6F, - 0xAB, 0x97, 0x34, 0x53, 0xAD, 0xAD, 0xC3, 0x10, - 0xF7, 0x20, 0x81, 0xCB, 0xBA, 0x96, 0x26, 0x4F, - 0xFE, 0x2B, 0x21, 0xA3, 0xB1, 0x8B, 0xE9, 0xD8, - 0x8C, 0x42, 0x46, 0xCB, 0xA6, 0xD3, 0x09, 0x01 - }, - { - 0xB5, 0xE6, 0xE4, 0xFC, 0xA0, 0xCF, 0x98, 0x48, - 0xA0, 0x05, 0x89, 0xC6, 0x54, 0x57, 0xDB, 0x68, - 0xB3, 0x25, 0x3A, 0x6E, 0x17, 0x78, 0x85, 0x41, - 0x47, 0x2E, 0x1F, 0xB9, 0x48, 0x17, 0xF8, 0x04, - 0x05, 0x4D, 0x07, 0xA5, 0xD3, 0x2D, 0xFA, 0x0C, - 0xDB, 0x6F, 0xB4, 0x4E, 0xED, 0x50, 0xD2, 0x0E, - 0x5F, 0x22, 0x64, 0x36, 0x11, 0x32, 0xFA, 0x5F, - 0xCF, 0xD6, 0xE1, 0xB3, 0x67, 0xC1, 0xBE, 0x28 - }, - { - 0x2E, 0xA4, 0x57, 0x38, 0x29, 0x25, 0xE0, 0x3C, - 0xF8, 0x11, 0x10, 0x05, 0x0E, 0x63, 0x6A, 0xD6, - 0x78, 0xE0, 0xAA, 0x3C, 0xBC, 0x69, 0x00, 0xBD, - 0xEF, 0x27, 0x8A, 0xAA, 0x18, 0xF2, 0x35, 0xE2, - 0x51, 0x60, 0xA2, 0x0E, 0x23, 0xFE, 0x0E, 0x62, - 0xA8, 0x51, 0x1B, 0x5D, 0xD0, 0x59, 0x2F, 0x79, - 0xCB, 0xC8, 0xEB, 0x7D, 0xEA, 0x64, 0xAC, 0x86, - 0x67, 0x49, 0x43, 0x45, 0xC6, 0x89, 0x2D, 0xD4 - }, - { - 0x96, 0xB3, 0x49, 0x8B, 0xCC, 0xD7, 0x8B, 0x5A, - 0x40, 0x1B, 0x27, 0x38, 0x78, 0x7D, 0x28, 0xA9, - 0x8A, 0x0E, 0xDF, 0xDC, 0x7C, 0x0B, 0x5F, 0xF9, - 0x43, 0xCF, 0xE1, 0xB1, 0x4E, 0x9C, 0xF5, 0xD9, - 0xED, 0x43, 0x10, 0x7D, 0xFB, 0xDD, 0x9E, 0x97, - 0x28, 0xD5, 0xFD, 0xD6, 0xF7, 0x1F, 0xBC, 0x77, - 0x0E, 0xAD, 0xDC, 0x4F, 0x2E, 0x40, 0x9A, 0xBE, - 0x71, 0x92, 0x7B, 0xAE, 0x1F, 0x8F, 0x73, 0xD1 - }, - { - 0xCE, 0x1B, 0xFB, 0x9A, 0xFE, 0xD2, 0x8A, 0xF4, - 0xDC, 0x75, 0x35, 0xAD, 0xEF, 0x71, 0xB8, 0xF1, - 0xB8, 0x0A, 0x8D, 0x72, 0x94, 0xB4, 0x11, 0xFD, - 0x1E, 0xD3, 0x93, 0xCF, 0x23, 0x2D, 0x3A, 0x5C, - 0x5D, 0xF2, 0x3D, 0xBB, 0x1D, 0xB2, 0x6D, 0xDD, - 0xF6, 0xF7, 0x45, 0xF8, 0xBC, 0x24, 0xC3, 0x78, - 0x1F, 0x2D, 0xBB, 0xC8, 0x18, 0xA0, 0x0A, 0xE1, - 0xFB, 0x9D, 0x64, 0x63, 0xE9, 0x5F, 0x29, 0x86 - }, - { - 0xE6, 0x4D, 0x37, 0x35, 0x6B, 0x29, 0x6B, 0x36, - 0x93, 0x0E, 0xAB, 0xE4, 0x54, 0xDB, 0x11, 0xB2, - 0x09, 0x7B, 0x0C, 0x04, 0x0B, 0xED, 0x57, 0x98, - 0x87, 0x8D, 0x38, 0xA8, 0xC4, 0xD1, 0xC6, 0xF3, - 0x26, 0x1F, 0x36, 0xBF, 0xF7, 0x64, 0xE3, 0xB4, - 0xD6, 0x06, 0xB3, 0x17, 0xE5, 0xFF, 0x50, 0x04, - 0x18, 0x45, 0x92, 0xB0, 0xB7, 0xDD, 0xFB, 0x8C, - 0x2F, 0xD8, 0x35, 0x23, 0x26, 0xCD, 0xDD, 0xB1 - }, - { - 0x85, 0xE6, 0xFE, 0x54, 0xE1, 0xE7, 0x60, 0x46, - 0xAF, 0x68, 0xF5, 0xC6, 0x04, 0x4C, 0x1E, 0x3F, - 0xFF, 0x3B, 0xFC, 0xA0, 0xBA, 0xEC, 0xAE, 0xF6, - 0xA1, 0xDF, 0x90, 0x35, 0x0D, 0xF2, 0xB0, 0xBE, - 0xC6, 0xA4, 0x20, 0xEE, 0x8F, 0x49, 0xAD, 0x44, - 0x64, 0xEC, 0x4C, 0x1E, 0x7D, 0x71, 0xF6, 0x67, - 0x61, 0x4A, 0xCE, 0xBD, 0xAD, 0xA3, 0xDF, 0x32, - 0x07, 0x79, 0x07, 0x83, 0x23, 0xF6, 0xA8, 0xAF - }, - { - 0xB1, 0x2F, 0xF1, 0xEB, 0x3B, 0xAB, 0x32, 0x0D, - 0x78, 0x55, 0xB5, 0x49, 0xD7, 0x2B, 0x72, 0x47, - 0x59, 0x91, 0x68, 0x11, 0xCB, 0xCF, 0x3E, 0x1A, - 0x12, 0x82, 0x3F, 0x98, 0xB6, 0x4A, 0xB5, 0xC4, - 0x59, 0x41, 0x61, 0x0F, 0x6B, 0x47, 0x1E, 0x35, - 0xFF, 0x79, 0x28, 0x29, 0xDD, 0x5A, 0xDE, 0x51, - 0x79, 0x12, 0x57, 0x38, 0xF3, 0xF2, 0x37, 0x28, - 0x63, 0x0F, 0x1E, 0xEC, 0x57, 0x77, 0x5A, 0x19 - }, - { - 0xB4, 0xDB, 0xE7, 0x2A, 0x1E, 0x21, 0x69, 0x7A, - 0x47, 0x44, 0xBE, 0x65, 0x00, 0x0C, 0xB1, 0xBA, - 0xD3, 0x7C, 0xE2, 0x14, 0x16, 0xEE, 0x6F, 0xCE, - 0xA8, 0x4E, 0xBA, 0xF1, 0x2A, 0x59, 0xC1, 0x1D, - 0x7C, 0x08, 0x0D, 0xF9, 0x2F, 0xB2, 0xAA, 0x8F, - 0x1C, 0x4E, 0xE8, 0xE2, 0xA2, 0x2D, 0x30, 0xBE, - 0x49, 0x85, 0x82, 0xD7, 0xC5, 0xFB, 0xBA, 0x16, - 0x5A, 0x47, 0x26, 0x89, 0xAF, 0xF6, 0x01, 0xB6 - }, - { - 0x34, 0x82, 0x18, 0xBE, 0x4D, 0xE0, 0x8D, 0xFB, - 0x24, 0x5B, 0xF2, 0x52, 0x86, 0xE3, 0x66, 0x18, - 0x63, 0x1D, 0x3B, 0xDB, 0x58, 0x27, 0xD9, 0xF7, - 0x4F, 0xA0, 0x43, 0x01, 0x66, 0x11, 0x31, 0xA4, - 0xD5, 0x5C, 0x76, 0x09, 0xB1, 0xA6, 0xA0, 0x3B, - 0x85, 0x3F, 0x07, 0x33, 0xE0, 0xAE, 0xC0, 0x26, - 0x16, 0xA0, 0xA4, 0x0E, 0x84, 0x91, 0xF4, 0x94, - 0xD7, 0x6C, 0x15, 0x43, 0xCF, 0xC6, 0x82, 0x14 - }, - { - 0x42, 0x87, 0xE1, 0x9B, 0xAB, 0x1D, 0x4F, 0x75, - 0xE1, 0xD1, 0x97, 0xCB, 0xB4, 0x3F, 0x11, 0x33, - 0x13, 0x07, 0xF2, 0xF7, 0x5B, 0x8D, 0x0D, 0x50, - 0x27, 0x8E, 0xEC, 0x54, 0x09, 0x99, 0xA0, 0x09, - 0xC0, 0x33, 0x73, 0x52, 0x96, 0x07, 0xFD, 0xA6, - 0x05, 0xAA, 0x0F, 0x07, 0x39, 0xE2, 0x0B, 0xD1, - 0xFD, 0xAA, 0x27, 0xD7, 0xC0, 0xCD, 0xC8, 0x28, - 0x4D, 0x98, 0xE6, 0xC7, 0x55, 0xA7, 0x56, 0x2E - }, - { - 0x08, 0x56, 0x0C, 0x99, 0x88, 0xC8, 0xCE, 0x5A, - 0x88, 0x76, 0xA6, 0x00, 0xB6, 0xE5, 0x12, 0xB4, - 0xE2, 0x43, 0xA4, 0xA4, 0x30, 0x0A, 0xD5, 0xAB, - 0x2F, 0xF0, 0x63, 0x7C, 0xC5, 0x6A, 0x04, 0x41, - 0x64, 0x5B, 0x3D, 0xEB, 0x16, 0x84, 0x06, 0x4E, - 0xA4, 0x3B, 0xAE, 0x1C, 0xB6, 0x2D, 0x3B, 0xC4, - 0x15, 0x37, 0xFE, 0x8D, 0x7D, 0xEC, 0xA7, 0x17, - 0x29, 0x37, 0x77, 0x6B, 0xBE, 0xD7, 0x93, 0xA9 - }, - { - 0xB5, 0x36, 0x16, 0x23, 0x94, 0x77, 0x6F, 0xA7, - 0xDD, 0x5E, 0x9F, 0xDD, 0x01, 0x53, 0x0F, 0xDA, - 0x52, 0xBE, 0x1D, 0x39, 0xBD, 0x60, 0x9B, 0x3F, - 0x3B, 0xD0, 0x47, 0x6B, 0x81, 0x60, 0xAA, 0x18, - 0xAB, 0x2D, 0x37, 0xD2, 0x99, 0x16, 0x28, 0xBE, - 0x2F, 0xCC, 0x12, 0x56, 0xCD, 0x48, 0x55, 0x25, - 0xD1, 0xFA, 0x35, 0x6B, 0x04, 0xD3, 0x0E, 0x4A, - 0x0F, 0x9F, 0xFF, 0xC9, 0x93, 0x5C, 0xF4, 0x32 - }, - { - 0x02, 0xAB, 0xC9, 0x71, 0x75, 0xED, 0xB4, 0x7A, - 0x4C, 0xB4, 0xBD, 0x38, 0xD8, 0x2F, 0x86, 0xAA, - 0x09, 0x9C, 0x8B, 0x8F, 0xA8, 0xAB, 0x3F, 0xE1, - 0xCE, 0x10, 0x5A, 0x22, 0xBD, 0x61, 0x65, 0x78, - 0xC6, 0xDD, 0x15, 0x15, 0xDF, 0xB0, 0x39, 0x7E, - 0x1D, 0x9D, 0x06, 0x71, 0x91, 0x6D, 0xE4, 0xB5, - 0x22, 0xE7, 0x4E, 0x63, 0x75, 0x23, 0x68, 0x93, - 0xC8, 0xFD, 0xA6, 0xD2, 0x36, 0xBC, 0x8D, 0xA1 - }, - { - 0x21, 0xE1, 0xEB, 0x73, 0x12, 0x76, 0xA8, 0x35, - 0xA6, 0xDD, 0xEA, 0x71, 0x78, 0xB2, 0x3E, 0xBC, - 0x9A, 0xEC, 0xAA, 0xBC, 0x7C, 0xCD, 0x70, 0x65, - 0x87, 0xD7, 0x1B, 0x85, 0x44, 0x97, 0x93, 0xB0, - 0x7E, 0x7B, 0x17, 0x9A, 0x3D, 0xA7, 0xA5, 0x71, - 0x98, 0x29, 0x97, 0xE8, 0xF5, 0xA6, 0x7F, 0x8C, - 0x93, 0xDA, 0xF1, 0x1A, 0xAA, 0x23, 0xF0, 0x7E, - 0x4D, 0xF7, 0xA1, 0x31, 0x05, 0xA5, 0x42, 0x09 - }, - { - 0x1C, 0xC5, 0x37, 0xD3, 0xE5, 0x0E, 0xD9, 0xFD, - 0xCD, 0xC4, 0xF3, 0xCC, 0xB4, 0x81, 0x93, 0x75, - 0x41, 0x53, 0x04, 0xD8, 0xE5, 0xA6, 0xC0, 0x58, - 0x05, 0xB6, 0xB5, 0xD9, 0xE1, 0xFC, 0x18, 0x25, - 0x68, 0x64, 0xF1, 0x0C, 0xD8, 0x12, 0xF8, 0x48, - 0x01, 0xB8, 0x61, 0x6A, 0x92, 0xB4, 0x07, 0x95, - 0xA1, 0x55, 0x93, 0x24, 0x64, 0xF6, 0x2D, 0xBF, - 0x6E, 0xBD, 0x2F, 0x9A, 0xC3, 0xEE, 0x28, 0x16 - }, - { - 0x6F, 0x6C, 0xD2, 0x60, 0x05, 0xC8, 0xA5, 0x61, - 0xCF, 0xF5, 0x1E, 0x30, 0x1D, 0x1A, 0x06, 0x8F, - 0xC2, 0x8B, 0x9B, 0x65, 0x0D, 0xDD, 0x27, 0xAE, - 0x97, 0xB5, 0x22, 0xDA, 0xE9, 0x63, 0x91, 0x34, - 0xD5, 0xA1, 0x50, 0x58, 0x7B, 0x0A, 0x90, 0x1F, - 0x3B, 0x9A, 0xAB, 0xC7, 0xE3, 0x97, 0x84, 0x98, - 0x4C, 0xC5, 0x85, 0x23, 0x5D, 0x8E, 0x17, 0xCE, - 0x9E, 0x3B, 0x42, 0x10, 0x5B, 0xF9, 0x03, 0x4C - }, - { - 0x69, 0xC1, 0x7C, 0x28, 0x64, 0xC3, 0x37, 0x9F, - 0xAF, 0xB7, 0x14, 0xC0, 0x47, 0x5E, 0x00, 0xCF, - 0x7C, 0x9B, 0x37, 0x7D, 0x57, 0xA8, 0xBC, 0x96, - 0x98, 0xB4, 0xD3, 0x4A, 0x54, 0x85, 0x41, 0x76, - 0xA2, 0xF8, 0xD1, 0x5A, 0xFB, 0x54, 0x77, 0x56, - 0x04, 0x78, 0x73, 0x90, 0xD6, 0x00, 0x74, 0xCD, - 0x4B, 0xCA, 0x69, 0x02, 0xEA, 0x23, 0xD3, 0xAE, - 0x1A, 0xC0, 0x83, 0x40, 0x9F, 0xE3, 0x8A, 0x4D - }, - { - 0x86, 0x69, 0xB0, 0xAD, 0x35, 0x82, 0x9E, 0xDC, - 0x2A, 0x8A, 0x09, 0x85, 0x2B, 0x0E, 0xE9, 0xB3, - 0x90, 0x3B, 0xF6, 0xC1, 0xF8, 0x2F, 0x90, 0xA3, - 0xF0, 0xED, 0x95, 0x24, 0x19, 0x2F, 0x10, 0x91, - 0xFD, 0x64, 0x84, 0xE0, 0x4C, 0x3F, 0xEA, 0x8B, - 0x02, 0x2F, 0x4A, 0x89, 0x50, 0xDB, 0x17, 0xD4, - 0x73, 0x41, 0x45, 0xC0, 0xCE, 0xC5, 0xDC, 0x38, - 0x74, 0x55, 0xC1, 0x26, 0x90, 0x3F, 0x77, 0x66 - }, - { - 0x3F, 0x35, 0xC4, 0x5D, 0x24, 0xFC, 0xFB, 0x4A, - 0xCC, 0xA6, 0x51, 0x07, 0x6C, 0x08, 0x00, 0x0E, - 0x27, 0x9E, 0xBB, 0xFF, 0x37, 0xA1, 0x33, 0x3C, - 0xE1, 0x9F, 0xD5, 0x77, 0x20, 0x2D, 0xBD, 0x24, - 0xB5, 0x8C, 0x51, 0x4E, 0x36, 0xDD, 0x9B, 0xA6, - 0x4A, 0xF4, 0xD7, 0x8E, 0xEA, 0x4E, 0x2D, 0xD1, - 0x3B, 0xC1, 0x8D, 0x79, 0x88, 0x87, 0xDD, 0x97, - 0x13, 0x76, 0xBC, 0xAE, 0x00, 0x87, 0xE1, 0x7E - }, -}; - - - - -static const uint8_t blake2bp_keyed_kat[KAT_LENGTH][BLAKE2B_OUTBYTES] = -{ - { - 0x9D, 0x94, 0x61, 0x07, 0x3E, 0x4E, 0xB6, 0x40, - 0xA2, 0x55, 0x35, 0x7B, 0x83, 0x9F, 0x39, 0x4B, - 0x83, 0x8C, 0x6F, 0xF5, 0x7C, 0x9B, 0x68, 0x6A, - 0x3F, 0x76, 0x10, 0x7C, 0x10, 0x66, 0x72, 0x8F, - 0x3C, 0x99, 0x56, 0xBD, 0x78, 0x5C, 0xBC, 0x3B, - 0xF7, 0x9D, 0xC2, 0xAB, 0x57, 0x8C, 0x5A, 0x0C, - 0x06, 0x3B, 0x9D, 0x9C, 0x40, 0x58, 0x48, 0xDE, - 0x1D, 0xBE, 0x82, 0x1C, 0xD0, 0x5C, 0x94, 0x0A - }, - { - 0xFF, 0x8E, 0x90, 0xA3, 0x7B, 0x94, 0x62, 0x39, - 0x32, 0xC5, 0x9F, 0x75, 0x59, 0xF2, 0x60, 0x35, - 0x02, 0x9C, 0x37, 0x67, 0x32, 0xCB, 0x14, 0xD4, - 0x16, 0x02, 0x00, 0x1C, 0xBB, 0x73, 0xAD, 0xB7, - 0x92, 0x93, 0xA2, 0xDB, 0xDA, 0x5F, 0x60, 0x70, - 0x30, 0x25, 0x14, 0x4D, 0x15, 0x8E, 0x27, 0x35, - 0x52, 0x95, 0x96, 0x25, 0x1C, 0x73, 0xC0, 0x34, - 0x5C, 0xA6, 0xFC, 0xCB, 0x1F, 0xB1, 0xE9, 0x7E - }, - { - 0xD6, 0x22, 0x0C, 0xA1, 0x95, 0xA0, 0xF3, 0x56, - 0xA4, 0x79, 0x5E, 0x07, 0x1C, 0xEE, 0x1F, 0x54, - 0x12, 0xEC, 0xD9, 0x5D, 0x8A, 0x5E, 0x01, 0xD7, - 0xC2, 0xB8, 0x67, 0x50, 0xCA, 0x53, 0xD7, 0xF6, - 0x4C, 0x29, 0xCB, 0xB3, 0xD2, 0x89, 0xC6, 0xF4, - 0xEC, 0xC6, 0xC0, 0x1E, 0x3C, 0xA9, 0x33, 0x89, - 0x71, 0x17, 0x03, 0x88, 0xE3, 0xE4, 0x02, 0x28, - 0x47, 0x90, 0x06, 0xD1, 0xBB, 0xEB, 0xAD, 0x51 - }, - { - 0x30, 0x30, 0x2C, 0x3F, 0xC9, 0x99, 0x06, 0x5D, - 0x10, 0xDC, 0x98, 0x2C, 0x8F, 0xEE, 0xF4, 0x1B, - 0xBB, 0x66, 0x42, 0x71, 0x8F, 0x62, 0x4A, 0xF6, - 0xE3, 0xEA, 0xBE, 0xA0, 0x83, 0xE7, 0xFE, 0x78, - 0x53, 0x40, 0xDB, 0x4B, 0x08, 0x97, 0xEF, 0xFF, - 0x39, 0xCE, 0xE1, 0xDC, 0x1E, 0xB7, 0x37, 0xCD, - 0x1E, 0xEA, 0x0F, 0xE7, 0x53, 0x84, 0x98, 0x4E, - 0x7D, 0x8F, 0x44, 0x6F, 0xAA, 0x68, 0x3B, 0x80 - }, - { - 0x32, 0xF3, 0x98, 0xA6, 0x0C, 0x1E, 0x53, 0xF1, - 0xF8, 0x1D, 0x6D, 0x8D, 0xA2, 0xEC, 0x11, 0x75, - 0x42, 0x2D, 0x6B, 0x2C, 0xFA, 0x0C, 0x0E, 0x66, - 0xD8, 0xC4, 0xE7, 0x30, 0xB2, 0x96, 0xA4, 0xB5, - 0x3E, 0x39, 0x2E, 0x39, 0x85, 0x98, 0x22, 0xA1, - 0x45, 0xAE, 0x5F, 0x1A, 0x24, 0xC2, 0x7F, 0x55, - 0x33, 0x9E, 0x2B, 0x4B, 0x44, 0x58, 0xE8, 0xC5, - 0xEB, 0x19, 0xAA, 0x14, 0x20, 0x64, 0x27, 0xAA - }, - { - 0x23, 0x6D, 0xB9, 0x33, 0xF1, 0x8A, 0x9D, 0xBD, - 0x4E, 0x50, 0xB7, 0x29, 0x53, 0x90, 0x65, 0xBD, - 0xA4, 0x20, 0xDF, 0x97, 0xAC, 0x78, 0x0B, 0xE4, - 0x3F, 0x59, 0x10, 0x3C, 0x47, 0x2E, 0x0B, 0xCC, - 0xA6, 0xD4, 0x97, 0x38, 0x97, 0x86, 0xAF, 0x22, - 0xBA, 0x94, 0x30, 0xB7, 0x4D, 0x6F, 0x74, 0xB1, - 0x3F, 0x6F, 0x94, 0x9E, 0x25, 0x6A, 0x14, 0x0A, - 0xA3, 0x4B, 0x47, 0x70, 0x0B, 0x10, 0x03, 0x43 - }, - { - 0x23, 0x8C, 0x9D, 0x08, 0x02, 0x85, 0xE3, 0x54, - 0x35, 0xCB, 0x53, 0x15, 0x5D, 0x9F, 0x79, 0x2C, - 0xA1, 0xBB, 0x27, 0xDE, 0x4F, 0x9B, 0x6C, 0x87, - 0x26, 0xE1, 0x1C, 0x02, 0x8E, 0x7B, 0x87, 0x87, - 0x33, 0x54, 0x91, 0x12, 0xA3, 0x28, 0xB5, 0x0E, - 0x8C, 0xD8, 0xBA, 0x27, 0x87, 0x21, 0x7E, 0x46, - 0xB8, 0x16, 0x8D, 0x57, 0x11, 0x3D, 0xD4, 0x04, - 0xD9, 0x14, 0xE2, 0x9A, 0x6A, 0x54, 0x70, 0xE6 - }, - { - 0x9A, 0x02, 0x1E, 0xBD, 0x50, 0x4A, 0x97, 0x59, - 0x6D, 0x0E, 0x85, 0x04, 0x8A, 0xE1, 0xDA, 0x89, - 0x99, 0xE3, 0xA0, 0x47, 0x01, 0x6F, 0x17, 0xC6, - 0xC5, 0x55, 0x6C, 0x27, 0x31, 0xE9, 0xB1, 0x39, - 0x26, 0x1F, 0x84, 0x3F, 0xAD, 0x6B, 0xD4, 0x3F, - 0x7C, 0x7C, 0x58, 0x7F, 0x69, 0x8D, 0x69, 0xB6, - 0x82, 0xE5, 0x68, 0xB4, 0x42, 0xAC, 0x45, 0x88, - 0x98, 0x57, 0xB7, 0x69, 0x07, 0x34, 0xCD, 0xBB - }, - { - 0x3A, 0xBA, 0x07, 0xAE, 0x98, 0x0E, 0x33, 0x86, - 0x37, 0x47, 0x9D, 0xCA, 0x1E, 0x35, 0x28, 0x00, - 0xF4, 0x58, 0x8E, 0x62, 0xD8, 0x23, 0x36, 0x5A, - 0xA6, 0x9C, 0x5B, 0x25, 0xFC, 0xE1, 0x29, 0x68, - 0xD2, 0x6C, 0x9B, 0xDB, 0xEE, 0x9A, 0x32, 0xBF, - 0xFD, 0x42, 0xE6, 0xB2, 0x2C, 0x81, 0x38, 0xA6, - 0x1C, 0x1F, 0xCE, 0x49, 0xFF, 0xBC, 0x19, 0x0E, - 0x1E, 0x15, 0x16, 0x01, 0x53, 0xCC, 0xB6, 0xB4 - }, - { - 0x77, 0x4C, 0xDF, 0x9A, 0xBB, 0x50, 0x81, 0xFE, - 0x07, 0xEB, 0x57, 0x25, 0xE6, 0x06, 0x9B, 0x8D, - 0x6C, 0x7E, 0x60, 0x04, 0xA2, 0x4D, 0x70, 0xF7, - 0xDF, 0xAB, 0xFC, 0x03, 0x82, 0x5B, 0xBC, 0x3B, - 0x30, 0xE6, 0x20, 0xB6, 0x04, 0x1F, 0x3C, 0xC2, - 0x89, 0x6B, 0x14, 0xAB, 0x66, 0x0A, 0xF7, 0x2E, - 0x24, 0x95, 0x10, 0xAC, 0x2F, 0xE8, 0x10, 0xCC, - 0x77, 0x63, 0xA2, 0xE5, 0xC3, 0xFC, 0xA7, 0xFC - }, - { - 0x9E, 0x08, 0x9F, 0x51, 0x65, 0x7B, 0x29, 0xC2, - 0x66, 0x8E, 0x28, 0x50, 0x52, 0x4E, 0x53, 0xAE, - 0xAA, 0xA7, 0x30, 0x6F, 0x2A, 0xD5, 0xA2, 0x32, - 0xB5, 0xF0, 0x7F, 0x68, 0x8D, 0x8A, 0xB2, 0xB4, - 0x25, 0xDF, 0x7E, 0xA5, 0xBD, 0x3E, 0x9F, 0xFD, - 0x61, 0x68, 0x38, 0x90, 0x15, 0x1D, 0x78, 0xBB, - 0x94, 0x03, 0x11, 0x85, 0xAC, 0xA4, 0x81, 0xE2, - 0x14, 0x0F, 0xE3, 0x79, 0x85, 0x36, 0x76, 0x43 - }, - { - 0xB3, 0x5B, 0xD5, 0x4E, 0x4F, 0x81, 0x69, 0x6B, - 0x4F, 0x22, 0x31, 0x6A, 0x1E, 0x33, 0x7D, 0x98, - 0xD1, 0xC6, 0xB0, 0x61, 0x10, 0x99, 0x87, 0x63, - 0xB5, 0x91, 0x33, 0x35, 0x92, 0x3A, 0x40, 0x76, - 0xCB, 0x80, 0xD6, 0xD8, 0xA5, 0x18, 0x62, 0x91, - 0x13, 0x47, 0x7B, 0x30, 0xA1, 0x32, 0xA6, 0xB2, - 0x7F, 0xC1, 0xEE, 0x79, 0xF6, 0xB2, 0xE0, 0xD3, - 0x5D, 0x5B, 0xC2, 0x97, 0x27, 0x46, 0x3D, 0xB5 - }, - { - 0x12, 0x39, 0x30, 0xD5, 0xA4, 0xB7, 0x3B, 0x49, - 0x1F, 0x50, 0xE5, 0x6E, 0x2B, 0x73, 0x97, 0xA4, - 0x3D, 0x2E, 0x47, 0x87, 0x23, 0x76, 0x02, 0xB6, - 0x6F, 0xE0, 0xA8, 0x47, 0xBD, 0x13, 0xCB, 0xE8, - 0xB3, 0x7D, 0xC7, 0x03, 0xD7, 0xB2, 0xB4, 0xEA, - 0xA8, 0xBF, 0xB9, 0xA5, 0x8A, 0x7D, 0x71, 0x9C, - 0x90, 0x8F, 0x19, 0x66, 0xA2, 0xF1, 0x9F, 0xE6, - 0xEB, 0x1A, 0x78, 0x96, 0x2A, 0xFA, 0x5B, 0xF9 - }, - { - 0x08, 0x9C, 0xBC, 0x7E, 0xE1, 0xB1, 0x2C, 0x0C, - 0xC9, 0xC8, 0x3F, 0xF6, 0x66, 0xFE, 0xC8, 0x02, - 0x6B, 0xB7, 0x1B, 0x90, 0x84, 0x97, 0x9B, 0x0E, - 0xA8, 0xB7, 0x23, 0xBB, 0xBE, 0x8B, 0x00, 0xD4, - 0x10, 0x08, 0xB6, 0x04, 0x99, 0xF2, 0x4F, 0x24, - 0x1B, 0x63, 0x28, 0x1F, 0xE5, 0xB4, 0xD8, 0x89, - 0x66, 0x30, 0x9C, 0x0D, 0x7E, 0x64, 0x66, 0x91, - 0x05, 0xE5, 0x1E, 0x69, 0xD7, 0xAF, 0x8C, 0xE5 - }, - { - 0x6B, 0x3C, 0x67, 0x89, 0x47, 0xF6, 0x12, 0x52, - 0x65, 0x7C, 0x35, 0x49, 0x78, 0xC1, 0x01, 0xB2, - 0xFD, 0xD2, 0x72, 0x9E, 0xC3, 0x49, 0x27, 0xDD, - 0x5E, 0xFF, 0x0A, 0x7C, 0x0A, 0x86, 0x58, 0x26, - 0xE8, 0x33, 0xC3, 0x63, 0x23, 0x21, 0x31, 0xB1, - 0x05, 0x93, 0xBE, 0x1C, 0xCF, 0x6B, 0xA5, 0x4E, - 0xCC, 0x14, 0x31, 0x2F, 0x45, 0xBF, 0xFC, 0x24, - 0x04, 0x62, 0x9F, 0xF8, 0x02, 0x67, 0xF0, 0x94 - }, - { - 0xAA, 0x0C, 0x23, 0xEA, 0x1C, 0x6F, 0xE2, 0xE9, - 0x0A, 0x77, 0x18, 0xEF, 0x4A, 0xA4, 0x75, 0x1F, - 0xF6, 0xBE, 0xB9, 0xD4, 0x61, 0x63, 0x59, 0x5B, - 0x5D, 0x4F, 0xB8, 0x96, 0x00, 0x52, 0x5C, 0x5B, - 0x6C, 0xF1, 0x9E, 0xCD, 0xB2, 0x47, 0x78, 0x72, - 0xA7, 0xA1, 0x2D, 0x40, 0xE5, 0x06, 0x36, 0x08, - 0xE5, 0xF0, 0x00, 0x8E, 0x79, 0x72, 0xA9, 0xC0, - 0x1A, 0x4B, 0xE2, 0xAF, 0xE9, 0x53, 0x2F, 0x9C - }, - { - 0x63, 0x34, 0x7A, 0xB4, 0xCB, 0xB6, 0xF2, 0x89, - 0x52, 0x99, 0x2C, 0x07, 0x9D, 0x18, 0xD4, 0x20, - 0x01, 0xB7, 0xF3, 0xA9, 0xD0, 0xFD, 0x90, 0xB0, - 0xA4, 0x77, 0x1F, 0x69, 0x72, 0xF0, 0xC5, 0x32, - 0x89, 0xC8, 0xAE, 0xE1, 0x43, 0x29, 0x4B, 0x50, - 0xC6, 0x34, 0x12, 0x58, 0x5C, 0xDC, 0xE4, 0xFF, - 0x7B, 0xED, 0x11, 0x2C, 0xD0, 0x3C, 0x9B, 0x1D, - 0xF3, 0xDE, 0xF0, 0xCC, 0x32, 0x0D, 0x6B, 0x70 - }, - { - 0x23, 0x96, 0xC0, 0xCB, 0x9E, 0xDA, 0xAC, 0xA9, - 0xD8, 0xB1, 0x04, 0x65, 0x2C, 0xB7, 0xF1, 0x25, - 0xF1, 0x93, 0x55, 0x1A, 0xE5, 0xD7, 0xBC, 0x94, - 0x63, 0x30, 0x7C, 0x9E, 0x69, 0xCA, 0x7D, 0xA2, - 0x3A, 0x9F, 0xBC, 0xBC, 0xB8, 0x66, 0x69, 0xD5, - 0xBA, 0x63, 0x43, 0x85, 0x93, 0xE1, 0x32, 0xF9, - 0x92, 0xB5, 0x7C, 0x00, 0x17, 0xC8, 0x6D, 0xDB, - 0x9B, 0x47, 0x28, 0x6E, 0xF5, 0xB6, 0x87, 0x18 - }, - { - 0xA9, 0x4B, 0x80, 0x22, 0x57, 0xFD, 0x03, 0x1E, - 0xE6, 0x0F, 0x1B, 0xE1, 0x84, 0x38, 0x3A, 0x76, - 0x32, 0x85, 0x39, 0xF9, 0xD8, 0x06, 0x08, 0x72, - 0xEF, 0x35, 0x73, 0xBE, 0xB6, 0xF2, 0x73, 0x68, - 0x08, 0x95, 0x90, 0xED, 0xBB, 0x21, 0xF4, 0xD8, - 0xF1, 0x81, 0xBA, 0x66, 0x20, 0x75, 0xF9, 0x19, - 0x05, 0x97, 0x4B, 0xEE, 0xEF, 0x1F, 0xC5, 0xCB, - 0x9B, 0xCF, 0xB2, 0x8A, 0xAE, 0x1E, 0x4D, 0xE3 - }, - { - 0x52, 0xC7, 0xD3, 0x39, 0x9A, 0x03, 0x80, 0x04, - 0xBE, 0xA5, 0x2D, 0x3E, 0xA9, 0xE9, 0x1E, 0x25, - 0x44, 0xC8, 0x65, 0x2A, 0xB8, 0xF5, 0x28, 0x5C, - 0x9D, 0x32, 0x18, 0x63, 0x7A, 0x6D, 0x9F, 0xCA, - 0xF0, 0xD9, 0x65, 0xB3, 0x58, 0x8E, 0xE6, 0xD7, - 0x3F, 0xA5, 0x99, 0xDE, 0xCA, 0x1F, 0x41, 0xDE, - 0xD8, 0x02, 0x5B, 0xF7, 0x76, 0x8E, 0x0E, 0x20, - 0x0E, 0x8C, 0xD3, 0xFF, 0x86, 0x8C, 0x38, 0x00 - }, - { - 0xB6, 0x29, 0xF5, 0x71, 0x62, 0x87, 0x6A, 0xDB, - 0x8F, 0xA9, 0x57, 0x2E, 0xBA, 0x4E, 0x1E, 0xCD, - 0x75, 0xA6, 0x56, 0x73, 0x08, 0xDE, 0x90, 0xDB, - 0xB8, 0xFF, 0xDE, 0x77, 0xDE, 0x82, 0x13, 0xA4, - 0xD7, 0xF7, 0xCB, 0x85, 0xAE, 0x1B, 0x71, 0xE6, - 0x45, 0x7B, 0xC4, 0xE8, 0x9C, 0x0D, 0x9D, 0xE2, - 0x41, 0xB6, 0xB9, 0xF3, 0x74, 0xB7, 0x34, 0x19, - 0x4D, 0xB2, 0xB2, 0x67, 0x02, 0xD7, 0xCB, 0x7C - }, - { - 0x72, 0x28, 0x46, 0xDD, 0xAC, 0xAA, 0x94, 0xFD, - 0xE6, 0x63, 0x2A, 0x2D, 0xC7, 0xDC, 0x70, 0x8B, - 0xDF, 0x98, 0x31, 0x1C, 0x9F, 0xB6, 0x3C, 0x61, - 0xE5, 0x25, 0xFD, 0x4B, 0x0D, 0x87, 0xB6, 0x38, - 0x8B, 0x5A, 0xF7, 0x04, 0x20, 0x18, 0xDD, 0xCA, - 0x06, 0x5E, 0x8A, 0x55, 0xBB, 0xFD, 0x68, 0xEE, - 0x61, 0xFC, 0xD3, 0xC6, 0x87, 0x8F, 0x5B, 0x09, - 0xBC, 0xC2, 0x7B, 0xED, 0x61, 0xDD, 0x93, 0xED - }, - { - 0x1C, 0xED, 0x6A, 0x0C, 0x78, 0x9D, 0xDB, 0x29, - 0x56, 0x78, 0xAD, 0x43, 0xA3, 0x22, 0xD8, 0x96, - 0x61, 0x7F, 0xDE, 0x27, 0x5F, 0x13, 0x8C, 0xCC, - 0xFB, 0x13, 0x26, 0xCD, 0x3F, 0x76, 0x09, 0xC2, - 0xAA, 0xA5, 0xEC, 0x10, 0x26, 0x97, 0x17, 0x3E, - 0x12, 0x1A, 0xE1, 0x63, 0x02, 0x4F, 0x42, 0x8C, - 0x98, 0x28, 0x35, 0xB4, 0xFA, 0x6D, 0xA6, 0xD6, - 0x78, 0xAE, 0xB9, 0xEE, 0x10, 0x6A, 0x3F, 0x6C - }, - { - 0xE8, 0x69, 0x14, 0x8C, 0x05, 0x45, 0xB3, 0x58, - 0x0E, 0x39, 0x5A, 0xFD, 0xC7, 0x45, 0xCD, 0x24, - 0x3B, 0x6B, 0x5F, 0xE3, 0xB6, 0x7E, 0x29, 0x43, - 0xF6, 0xF8, 0xD9, 0xF2, 0x4F, 0xFA, 0x40, 0xE8, - 0x81, 0x75, 0x6E, 0x1C, 0x18, 0xD9, 0x2F, 0x3E, - 0xBE, 0x84, 0x55, 0x9B, 0x57, 0xE2, 0xEE, 0x3A, - 0x65, 0xD9, 0xEC, 0xE0, 0x49, 0x72, 0xB3, 0x5D, - 0x4C, 0x4E, 0xBE, 0x78, 0x6C, 0x88, 0xDA, 0x62 - }, - { - 0xDA, 0xDA, 0x15, 0x5E, 0x55, 0x42, 0x32, 0xB1, - 0x6E, 0xCA, 0xD9, 0x31, 0xCB, 0x42, 0xE3, 0x25, - 0xB5, 0x86, 0xDB, 0xF1, 0xCB, 0xD0, 0xCE, 0x38, - 0x14, 0x45, 0x16, 0x6B, 0xD1, 0xBF, 0xA3, 0x32, - 0x49, 0x85, 0xE7, 0x7C, 0x6F, 0x0D, 0x51, 0x2A, - 0x02, 0x6E, 0x09, 0xD4, 0x86, 0x1C, 0x3B, 0xB8, - 0x52, 0x9D, 0x72, 0x02, 0xEA, 0xC1, 0xC0, 0x44, - 0x27, 0x44, 0xD3, 0x7C, 0x7F, 0x5A, 0xB8, 0xAF - }, - { - 0x2D, 0x14, 0x8C, 0x8E, 0x8F, 0x76, 0xFA, 0xAC, - 0x6F, 0x7F, 0x01, 0xF2, 0x03, 0x9E, 0xA0, 0x2A, - 0x42, 0xD9, 0x32, 0x57, 0x94, 0xC2, 0xC7, 0xA0, - 0x0F, 0x83, 0xF4, 0xA7, 0x79, 0x8A, 0xFB, 0xA9, - 0x93, 0xFF, 0x94, 0x91, 0x1E, 0x09, 0x8B, 0x00, - 0x1A, 0x0B, 0xDF, 0xF4, 0xC8, 0x5A, 0x2A, 0x61, - 0x31, 0xE0, 0xCF, 0xE7, 0x0F, 0x1D, 0x2E, 0x07, - 0xAF, 0x02, 0x09, 0xDA, 0x77, 0x96, 0x09, 0x1F - }, - { - 0x99, 0x98, 0x3A, 0x75, 0x9C, 0xCF, 0x9C, 0xAC, - 0xAE, 0x70, 0x2D, 0xCB, 0xFC, 0xDF, 0x72, 0x04, - 0xDD, 0xF0, 0x33, 0x4B, 0xC6, 0x5D, 0xAD, 0x84, - 0x6F, 0x83, 0x1F, 0x9F, 0x9D, 0x8A, 0x45, 0x3F, - 0x0D, 0x24, 0x93, 0x5C, 0x4C, 0x65, 0x7F, 0xFF, - 0x2E, 0xBB, 0xDB, 0xAF, 0x7B, 0xCE, 0x6A, 0xAC, - 0xDB, 0xB8, 0x87, 0x6F, 0x16, 0x04, 0x59, 0xB1, - 0xA4, 0xAA, 0xC9, 0x56, 0x97, 0xE0, 0x0D, 0x98 - }, - { - 0x7E, 0x4A, 0x02, 0x12, 0x6D, 0x75, 0x52, 0xF4, - 0xC9, 0xB9, 0x4D, 0x80, 0xE3, 0xCF, 0x7B, 0x89, - 0x7E, 0x09, 0x84, 0xE4, 0x06, 0xF0, 0x78, 0x13, - 0x5C, 0xF4, 0x56, 0xC0, 0xD5, 0x1E, 0x13, 0x91, - 0xFF, 0x18, 0xA8, 0x8F, 0x93, 0x12, 0x2C, 0x83, - 0x2C, 0xAC, 0x7D, 0x79, 0x6A, 0x6B, 0x42, 0x51, - 0x9B, 0x1D, 0xB4, 0xEA, 0xD8, 0xF4, 0x98, 0x40, - 0xCE, 0xB5, 0x52, 0x33, 0x6B, 0x29, 0xDE, 0x44 - }, - { - 0xD7, 0xE1, 0x6F, 0xD1, 0x59, 0x65, 0x8A, 0xD7, - 0xEE, 0x25, 0x1E, 0x51, 0x7D, 0xCE, 0x5A, 0x29, - 0xF4, 0x6F, 0xD4, 0xB8, 0xD3, 0x19, 0xDB, 0x80, - 0x5F, 0xC2, 0x5A, 0xA6, 0x20, 0x35, 0x0F, 0xF4, - 0x23, 0xAD, 0x8D, 0x05, 0x37, 0xCD, 0x20, 0x69, - 0x43, 0x2E, 0xBF, 0xF2, 0x92, 0x36, 0xF8, 0xC2, - 0xA8, 0xA0, 0x4D, 0x04, 0xB3, 0xB4, 0x8C, 0x59, - 0xA3, 0x55, 0xFC, 0xC6, 0x2D, 0x27, 0xF8, 0xEE - }, - { - 0x0D, 0x45, 0x17, 0xD4, 0xF1, 0xD0, 0x47, 0x30, - 0xC6, 0x91, 0x69, 0x18, 0xA0, 0x4C, 0x9E, 0x90, - 0xCC, 0xA3, 0xAC, 0x1C, 0x63, 0xD6, 0x45, 0x97, - 0x8A, 0x7F, 0x07, 0x03, 0x9F, 0x92, 0x20, 0x64, - 0x7C, 0x25, 0xC0, 0x4E, 0x85, 0xF6, 0xE2, 0x28, - 0x6D, 0x2E, 0x35, 0x46, 0x0D, 0x0B, 0x2C, 0x1E, - 0x25, 0xAF, 0x9D, 0x35, 0x37, 0xEF, 0x33, 0xFD, - 0x7F, 0xE5, 0x1E, 0x2B, 0xA8, 0x76, 0x4B, 0x36 - }, - { - 0x56, 0xB7, 0x2E, 0x51, 0x37, 0xC6, 0x89, 0xB2, - 0x73, 0x66, 0xFB, 0x22, 0xC7, 0xC6, 0x75, 0x44, - 0xF6, 0xBC, 0xE5, 0x76, 0x19, 0x41, 0x31, 0xC5, - 0xBF, 0xAB, 0x1C, 0xF9, 0x3C, 0x2B, 0x51, 0xAA, - 0xA3, 0x03, 0x36, 0x8A, 0xA8, 0x44, 0xD5, 0x8D, - 0xF0, 0xEE, 0x5D, 0x4E, 0x31, 0x9F, 0xCD, 0x8E, - 0xFF, 0xC6, 0x02, 0xCE, 0xE4, 0x35, 0x1B, 0xD2, - 0xF5, 0x51, 0x43, 0x0B, 0x92, 0x11, 0xE7, 0x3C - }, - { - 0xF3, 0x35, 0xCC, 0x22, 0xFF, 0xEA, 0x5A, 0xA5, - 0x9C, 0xDF, 0xC8, 0xF5, 0x02, 0x89, 0xCC, 0x92, - 0x31, 0x9B, 0x8B, 0x14, 0x40, 0x8D, 0x7A, 0x5A, - 0xA1, 0x23, 0x2A, 0xE2, 0x3A, 0xA1, 0xEA, 0x7F, - 0x77, 0x48, 0xCF, 0xEF, 0x03, 0x20, 0x10, 0xF8, - 0x62, 0x6D, 0x93, 0x18, 0xED, 0xBA, 0x98, 0xD4, - 0x16, 0x62, 0x03, 0x35, 0xC9, 0x01, 0xED, 0x02, - 0xEA, 0xBD, 0x27, 0x6A, 0x1B, 0x82, 0x9C, 0x9D - }, - { - 0xA9, 0x9A, 0x3D, 0x10, 0xF9, 0x5B, 0x44, 0x2F, - 0xFF, 0xF7, 0xC4, 0x18, 0xFA, 0x94, 0x9D, 0x48, - 0x30, 0x86, 0x9B, 0x0E, 0x60, 0xEC, 0x8B, 0x97, - 0x2C, 0x30, 0xA3, 0x16, 0x9C, 0x27, 0xBE, 0xB5, - 0xCF, 0x33, 0x05, 0x94, 0xF0, 0x14, 0xB6, 0x6B, - 0x22, 0x00, 0xA7, 0xF0, 0x86, 0xD2, 0xC2, 0xF3, - 0xF9, 0xFD, 0x85, 0x32, 0xA5, 0x71, 0x88, 0x76, - 0xDF, 0xCA, 0x66, 0x1B, 0xA0, 0xF7, 0xB3, 0x6D - }, - { - 0x15, 0x8E, 0x25, 0x70, 0xD0, 0x84, 0xA4, 0x86, - 0x9D, 0x96, 0x93, 0x43, 0xC0, 0x10, 0x86, 0x07, - 0x17, 0xFF, 0x74, 0x11, 0x61, 0x88, 0x17, 0x5F, - 0x2E, 0xD7, 0x4C, 0xD5, 0x78, 0xFA, 0x0D, 0x80, - 0x91, 0xB0, 0x3F, 0xAD, 0x0C, 0x65, 0xCF, 0x59, - 0xAB, 0x91, 0xDD, 0x73, 0xB3, 0x7F, 0xE3, 0xF5, - 0x8A, 0x58, 0xE7, 0xB4, 0x47, 0x9C, 0x87, 0x5A, - 0xCD, 0x63, 0xEC, 0x52, 0x58, 0x12, 0x35, 0x3F - }, - { - 0x7C, 0x49, 0x50, 0x1C, 0x58, 0x08, 0xB1, 0x5C, - 0x0D, 0x31, 0xBD, 0xD5, 0xBB, 0x56, 0x31, 0xD5, - 0x3A, 0xE0, 0x0D, 0xF4, 0x31, 0x02, 0x5F, 0xEA, - 0x51, 0xEB, 0x47, 0x62, 0x54, 0x4E, 0xFD, 0xEE, - 0x97, 0x8A, 0x83, 0x50, 0x8D, 0xEA, 0x6B, 0xFD, - 0x3B, 0x93, 0x1A, 0x0E, 0x95, 0x83, 0xCC, 0xFC, - 0x04, 0x9E, 0xA8, 0x46, 0x44, 0x70, 0x5D, 0x31, - 0x9F, 0xDC, 0x5C, 0x16, 0x3B, 0xF4, 0x82, 0x24 - }, - { - 0xFE, 0xF4, 0x36, 0xB3, 0x5F, 0x71, 0x7D, 0x59, - 0xAC, 0xA1, 0x7E, 0x9B, 0xF5, 0xFF, 0xDA, 0x28, - 0xF5, 0xF4, 0x01, 0x94, 0x3E, 0xFE, 0x93, 0xEB, - 0x58, 0x0F, 0xFB, 0x98, 0xF1, 0x3B, 0xEA, 0x80, - 0x94, 0x69, 0xA3, 0x44, 0xE7, 0x82, 0xA4, 0x43, - 0xC6, 0x4E, 0xB2, 0x5A, 0xD0, 0x9D, 0x8D, 0xE2, - 0x05, 0xFE, 0xE7, 0xD5, 0x63, 0x96, 0x86, 0xA1, - 0x9E, 0x7C, 0x42, 0xB4, 0x0F, 0x70, 0x6A, 0x08 - }, - { - 0x4D, 0x47, 0xA6, 0x7A, 0x5F, 0x8E, 0x17, 0xB7, - 0x22, 0xDF, 0x98, 0x58, 0xAE, 0xB6, 0x7B, 0x99, - 0x56, 0xB4, 0x59, 0x62, 0xEC, 0x35, 0x3D, 0xC2, - 0xE2, 0x7F, 0x0F, 0x50, 0x1C, 0x39, 0x8E, 0x34, - 0x39, 0x7B, 0xEB, 0xE0, 0x2B, 0x54, 0x92, 0x7E, - 0x2D, 0x31, 0xF1, 0x2E, 0xCF, 0x55, 0xE8, 0x82, - 0x69, 0xFA, 0xB5, 0x37, 0x0E, 0x7F, 0xA5, 0x70, - 0x35, 0x26, 0x6F, 0x89, 0xD5, 0xC2, 0x64, 0x41 - }, - { - 0x1B, 0x58, 0xDC, 0x7A, 0xAC, 0x36, 0x3B, 0x00, - 0x44, 0x6E, 0xA8, 0x03, 0xBC, 0xD7, 0x49, 0xC3, - 0xF5, 0xCA, 0xBE, 0xAA, 0xF2, 0x23, 0x99, 0x4C, - 0x0C, 0x3E, 0xCC, 0x1B, 0x28, 0x47, 0x73, 0x44, - 0xD7, 0xBF, 0x97, 0xC0, 0x8A, 0x95, 0x9D, 0x1A, - 0xC2, 0x06, 0x0B, 0x47, 0x27, 0x89, 0x86, 0x92, - 0x91, 0x88, 0xAD, 0x73, 0xDE, 0x67, 0x07, 0x8B, - 0xA6, 0x80, 0x96, 0x3B, 0x9D, 0x3B, 0x12, 0xA4 - }, - { - 0x3C, 0x52, 0x2C, 0x84, 0x3E, 0x69, 0x74, 0xEC, - 0x75, 0x0D, 0xF2, 0x20, 0xD4, 0x1A, 0x00, 0x4A, - 0xC2, 0xAD, 0xF0, 0x94, 0x56, 0xFA, 0x78, 0x7F, - 0x7C, 0x65, 0x43, 0xAB, 0x17, 0x97, 0x9C, 0x77, - 0x7B, 0x3E, 0x79, 0xD1, 0x78, 0x7D, 0xA5, 0xA8, - 0x3F, 0x17, 0x8D, 0xA9, 0xF0, 0x4C, 0xF6, 0xF5, - 0xB2, 0x55, 0xDD, 0xCB, 0x18, 0x74, 0x84, 0x1B, - 0xBF, 0x70, 0x16, 0xE6, 0x13, 0x2B, 0x99, 0x8A - }, - { - 0x5A, 0x4F, 0xEB, 0x8F, 0x70, 0x75, 0xB4, 0xDC, - 0x9C, 0xA1, 0x6C, 0x6F, 0x05, 0xCD, 0x6B, 0x70, - 0x27, 0x48, 0x5F, 0xFE, 0xD9, 0x15, 0x7D, 0x82, - 0x4D, 0x9D, 0x1A, 0x17, 0x20, 0xEE, 0xEE, 0xEA, - 0x3F, 0x6C, 0x12, 0x5F, 0xDA, 0x4B, 0xA4, 0x40, - 0x9D, 0x79, 0x80, 0x49, 0xFD, 0x18, 0x82, 0xC6, - 0x90, 0x28, 0x8F, 0x33, 0x54, 0x7A, 0x3D, 0x8D, - 0x62, 0x60, 0xB6, 0x54, 0x54, 0x88, 0x53, 0xD7 - }, - { - 0xBC, 0xAA, 0x79, 0x36, 0x32, 0x56, 0x9E, 0x2F, - 0x84, 0x17, 0xCC, 0x60, 0x32, 0x53, 0x53, 0x5B, - 0xD7, 0xD8, 0x5F, 0x38, 0x53, 0x19, 0x92, 0x59, - 0x1E, 0x56, 0xC1, 0xA4, 0xB6, 0xF5, 0x8E, 0xE7, - 0xF8, 0x18, 0xFA, 0xE0, 0x27, 0x88, 0x8A, 0x86, - 0x28, 0x43, 0x05, 0x10, 0x1E, 0xC0, 0x46, 0x61, - 0xF5, 0x99, 0x53, 0x47, 0xA4, 0x67, 0xED, 0x8B, - 0x92, 0x79, 0xF1, 0xAC, 0xC2, 0xB4, 0xBB, 0x1F - }, - { - 0x34, 0xAF, 0x91, 0xCC, 0x22, 0xA6, 0x9B, 0xCB, - 0x55, 0xDD, 0xBF, 0x7F, 0x0F, 0x43, 0xEC, 0x56, - 0x48, 0x40, 0x43, 0x32, 0x13, 0xEA, 0x55, 0xD9, - 0xF8, 0x1A, 0xC4, 0x75, 0x20, 0x8D, 0x74, 0x85, - 0x1D, 0xB7, 0x0F, 0xE4, 0x96, 0xAF, 0x9D, 0xA1, - 0xD3, 0x93, 0xEC, 0xF8, 0x78, 0x69, 0x5D, 0xD3, - 0x3F, 0xD5, 0x43, 0x49, 0xA6, 0xF8, 0x24, 0xAE, - 0xED, 0x18, 0x3C, 0xB1, 0xB0, 0x8C, 0x54, 0x85 - }, - { - 0xB8, 0xB7, 0xAD, 0x2E, 0xA2, 0xB6, 0xFA, 0x06, - 0xD0, 0x0B, 0xCD, 0x59, 0x9C, 0x99, 0x71, 0xC5, - 0xB4, 0xE1, 0x65, 0x58, 0xE1, 0x52, 0x12, 0xC9, - 0xBF, 0xD3, 0x73, 0xE4, 0xBC, 0x79, 0x17, 0x05, - 0x26, 0x01, 0xFF, 0xDB, 0x68, 0x01, 0xBE, 0x80, - 0xBA, 0x50, 0x9D, 0xB8, 0x2A, 0x0B, 0x71, 0x95, - 0x92, 0x91, 0x33, 0xAD, 0x53, 0x99, 0x56, 0x06, - 0x52, 0x33, 0xF4, 0x9D, 0x07, 0x1C, 0x84, 0xE4 - }, - { - 0xDC, 0xEE, 0x9C, 0x45, 0xBC, 0x5D, 0x1F, 0xE6, - 0x30, 0xB1, 0x8B, 0x06, 0x3C, 0xE8, 0x2C, 0x38, - 0x57, 0xE3, 0x0D, 0x20, 0xC6, 0x4B, 0x5C, 0xC2, - 0x58, 0x84, 0x94, 0x3E, 0x7A, 0xE9, 0x4E, 0xDF, - 0xF8, 0x50, 0xEB, 0x0E, 0x82, 0x44, 0x02, 0x3D, - 0x3D, 0x07, 0xA8, 0xA0, 0x07, 0x06, 0xF0, 0x58, - 0x2C, 0xC1, 0x02, 0xB6, 0x6C, 0x6D, 0xDA, 0x86, - 0xE8, 0xF2, 0xDF, 0x32, 0x56, 0x59, 0x88, 0x6F - }, - { - 0x04, 0xF6, 0xE8, 0x22, 0xF1, 0x7C, 0xC7, 0xA5, - 0x94, 0x6D, 0xF8, 0x0D, 0x95, 0x8A, 0xEF, 0x06, - 0x5D, 0x87, 0x49, 0x16, 0xE1, 0x03, 0xA6, 0x83, - 0x0C, 0x6E, 0x46, 0xB6, 0x05, 0x59, 0x18, 0x18, - 0x0D, 0x14, 0x52, 0x29, 0x3C, 0x58, 0xA9, 0x74, - 0x9C, 0xBC, 0x8F, 0x0A, 0xC4, 0x08, 0xA9, 0xCA, - 0x89, 0x57, 0x61, 0xCF, 0xC4, 0x51, 0x16, 0x46, - 0x41, 0xA1, 0x79, 0xFB, 0x5C, 0xD8, 0xFE, 0xBC - }, - { - 0x51, 0x1F, 0xDB, 0x7C, 0x88, 0x26, 0x85, 0x35, - 0xE9, 0x7E, 0x4E, 0xD8, 0x92, 0xF3, 0xC0, 0x65, - 0x83, 0x2B, 0x26, 0x59, 0x14, 0xFC, 0x61, 0x07, - 0xA1, 0xD2, 0x7D, 0xBB, 0x7D, 0x51, 0xC3, 0x7E, - 0x95, 0x98, 0x15, 0x06, 0xC1, 0x14, 0x72, 0x44, - 0xD5, 0xBA, 0xE9, 0x0E, 0xE9, 0x0D, 0x08, 0x49, - 0x84, 0xBA, 0xA7, 0x58, 0x7F, 0x41, 0xFF, 0x6F, - 0x4B, 0xA7, 0x22, 0xC8, 0xB9, 0x2A, 0xEB, 0x99 - }, - { - 0x2B, 0xA2, 0xBD, 0x17, 0xE9, 0x26, 0x27, 0x5B, - 0x06, 0x83, 0xB2, 0x36, 0xBF, 0xE3, 0x76, 0x30, - 0x26, 0x6E, 0x37, 0xF4, 0x18, 0x2F, 0x53, 0xA9, - 0x82, 0x34, 0xE9, 0x15, 0xAB, 0x64, 0xC9, 0x59, - 0x96, 0xC6, 0xCB, 0x7A, 0xE8, 0x80, 0xC3, 0xDF, - 0xCB, 0x47, 0xD0, 0x5A, 0xAD, 0xD2, 0x1A, 0xBF, - 0x8E, 0x40, 0xB7, 0x3F, 0x40, 0xF3, 0x98, 0xDC, - 0x5B, 0x02, 0x14, 0x14, 0x57, 0x45, 0x6A, 0x09 - }, - { - 0x9B, 0x66, 0x8D, 0x9B, 0x44, 0x47, 0xE3, 0x76, - 0xF6, 0xC6, 0xCF, 0xA6, 0x8D, 0xBC, 0x79, 0x19, - 0x83, 0x81, 0xAB, 0x60, 0x5F, 0x55, 0xD5, 0xA7, - 0xEF, 0x68, 0x3B, 0xCE, 0xD4, 0x6F, 0x9A, 0xFD, - 0x36, 0x85, 0x41, 0x1A, 0x66, 0xE2, 0x34, 0x6F, - 0x96, 0x07, 0x77, 0xD0, 0xC9, 0x22, 0x71, 0x24, - 0x30, 0xE0, 0x18, 0xBF, 0xAE, 0x86, 0x53, 0x01, - 0x7E, 0xA2, 0x0E, 0xCD, 0x5F, 0x1F, 0x95, 0x6C - }, - { - 0x56, 0x81, 0x02, 0x4F, 0x53, 0x85, 0x88, 0xA0, - 0x1B, 0x2C, 0x83, 0x94, 0xCA, 0xE8, 0x73, 0xC6, - 0xD8, 0x5D, 0x6A, 0xA0, 0x6E, 0xDD, 0xB3, 0xA5, - 0x02, 0x09, 0x6F, 0xC0, 0x82, 0xBB, 0x89, 0xCB, - 0x24, 0x15, 0x31, 0xB3, 0x15, 0x75, 0x0D, 0x31, - 0xBB, 0x0B, 0x63, 0x01, 0x28, 0xD1, 0x9D, 0x11, - 0x39, 0x2B, 0xCF, 0x4B, 0x34, 0x78, 0xD5, 0x23, - 0xD7, 0xD2, 0x13, 0xE4, 0x75, 0x0F, 0x55, 0x92 - }, - { - 0x2A, 0xA9, 0x1B, 0xA6, 0xDE, 0x60, 0x17, 0xF1, - 0x93, 0x0F, 0xC7, 0xD9, 0x6D, 0xCC, 0xD6, 0x70, - 0x74, 0x8B, 0x7E, 0xB1, 0xD0, 0x94, 0xDF, 0xB4, - 0xB3, 0xB1, 0x47, 0x8A, 0x61, 0x2E, 0xBF, 0x03, - 0xDD, 0xD7, 0x21, 0x27, 0x9A, 0x26, 0x6D, 0xE3, - 0x88, 0x45, 0xE6, 0x12, 0xC9, 0x30, 0x98, 0xC2, - 0xEF, 0xFF, 0x34, 0xFE, 0x50, 0x06, 0x17, 0x20, - 0x5B, 0x1D, 0xE2, 0xFE, 0xA1, 0xD8, 0x02, 0x46 - }, - { - 0x82, 0x4D, 0x89, 0xC0, 0x63, 0x7C, 0xE1, 0x78, - 0xB6, 0x30, 0x68, 0x4C, 0x72, 0x9E, 0x26, 0x65, - 0x3F, 0x34, 0xEA, 0xC7, 0xE9, 0x04, 0x12, 0xE9, - 0x63, 0xD3, 0xF1, 0x9D, 0x64, 0x51, 0xE8, 0x25, - 0x85, 0x21, 0x67, 0xC4, 0x8D, 0xF7, 0xCC, 0x55, - 0xB2, 0x57, 0xB2, 0x50, 0xA7, 0x0C, 0x7B, 0xCC, - 0xFA, 0x9A, 0xA1, 0x5C, 0x18, 0x8A, 0xC4, 0x63, - 0x7A, 0x52, 0x22, 0x89, 0xC0, 0x87, 0x6A, 0xD4 - }, - { - 0x87, 0xE4, 0xAE, 0x11, 0xDA, 0x1A, 0x2C, 0xA8, - 0x82, 0x2A, 0xE3, 0x30, 0xDC, 0x97, 0xAB, 0x2E, - 0x47, 0xFF, 0x62, 0x32, 0x30, 0x93, 0xC2, 0xB7, - 0xA6, 0xC0, 0xE2, 0xC1, 0x68, 0x21, 0xCD, 0x7C, - 0xEC, 0x92, 0x18, 0x4D, 0xF4, 0xBB, 0x6E, 0x2B, - 0x62, 0x6A, 0x44, 0x78, 0x03, 0x90, 0x63, 0xAF, - 0xEE, 0xB0, 0xD2, 0x87, 0xF2, 0x42, 0x19, 0x20, - 0x78, 0x98, 0xCC, 0xE7, 0xAD, 0xE0, 0x63, 0x9C - }, - { - 0xDD, 0x7F, 0x2F, 0x44, 0xA4, 0x02, 0xA0, 0x1E, - 0x82, 0x16, 0xB1, 0x03, 0xA4, 0xE7, 0x23, 0x5C, - 0x28, 0x30, 0x31, 0x9D, 0x56, 0xAF, 0x63, 0x9F, - 0x23, 0xC4, 0x8C, 0x27, 0x59, 0xAB, 0xA6, 0xEB, - 0x5E, 0xEE, 0xE3, 0x8C, 0x29, 0x8E, 0xBE, 0x41, - 0x98, 0x26, 0x7A, 0x00, 0xEB, 0x2A, 0x08, 0xD9, - 0x3A, 0x50, 0x37, 0x03, 0x17, 0x1C, 0x77, 0x33, - 0x38, 0x62, 0x10, 0x10, 0x55, 0xBD, 0x7A, 0xD2 - }, - { - 0x4C, 0xB8, 0x46, 0x59, 0x61, 0x93, 0xF7, 0xF2, - 0x78, 0xAA, 0xAA, 0xC5, 0xCC, 0xFF, 0xD5, 0x35, - 0x7A, 0xB0, 0xD1, 0x24, 0x5F, 0x69, 0x79, 0xD1, - 0x41, 0xA4, 0x71, 0xBD, 0xAB, 0x55, 0xE2, 0x38, - 0xB1, 0xAE, 0xD6, 0x7B, 0x73, 0x39, 0x95, 0x04, - 0xB9, 0x7D, 0xF1, 0xA2, 0x5E, 0xB6, 0xFE, 0x27, - 0x2B, 0x5C, 0xD4, 0x96, 0xA7, 0xC8, 0xA0, 0x60, - 0x92, 0x6E, 0x74, 0x04, 0xFD, 0xA0, 0x79, 0x0D - }, - { - 0x6F, 0x44, 0xEC, 0xDA, 0xE1, 0x4E, 0x3B, 0x81, - 0xA1, 0x91, 0x22, 0x03, 0x01, 0x5F, 0x59, 0x18, - 0xEA, 0xC6, 0xFB, 0xF4, 0x96, 0x60, 0x10, 0xF4, - 0x9D, 0x2B, 0xC2, 0xBC, 0xEF, 0xE7, 0xB1, 0xDF, - 0xEC, 0x5C, 0x83, 0x5D, 0x7D, 0x87, 0xA4, 0x43, - 0x71, 0xF1, 0x5A, 0x6C, 0x08, 0x42, 0x52, 0xB9, - 0x34, 0x65, 0x26, 0x42, 0x72, 0xA4, 0x10, 0xD5, - 0x0F, 0x89, 0xA1, 0x17, 0xF3, 0x1A, 0xF4, 0x63 - }, - { - 0x1F, 0x70, 0x5F, 0x6E, 0x9F, 0x07, 0x0D, 0x87, - 0xFD, 0xE8, 0xE2, 0x77, 0x46, 0x74, 0xFA, 0x9B, - 0xF1, 0x20, 0xD2, 0x88, 0xEB, 0x0B, 0xE7, 0xAA, - 0x12, 0x8D, 0xFB, 0x5D, 0x10, 0x11, 0xCE, 0x1F, - 0xDA, 0x99, 0xB2, 0x55, 0x22, 0x66, 0x65, 0xD8, - 0x3F, 0x63, 0x4E, 0x8F, 0xCA, 0xBD, 0xA9, 0xA2, - 0x3C, 0x03, 0x51, 0x5E, 0x9C, 0xFE, 0xCE, 0x6E, - 0x94, 0xA8, 0xEC, 0x92, 0xE4, 0xED, 0xEC, 0xB7 - }, - { - 0x2D, 0x96, 0xC5, 0xB0, 0x15, 0x74, 0x72, 0x2B, - 0x81, 0x7F, 0xEB, 0x48, 0x6C, 0x5F, 0xC9, 0x8F, - 0x5F, 0x84, 0x61, 0xF4, 0xCE, 0xE9, 0x90, 0x5A, - 0xF2, 0x06, 0xD4, 0x72, 0x33, 0x86, 0xD1, 0xC4, - 0xC7, 0xCA, 0xC5, 0x84, 0x00, 0x28, 0xD7, 0xAF, - 0xED, 0x0E, 0x38, 0xAD, 0x13, 0x96, 0x28, 0xEB, - 0x6A, 0xF9, 0x2B, 0x4B, 0x88, 0xEB, 0xF0, 0x9B, - 0x1F, 0xA0, 0x47, 0xFB, 0xE1, 0x0B, 0xC3, 0x1D - }, - { - 0x65, 0xDA, 0x78, 0x0A, 0x0A, 0x37, 0x47, 0x9D, - 0xD8, 0xF4, 0xD6, 0x55, 0x64, 0xF9, 0xA7, 0x08, - 0x9E, 0x42, 0x07, 0xEB, 0x16, 0xAC, 0xA3, 0xF6, - 0x55, 0x31, 0xCF, 0xEE, 0x76, 0x25, 0xBA, 0x13, - 0x80, 0xA4, 0x97, 0xB6, 0x24, 0x72, 0xFC, 0x7E, - 0x00, 0x07, 0xA6, 0xB0, 0x35, 0x61, 0x04, 0x16, - 0xA5, 0xF8, 0x2C, 0x10, 0x82, 0xFA, 0x06, 0x5C, - 0x46, 0xDD, 0xEE, 0x49, 0x40, 0xD1, 0xFC, 0x46 - }, - { - 0x1C, 0x09, 0xA3, 0xB3, 0x80, 0xB8, 0xA7, 0xFC, - 0x33, 0x3F, 0xD2, 0x71, 0x4D, 0xF7, 0x12, 0x9B, - 0x44, 0xA4, 0x67, 0x68, 0xBA, 0xCF, 0x0A, 0x67, - 0xA3, 0x8A, 0x47, 0xB3, 0xAB, 0x31, 0xF5, 0x1B, - 0x05, 0x33, 0xC2, 0xAA, 0x2B, 0x4B, 0x7B, 0xBB, - 0x6A, 0xE5, 0xED, 0xF3, 0xDC, 0xB0, 0xEC, 0xC1, - 0xA2, 0x83, 0xE8, 0x43, 0xF2, 0x90, 0x7B, 0x34, - 0x1F, 0x17, 0x9A, 0xFD, 0x8B, 0x67, 0xDA, 0x90 - }, - { - 0x67, 0x88, 0x8B, 0x83, 0xFA, 0xAF, 0xBB, 0x62, - 0x29, 0x34, 0xB8, 0xD5, 0x59, 0x63, 0xE1, 0x86, - 0x15, 0x3E, 0x59, 0x51, 0x88, 0x7C, 0x7F, 0x4A, - 0x76, 0x35, 0xC7, 0x98, 0xD9, 0xA5, 0x82, 0x94, - 0xBE, 0x26, 0xA3, 0xC5, 0x49, 0xC9, 0xFD, 0x59, - 0x86, 0xAB, 0xD1, 0x9F, 0x40, 0x1E, 0xE2, 0x4E, - 0xDA, 0x36, 0x02, 0x04, 0x2A, 0xD3, 0x83, 0x35, - 0x7A, 0x31, 0x7D, 0x38, 0x07, 0x3B, 0x38, 0xCE - }, - { - 0xB4, 0xF7, 0x99, 0x63, 0xCA, 0x31, 0xBB, 0x62, - 0x26, 0x5D, 0xD9, 0x29, 0xAF, 0x7D, 0x51, 0x27, - 0x2F, 0xA6, 0x63, 0x1D, 0xE7, 0xFA, 0x35, 0xF7, - 0xA6, 0xB0, 0x3F, 0x9F, 0xCF, 0xDB, 0x8E, 0x3B, - 0x5B, 0xAC, 0xE3, 0x35, 0x91, 0xB7, 0xEC, 0x2C, - 0xFA, 0xB4, 0x9C, 0x91, 0xA6, 0xDB, 0x1F, 0xF8, - 0xF6, 0x78, 0x6D, 0x08, 0xF4, 0x4E, 0x80, 0x62, - 0xD2, 0xFF, 0x69, 0x6A, 0x7D, 0x98, 0x41, 0x42 - }, - { - 0x40, 0x84, 0x83, 0x69, 0x7B, 0xB6, 0xF9, 0xD0, - 0x11, 0xA1, 0xF2, 0x9A, 0x23, 0xC2, 0x78, 0xA8, - 0x1D, 0x37, 0x57, 0x8D, 0xCC, 0xCF, 0x42, 0x3B, - 0xDF, 0x48, 0x93, 0x37, 0xF1, 0x82, 0xEA, 0xB7, - 0x9A, 0x50, 0xB0, 0x5F, 0x3D, 0x2C, 0xCC, 0x49, - 0x13, 0x37, 0xC7, 0xE4, 0x1F, 0x30, 0x79, 0x3B, - 0xD2, 0x7D, 0x76, 0x61, 0xC2, 0xE3, 0x04, 0xC9, - 0x46, 0xA5, 0xA4, 0x01, 0xAF, 0x8D, 0x94, 0x6F - }, - { - 0xEE, 0xB5, 0xAD, 0xE1, 0xAB, 0x97, 0xE7, 0x15, - 0x43, 0x43, 0xA4, 0x6E, 0xB4, 0xCD, 0xD2, 0xA7, - 0x73, 0xF3, 0x63, 0x01, 0xED, 0xC6, 0xA1, 0xBC, - 0x1D, 0xD6, 0x48, 0x0E, 0x08, 0xF5, 0x87, 0x65, - 0xCB, 0x93, 0x87, 0x82, 0x92, 0x3B, 0xC0, 0x1F, - 0x8E, 0x0C, 0x61, 0xC6, 0xBE, 0x0D, 0xD1, 0xAB, - 0x4C, 0x18, 0xCB, 0x15, 0xED, 0x52, 0x10, 0x11, - 0x24, 0x05, 0xF1, 0xEA, 0x8F, 0x2E, 0x8C, 0x4E - }, - { - 0x71, 0x4A, 0xD1, 0x85, 0xF1, 0xEE, 0xC4, 0x3F, - 0x46, 0xB6, 0x7E, 0x99, 0x2D, 0x2D, 0x38, 0xBC, - 0x31, 0x49, 0xE3, 0x7D, 0xA7, 0xB4, 0x47, 0x48, - 0xD4, 0xD1, 0x4C, 0x16, 0x1E, 0x08, 0x78, 0x02, - 0x04, 0x42, 0x14, 0x95, 0x79, 0xA8, 0x65, 0xD8, - 0x04, 0xB0, 0x49, 0xCD, 0x01, 0x55, 0xBA, 0x98, - 0x33, 0x78, 0x75, 0x7A, 0x13, 0x88, 0x30, 0x1B, - 0xDC, 0x0F, 0xAE, 0x2C, 0xEA, 0xEA, 0x07, 0xDD - }, - { - 0x22, 0xB8, 0x24, 0x9E, 0xAF, 0x72, 0x29, 0x64, - 0xCE, 0x42, 0x4F, 0x71, 0xA7, 0x4D, 0x03, 0x8F, - 0xF9, 0xB6, 0x15, 0xFB, 0xA5, 0xC7, 0xC2, 0x2C, - 0xB6, 0x27, 0x97, 0xF5, 0x39, 0x82, 0x24, 0xC3, - 0xF0, 0x72, 0xEB, 0xC1, 0xDA, 0xCB, 0xA3, 0x2F, - 0xC6, 0xF6, 0x63, 0x60, 0xB3, 0xE1, 0x65, 0x8D, - 0x0F, 0xA0, 0xDA, 0x1E, 0xD1, 0xC1, 0xDA, 0x66, - 0x2A, 0x20, 0x37, 0xDA, 0x82, 0x3A, 0x33, 0x83 - }, - { - 0xB8, 0xE9, 0x03, 0xE6, 0x91, 0xB9, 0x92, 0x78, - 0x25, 0x28, 0xF8, 0xDB, 0x96, 0x4D, 0x08, 0xE3, - 0xBA, 0xAF, 0xBD, 0x08, 0xBA, 0x60, 0xC7, 0x2A, - 0xEC, 0x0C, 0x28, 0xEC, 0x6B, 0xFE, 0xCA, 0x4B, - 0x2E, 0xC4, 0xC4, 0x6F, 0x22, 0xBF, 0x62, 0x1A, - 0x5D, 0x74, 0xF7, 0x5C, 0x0D, 0x29, 0x69, 0x3E, - 0x56, 0xC5, 0xC5, 0x84, 0xF4, 0x39, 0x9E, 0x94, - 0x2F, 0x3B, 0xD8, 0xD3, 0x86, 0x13, 0xE6, 0x39 - }, - { - 0xD5, 0xB4, 0x66, 0xFF, 0x1F, 0xD6, 0x8C, 0xFA, - 0x8E, 0xDF, 0x0B, 0x68, 0x02, 0x44, 0x8F, 0x30, - 0x2D, 0xCC, 0xDA, 0xF5, 0x66, 0x28, 0x78, 0x6B, - 0x9D, 0xA0, 0xF6, 0x62, 0xFD, 0xA6, 0x90, 0x26, - 0x6B, 0xD4, 0x0A, 0xB6, 0xF0, 0xBE, 0xC0, 0x43, - 0xF1, 0x01, 0x28, 0xB3, 0x3D, 0x05, 0xDB, 0x82, - 0xD4, 0xAB, 0x26, 0x8A, 0x4F, 0x91, 0xAC, 0x42, - 0x86, 0x79, 0x5F, 0xC0, 0xF7, 0xCB, 0x48, 0x5C - }, - { - 0x0A, 0x1E, 0x8C, 0x0A, 0x8C, 0x48, 0xB8, 0x4B, - 0x71, 0xBA, 0x0F, 0xE5, 0x6F, 0xA0, 0x56, 0x09, - 0x8C, 0xA6, 0x92, 0xE9, 0x2F, 0x27, 0x6E, 0x85, - 0xB3, 0x38, 0x26, 0xCD, 0x78, 0x75, 0xFC, 0xF8, - 0x83, 0x85, 0x13, 0x1B, 0x43, 0xDF, 0x74, 0x53, - 0x2E, 0xAA, 0x86, 0xCF, 0x17, 0x1F, 0x50, 0x76, - 0xE6, 0xD1, 0x7B, 0x1C, 0x75, 0xFB, 0xA1, 0xDB, - 0x00, 0x1B, 0x6E, 0x66, 0x97, 0x7C, 0xB8, 0xD7 - }, - { - 0x65, 0xAA, 0x17, 0x99, 0x14, 0x36, 0x93, 0xAB, - 0xD9, 0xCB, 0x21, 0x8D, 0x9B, 0x5E, 0xC6, 0x0C, - 0x0E, 0xDD, 0xB0, 0x67, 0xE6, 0xA3, 0x2F, 0x76, - 0x79, 0x60, 0x10, 0xAC, 0xB1, 0x1A, 0xD0, 0x13, - 0x6C, 0xE4, 0x9F, 0x97, 0x6E, 0x74, 0xF8, 0x95, - 0x04, 0x2F, 0x7C, 0xBF, 0x13, 0xFB, 0x73, 0xD1, - 0x9D, 0xC8, 0x89, 0xD7, 0xE9, 0x03, 0x46, 0x9D, - 0xEB, 0x33, 0x73, 0x1F, 0x24, 0x06, 0xB6, 0x63 - }, - { - 0xDE, 0xB7, 0x12, 0xB9, 0xCC, 0x64, 0xF5, 0x88, - 0x14, 0x86, 0x0B, 0x51, 0xFA, 0x89, 0xAD, 0x8A, - 0x92, 0x6A, 0x69, 0x08, 0xC7, 0x96, 0xDE, 0x55, - 0x7F, 0x90, 0xCF, 0xAD, 0xB0, 0xC6, 0x2C, 0x07, - 0x87, 0x2F, 0x33, 0xFE, 0x18, 0x4E, 0x5E, 0x21, - 0x2A, 0x3C, 0x5C, 0x37, 0x31, 0x74, 0x18, 0x44, - 0x6E, 0xFD, 0x95, 0x61, 0x3F, 0x61, 0x8A, 0x35, - 0xF7, 0xD2, 0x78, 0x9E, 0xFE, 0x0D, 0x96, 0x60 - }, - { - 0xB4, 0x2F, 0x4A, 0x40, 0xB3, 0xC8, 0x8B, 0xCE, - 0xCF, 0xE3, 0x28, 0xC8, 0x46, 0xBF, 0x06, 0x48, - 0xA1, 0x69, 0x90, 0xCA, 0x53, 0x91, 0x95, 0xC0, - 0xC1, 0xDC, 0x8D, 0x70, 0x30, 0x80, 0x67, 0x68, - 0x5A, 0xF6, 0x77, 0xAD, 0x65, 0xAC, 0x0C, 0x7A, - 0x9B, 0xCF, 0xA8, 0xF7, 0xAC, 0xC0, 0xAA, 0xCF, - 0x45, 0xCA, 0x18, 0xAC, 0x83, 0x1F, 0xED, 0x64, - 0x4E, 0xC3, 0xD9, 0x28, 0x31, 0x01, 0xFF, 0xEF - }, - { - 0xED, 0xCF, 0x6C, 0x81, 0xCC, 0xF1, 0x6E, 0x11, - 0xDD, 0xF7, 0x19, 0xA3, 0x3D, 0xD0, 0xE5, 0x34, - 0x9C, 0xAB, 0xAC, 0x5C, 0xFA, 0xE5, 0x97, 0x00, - 0x98, 0x40, 0xE1, 0xC3, 0x93, 0x62, 0xC0, 0xF1, - 0x19, 0x82, 0xFE, 0x2C, 0x27, 0x65, 0x85, 0x9A, - 0x94, 0x26, 0x2D, 0xA2, 0x8D, 0xD3, 0x37, 0x3D, - 0x52, 0x26, 0x93, 0x89, 0x75, 0x11, 0xEB, 0xA5, - 0xE0, 0x7B, 0x8B, 0xC6, 0xB6, 0x06, 0x4D, 0xC0 - }, - { - 0x46, 0xB9, 0x62, 0xD2, 0x28, 0x36, 0x94, 0xD2, - 0x79, 0x75, 0xDC, 0xBF, 0x32, 0x56, 0x4C, 0x9B, - 0x04, 0x03, 0x2B, 0x30, 0xA9, 0x3E, 0x05, 0x8F, - 0xB7, 0x7B, 0x2B, 0x71, 0x8B, 0x4A, 0xD5, 0xFB, - 0x78, 0x9A, 0xB7, 0xD7, 0xAA, 0x90, 0x85, 0x2D, - 0xA2, 0xBF, 0xB6, 0xB3, 0x93, 0xB0, 0x9F, 0x98, - 0xE8, 0x69, 0xB1, 0x6E, 0x41, 0x0E, 0x7D, 0xE2, - 0x30, 0xB1, 0x79, 0xF6, 0x2E, 0xB5, 0x74, 0x71 - }, - { - 0x29, 0x03, 0x6C, 0x3F, 0x53, 0x82, 0xE3, 0x5D, - 0xE7, 0xA6, 0x9F, 0xA7, 0xA6, 0x3E, 0xC7, 0xBD, - 0xCB, 0xC4, 0xE0, 0xCC, 0x5A, 0x7B, 0x64, 0x14, - 0xCF, 0x44, 0xBF, 0x9A, 0x83, 0x83, 0xEF, 0xB5, - 0x97, 0x23, 0x50, 0x6F, 0x0D, 0x51, 0xAD, 0x50, - 0xAC, 0x1E, 0xAC, 0xF7, 0x04, 0x30, 0x8E, 0x8A, - 0xEC, 0xB9, 0x66, 0xF6, 0xAC, 0x94, 0x1D, 0xB1, - 0xCD, 0xE4, 0xB5, 0x9E, 0x84, 0xC1, 0xEB, 0xBA - }, - { - 0x17, 0x3F, 0x8A, 0xB8, 0x93, 0x3E, 0xB0, 0x7C, - 0xC5, 0xFD, 0x6E, 0x4B, 0xCE, 0xBA, 0xE1, 0xFF, - 0x35, 0xC7, 0x87, 0x9B, 0x93, 0x8A, 0x5A, 0x15, - 0x79, 0xEA, 0x02, 0xF3, 0x83, 0x32, 0x48, 0x86, - 0xC7, 0x0E, 0xD9, 0x10, 0x9D, 0xE1, 0x69, 0x0B, - 0x8E, 0xE8, 0x01, 0xBC, 0x95, 0x9B, 0x21, 0xD3, - 0x81, 0x17, 0xEB, 0xB8, 0x4A, 0xB5, 0x6F, 0x88, - 0xF8, 0xA3, 0x72, 0x62, 0x00, 0x2D, 0xD9, 0x8E - }, - { - 0xC6, 0xAF, 0xA6, 0xA1, 0x91, 0x93, 0x1F, 0xD4, - 0x5C, 0x3B, 0xAD, 0xBA, 0x72, 0x6E, 0x68, 0xA9, - 0xBC, 0x73, 0x88, 0xC8, 0xCF, 0x37, 0xAD, 0xEC, - 0x7C, 0x64, 0x56, 0x1C, 0xF4, 0x81, 0xFD, 0x25, - 0x9A, 0x64, 0x6C, 0x8B, 0xD8, 0x43, 0xE7, 0x70, - 0x9E, 0x11, 0xE6, 0x4D, 0xCF, 0xD5, 0xDF, 0xFF, - 0xED, 0x79, 0x23, 0x5C, 0x68, 0x9B, 0x42, 0x00, - 0xFE, 0x7A, 0xC8, 0xDF, 0xDA, 0xDD, 0xEC, 0xE0 - }, - { - 0xA6, 0xDC, 0xCD, 0x8C, 0x19, 0x26, 0x64, 0x88, - 0xBF, 0x77, 0xB9, 0xF2, 0x4B, 0x91, 0x43, 0xDE, - 0xF1, 0xFE, 0xD6, 0x1D, 0x0C, 0x60, 0xB5, 0x00, - 0x0A, 0x52, 0x3F, 0x45, 0x0D, 0xA2, 0x3D, 0x74, - 0xE4, 0xE3, 0xF6, 0xEF, 0x04, 0x09, 0x0D, 0x10, - 0x66, 0xB6, 0xAC, 0xE8, 0x5A, 0xBC, 0x0F, 0x03, - 0x01, 0x73, 0xF5, 0x28, 0x17, 0x72, 0x7C, 0x4E, - 0x40, 0x43, 0x2D, 0xD3, 0x4C, 0x6E, 0xF9, 0xF0 - }, - { - 0xAA, 0xF8, 0x90, 0x8D, 0x54, 0x6E, 0x4F, 0x1E, - 0x31, 0x4C, 0x00, 0xE9, 0xD2, 0xE8, 0x85, 0x5C, - 0xB2, 0x56, 0x44, 0x5A, 0xAE, 0x3E, 0xCA, 0x44, - 0x23, 0x83, 0x22, 0xAE, 0xC7, 0x40, 0x34, 0xA1, - 0x45, 0x8A, 0x29, 0x36, 0x75, 0xDA, 0xD9, 0x49, - 0x40, 0x8D, 0xE5, 0x55, 0x4F, 0x22, 0xD7, 0x34, - 0x54, 0xF3, 0xF0, 0x70, 0x9C, 0xBC, 0xCC, 0x85, - 0xCB, 0x05, 0x3A, 0x6F, 0x50, 0x38, 0x91, 0xA1 - }, - { - 0x52, 0x5F, 0x4A, 0xAB, 0x9C, 0x32, 0x7D, 0x2A, - 0x6A, 0x3C, 0x9D, 0xF8, 0x1F, 0xB7, 0xBE, 0x97, - 0xEE, 0x03, 0xE3, 0xF7, 0xCE, 0x33, 0x21, 0x1C, - 0x47, 0x78, 0x8A, 0xCD, 0x13, 0x46, 0x40, 0xDD, - 0x90, 0xAD, 0x74, 0x99, 0x2D, 0x3D, 0xD6, 0xAC, - 0x80, 0x63, 0x50, 0xF3, 0xBA, 0xBC, 0x7F, 0xE1, - 0x98, 0xA6, 0x1D, 0xB3, 0x2D, 0x4A, 0xD1, 0xD6, - 0x56, 0x9A, 0xE8, 0x41, 0x31, 0x04, 0xDE, 0xA4 - }, - { - 0x2D, 0xAC, 0xCD, 0x88, 0x71, 0x9D, 0x0A, 0x00, - 0xB5, 0x2C, 0x6E, 0xB7, 0x9E, 0x1C, 0xA8, 0xB4, - 0xA1, 0xB4, 0xB4, 0x4F, 0xFA, 0x20, 0x88, 0x9F, - 0x23, 0x63, 0xEF, 0x5C, 0x0D, 0x73, 0x7F, 0x1F, - 0x81, 0xF5, 0x0D, 0xA1, 0xCA, 0xAC, 0x23, 0x1D, - 0x6F, 0xCB, 0x48, 0x89, 0x5E, 0x72, 0x99, 0xB7, - 0x7A, 0xF8, 0x1F, 0x0A, 0xA4, 0xA7, 0x61, 0x8A, - 0xD2, 0x4B, 0x7A, 0xAF, 0xC8, 0xE3, 0xA2, 0xBE - }, - { - 0x7D, 0x28, 0x6F, 0x1F, 0x72, 0x1E, 0xC2, 0xD2, - 0x11, 0x5E, 0xF4, 0xCC, 0xD8, 0x28, 0x58, 0xA4, - 0xD5, 0x12, 0x21, 0x13, 0x55, 0xD4, 0xFC, 0x58, - 0xE5, 0x34, 0xBF, 0xA5, 0x9C, 0x2E, 0x1B, 0xF5, - 0x52, 0xA9, 0x6D, 0xC4, 0xB3, 0xE4, 0x6B, 0x01, - 0x28, 0x65, 0xDA, 0x88, 0x13, 0x4C, 0xF0, 0x4E, - 0x73, 0x1B, 0x19, 0x30, 0x75, 0x9E, 0x15, 0x8F, - 0xF6, 0x20, 0xB6, 0xEC, 0x5A, 0xAF, 0xD0, 0x12 - }, - { - 0x21, 0x82, 0x6B, 0x95, 0x29, 0xC4, 0xBC, 0x51, - 0x91, 0x47, 0xF5, 0xF9, 0xFE, 0x6D, 0xB8, 0x78, - 0x34, 0x52, 0x15, 0xE5, 0x09, 0x4F, 0x4E, 0x99, - 0xB1, 0x31, 0xED, 0x54, 0xE2, 0x49, 0x53, 0xCE, - 0xE9, 0xAD, 0xB7, 0x18, 0xD1, 0x74, 0x3E, 0x6C, - 0x27, 0xFC, 0x94, 0x51, 0x6A, 0x99, 0x22, 0xFB, - 0x97, 0x5A, 0x78, 0x16, 0xB8, 0xAA, 0xB0, 0x21, - 0x12, 0x60, 0x8C, 0x03, 0x2B, 0xF1, 0x38, 0xE3 - }, - { - 0xC1, 0x68, 0x9C, 0x69, 0x8A, 0xB0, 0x65, 0xF6, - 0x2E, 0xEE, 0x65, 0xDD, 0xCA, 0x67, 0x6B, 0xAA, - 0x45, 0xB5, 0x2F, 0x30, 0x8A, 0xFA, 0x80, 0x4A, - 0xB4, 0xAA, 0x6A, 0xB8, 0x4B, 0x7A, 0xC1, 0xAA, - 0x1D, 0xFF, 0x07, 0x17, 0x56, 0x10, 0xB1, 0x2A, - 0xE1, 0x1F, 0x27, 0xB7, 0xC4, 0x30, 0xAF, 0xD5, - 0x75, 0x56, 0xBD, 0x18, 0x1D, 0x02, 0x83, 0x2C, - 0xD8, 0xD0, 0xA5, 0xFD, 0xC3, 0x02, 0x01, 0x24 - }, - { - 0xA1, 0xA6, 0x28, 0x17, 0x47, 0xE3, 0x4D, 0x3E, - 0xDE, 0x5E, 0x93, 0x34, 0x01, 0x74, 0x7C, 0xA7, - 0xF7, 0x66, 0x28, 0xB6, 0x14, 0xC8, 0xA3, 0x94, - 0xF5, 0x02, 0x56, 0x2B, 0xFE, 0xE0, 0xB9, 0x94, - 0xEC, 0xB6, 0x5F, 0xBF, 0xE1, 0xFF, 0x70, 0x67, - 0xDC, 0xB0, 0x1D, 0x02, 0xA9, 0x2B, 0xA4, 0x62, - 0x20, 0x75, 0x87, 0xCE, 0xF7, 0xDC, 0x2C, 0xFD, - 0xB4, 0x58, 0x48, 0x48, 0xAD, 0x55, 0x91, 0x4A - }, - { - 0x00, 0x70, 0xA0, 0x19, 0x0A, 0xA6, 0x96, 0x57, - 0x2D, 0x85, 0x3F, 0x1D, 0x24, 0xAB, 0x63, 0x08, - 0x48, 0xAC, 0x56, 0xAD, 0x5C, 0x2E, 0xBF, 0xCF, - 0xDE, 0x27, 0xD1, 0x11, 0xCD, 0x55, 0x93, 0x9C, - 0x1E, 0x4D, 0x07, 0x87, 0x2D, 0xDE, 0x7C, 0xE7, - 0x8B, 0x53, 0x4B, 0x53, 0x0F, 0x0A, 0x39, 0x6E, - 0x86, 0xAF, 0x9D, 0x57, 0x53, 0x54, 0xB5, 0xD7, - 0xE3, 0x4A, 0xCD, 0xE1, 0x8C, 0xC7, 0x67, 0xAE - }, - { - 0x51, 0xB9, 0xB5, 0xED, 0x19, 0x3F, 0xD4, 0xB1, - 0xA3, 0xA9, 0x2B, 0x46, 0xBD, 0x4B, 0xD1, 0xF6, - 0xEC, 0x6B, 0x38, 0xA6, 0x0F, 0x2D, 0x02, 0x61, - 0xD7, 0x2A, 0xBF, 0xD1, 0x64, 0x36, 0x12, 0x8D, - 0xCB, 0xF2, 0x2C, 0x25, 0xE3, 0xE3, 0xC4, 0x3F, - 0xE4, 0xD2, 0x9D, 0xB9, 0x12, 0x4D, 0x03, 0x33, - 0x30, 0x18, 0x45, 0x92, 0xD2, 0x0C, 0x5B, 0x08, - 0x2C, 0x23, 0x20, 0x64, 0x54, 0xCB, 0x3D, 0xD7 - }, - { - 0x57, 0x8F, 0x24, 0x27, 0x46, 0x91, 0x4E, 0x36, - 0xD0, 0xD9, 0xD4, 0x80, 0x96, 0x89, 0x57, 0x12, - 0x16, 0xA4, 0x3E, 0x47, 0x33, 0x32, 0x39, 0x51, - 0x62, 0x0F, 0x5E, 0xE7, 0x8C, 0xCF, 0xEE, 0x91, - 0x9B, 0xF5, 0x5F, 0x28, 0x7B, 0x45, 0xA7, 0x3D, - 0x44, 0x85, 0xAC, 0x74, 0x22, 0x87, 0x92, 0x39, - 0x65, 0x3B, 0x05, 0x91, 0xC3, 0x6C, 0x86, 0x69, - 0x41, 0xF8, 0xAF, 0xFE, 0x4A, 0xE5, 0x6E, 0x9E - }, - { - 0x94, 0x71, 0x30, 0xEF, 0x0B, 0x94, 0x8E, 0xE0, - 0x45, 0x81, 0xAB, 0xA3, 0xE2, 0xCC, 0x4C, 0xEF, - 0xC3, 0x8C, 0xCE, 0xDC, 0x86, 0x17, 0x92, 0xB7, - 0xB5, 0xDC, 0xD9, 0xD9, 0x36, 0x1C, 0x72, 0x4A, - 0x12, 0x20, 0x03, 0xBF, 0x79, 0x6C, 0xE0, 0x97, - 0x98, 0x00, 0xAD, 0xAB, 0xC7, 0x45, 0x6F, 0x17, - 0x3A, 0xE5, 0x26, 0x93, 0x15, 0xAF, 0xC0, 0x1B, - 0x60, 0x6D, 0xB2, 0x9C, 0x75, 0x50, 0xE8, 0xCA - }, - { - 0xC8, 0x52, 0xE6, 0x77, 0xF7, 0x7B, 0x14, 0xB5, - 0x85, 0xBD, 0x10, 0x2A, 0x0F, 0x14, 0x42, 0x43, - 0x05, 0x9D, 0xAB, 0xEC, 0x7C, 0xB0, 0x1F, 0xFA, - 0x61, 0xDF, 0x19, 0xFC, 0xE8, 0xAB, 0x43, 0x6B, - 0xF5, 0xE2, 0xD5, 0xC7, 0x9A, 0xA2, 0xD7, 0xB6, - 0x77, 0xF6, 0xC3, 0x75, 0xE9, 0x34, 0x3D, 0x34, - 0x2E, 0x4F, 0xF4, 0xE3, 0xAB, 0x00, 0x1B, 0xC7, - 0x98, 0x8C, 0x3C, 0x7A, 0x83, 0xCC, 0xB6, 0x9F - }, - { - 0x01, 0x19, 0x75, 0x26, 0x91, 0x7A, 0xC2, 0xC7, - 0xBC, 0x53, 0x95, 0x19, 0xE6, 0x8B, 0xB2, 0x79, - 0x81, 0x35, 0xF6, 0x03, 0x3E, 0xD5, 0x8F, 0x5C, - 0x45, 0x1E, 0x0C, 0xE9, 0x46, 0xAF, 0xF0, 0xF9, - 0x8D, 0xFD, 0xD1, 0x51, 0x01, 0x73, 0x1A, 0xC1, - 0x66, 0x12, 0x6E, 0xAF, 0xB5, 0xE7, 0xCB, 0xE2, - 0xE2, 0x72, 0xEE, 0x23, 0x3F, 0x34, 0xE5, 0xF3, - 0xF8, 0xEA, 0x3D, 0x2D, 0x12, 0x24, 0x82, 0xFB - }, - { - 0x05, 0x9C, 0x90, 0x85, 0x89, 0x5E, 0xB7, 0x18, - 0x30, 0x4E, 0x2D, 0xDA, 0x78, 0x68, 0x6B, 0xD9, - 0x57, 0x49, 0x81, 0x5A, 0x5E, 0xE9, 0x02, 0x51, - 0x0B, 0x00, 0x9A, 0xF6, 0x92, 0x48, 0xB6, 0xA7, - 0xA7, 0x2F, 0xF8, 0xA6, 0x28, 0xD8, 0x17, 0x73, - 0xE1, 0x1D, 0x5A, 0x1E, 0x7F, 0x69, 0x7A, 0x44, - 0x9B, 0x7A, 0x1E, 0x27, 0x12, 0xD5, 0xCF, 0xAE, - 0x7A, 0xB2, 0x65, 0x07, 0xD1, 0x11, 0x29, 0x18 - }, - { - 0x29, 0x52, 0x43, 0xBD, 0x75, 0x8C, 0xF2, 0x1C, - 0x80, 0x31, 0x25, 0xFC, 0xF3, 0x21, 0xDE, 0x5F, - 0x97, 0x98, 0x7C, 0x8D, 0xB3, 0xBB, 0x3C, 0xB5, - 0x1F, 0xF9, 0x7C, 0x4C, 0xDA, 0xC9, 0xD3, 0xBF, - 0x0A, 0x67, 0xCE, 0xE7, 0xED, 0x35, 0x0A, 0x41, - 0xFD, 0xE6, 0xAB, 0xCC, 0x25, 0x4F, 0xBC, 0x9F, - 0x8E, 0x6B, 0x3E, 0x3C, 0xCE, 0xCB, 0xD0, 0xE4, - 0xA6, 0x40, 0xA2, 0x0F, 0x36, 0x2B, 0xA3, 0xA0 - }, - { - 0xDD, 0x82, 0x32, 0xD2, 0x41, 0x2C, 0xCE, 0xEC, - 0xB5, 0x12, 0x31, 0x91, 0xF6, 0xE9, 0x22, 0x1E, - 0x85, 0x1E, 0xCC, 0xE0, 0xFA, 0xEB, 0xF0, 0x50, - 0x5F, 0x2A, 0xEE, 0xFF, 0x8A, 0x8C, 0x92, 0xD4, - 0x1D, 0xAC, 0xF1, 0x77, 0xBD, 0xAE, 0x27, 0x76, - 0x3E, 0xA4, 0xA8, 0x62, 0x05, 0xEF, 0x76, 0x34, - 0xF7, 0xA6, 0x87, 0xCC, 0x44, 0xBB, 0xBB, 0xDE, - 0xEE, 0x5E, 0x11, 0xE6, 0x5F, 0x9F, 0xBD, 0x69 - }, - { - 0xB0, 0x46, 0xB6, 0x83, 0x71, 0x6D, 0x31, 0xC9, - 0x14, 0xC7, 0x0B, 0x10, 0xF7, 0x64, 0x6D, 0xA3, - 0x1E, 0xFA, 0xB2, 0x23, 0x63, 0x47, 0x45, 0x9C, - 0xF8, 0xFA, 0x2C, 0x09, 0x12, 0x34, 0x31, 0xF7, - 0x28, 0x07, 0xF1, 0x1D, 0x86, 0x7C, 0x37, 0x70, - 0xB1, 0xF0, 0x61, 0xD5, 0x6C, 0xA0, 0xE5, 0xB1, - 0xE8, 0x8A, 0x6B, 0x44, 0xA3, 0x3C, 0xF9, 0x3E, - 0x18, 0xBC, 0xC9, 0xCE, 0xBB, 0xA5, 0xAD, 0xE7 - }, - { - 0x20, 0xE5, 0xA2, 0x55, 0x05, 0x8B, 0xE5, 0x1E, - 0x1A, 0x62, 0x9B, 0x4E, 0xBF, 0x81, 0xE5, 0xCB, - 0xE0, 0x78, 0x1C, 0xB6, 0x7C, 0xA4, 0xE5, 0x7B, - 0xA8, 0x6B, 0x30, 0x88, 0x96, 0xBC, 0xE7, 0x38, - 0x20, 0xEB, 0x08, 0x43, 0x1C, 0xE8, 0xC9, 0xBC, - 0x58, 0x10, 0xCC, 0x8D, 0x8B, 0x9C, 0x9D, 0x6F, - 0xCF, 0x83, 0x4E, 0x42, 0xEA, 0x33, 0xEF, 0x73, - 0xCE, 0xC4, 0x7D, 0x71, 0x3B, 0x6D, 0x8D, 0xFD - }, - { - 0x1E, 0x48, 0x04, 0xF9, 0xC0, 0xB1, 0xE8, 0x2B, - 0x9E, 0xD3, 0x63, 0xBD, 0xE4, 0x47, 0x28, 0xAC, - 0xF7, 0xD0, 0x90, 0xA1, 0xBF, 0xE2, 0xDD, 0xF8, - 0x81, 0x9D, 0x65, 0x92, 0xEF, 0x45, 0x3B, 0x83, - 0x5B, 0xD2, 0xEF, 0xE8, 0xB0, 0x20, 0x6E, 0x29, - 0x25, 0x5B, 0x07, 0xFB, 0x90, 0xC7, 0xD3, 0x0D, - 0x2C, 0x11, 0x48, 0x00, 0xB8, 0x6C, 0xB0, 0xE3, - 0xE0, 0x7D, 0x38, 0x7E, 0x98, 0xCE, 0x95, 0x37 - }, - { - 0x41, 0xC9, 0x53, 0xD8, 0xD2, 0x2A, 0x86, 0xC3, - 0x63, 0x4D, 0xF4, 0x22, 0xB6, 0xDE, 0x4A, 0x4F, - 0x14, 0x96, 0x66, 0xBE, 0x8C, 0x4F, 0x58, 0x1B, - 0x26, 0x23, 0xEE, 0x65, 0xC3, 0x92, 0xA5, 0xC3, - 0x28, 0x36, 0x63, 0x9E, 0xF5, 0x6B, 0x93, 0x68, - 0x62, 0x20, 0xF4, 0x5C, 0xE6, 0x5B, 0x4F, 0xA8, - 0x58, 0x9C, 0x91, 0x25, 0x64, 0x17, 0x90, 0xB6, - 0x92, 0x5F, 0xAA, 0xD9, 0x48, 0xB8, 0xBE, 0x04 - }, - { - 0x8B, 0xFC, 0xA4, 0xC8, 0xDF, 0xE3, 0xFD, 0xE4, - 0x25, 0x7B, 0x75, 0xC3, 0xDB, 0x01, 0x86, 0x2E, - 0xD3, 0x11, 0x67, 0xDE, 0x66, 0xC2, 0xE0, 0x3A, - 0x25, 0x56, 0xC4, 0xF4, 0x6C, 0x9D, 0xFF, 0xC1, - 0xAC, 0x45, 0xF7, 0xBC, 0x59, 0xA6, 0x7A, 0xB9, - 0x36, 0x24, 0xBE, 0xB8, 0x6D, 0xDD, 0x0D, 0x02, - 0x60, 0x3F, 0x0D, 0xCD, 0x03, 0x64, 0xF0, 0xF8, - 0x08, 0x81, 0x9B, 0xE9, 0x6C, 0xD8, 0xD3, 0xB6 - }, - { - 0xF6, 0xBF, 0x59, 0xD8, 0xD4, 0x5A, 0x55, 0x71, - 0x11, 0xA2, 0x36, 0xCB, 0xBA, 0x52, 0x61, 0x9A, - 0xE3, 0xDF, 0xCC, 0x43, 0x16, 0x94, 0x38, 0x43, - 0xAF, 0xD1, 0x28, 0x1B, 0x28, 0x21, 0x4A, 0x4A, - 0x5E, 0x85, 0x1E, 0xF8, 0xC5, 0x4F, 0x50, 0x5E, - 0x3C, 0x4B, 0x60, 0x0E, 0xFF, 0xBE, 0xBB, 0x3E, - 0xAC, 0x17, 0x08, 0x7F, 0x22, 0x27, 0x58, 0x12, - 0x63, 0xF1, 0x7D, 0x7E, 0x5F, 0x68, 0xEA, 0x83 - }, - { - 0x1B, 0xC9, 0xED, 0xE4, 0xD4, 0x1A, 0x4D, 0xF6, - 0xE8, 0xE6, 0xF4, 0x7C, 0x2F, 0x4A, 0xD8, 0x73, - 0x37, 0xB6, 0x9B, 0x19, 0xF7, 0x10, 0xF7, 0x66, - 0xE1, 0xFA, 0xF5, 0xAA, 0x05, 0xA4, 0x3B, 0x66, - 0x45, 0x39, 0x6E, 0x7F, 0xBE, 0xF4, 0x3B, 0xB7, - 0x79, 0x5D, 0x39, 0x40, 0x7B, 0x58, 0x15, 0xB9, - 0x2E, 0xCC, 0x23, 0xA6, 0xC1, 0x24, 0x14, 0x21, - 0x15, 0x3A, 0x55, 0xD5, 0x1F, 0x12, 0xBF, 0xD8 - }, - { - 0x76, 0xB3, 0x8B, 0x36, 0x31, 0x55, 0x5D, 0xBC, - 0xFB, 0x21, 0x21, 0x8F, 0xF9, 0xE4, 0x12, 0xA2, - 0x29, 0x88, 0x9E, 0xF2, 0xCE, 0x8A, 0xD7, 0x05, - 0xE9, 0x0F, 0x96, 0xAA, 0xBB, 0xD5, 0xBE, 0x7E, - 0x53, 0x29, 0xA4, 0x26, 0x53, 0x4C, 0x81, 0x5A, - 0x56, 0x53, 0x77, 0x13, 0x18, 0x72, 0x66, 0x41, - 0x42, 0x4E, 0x3B, 0x88, 0x29, 0x2F, 0xB1, 0xD8, - 0x95, 0x44, 0x40, 0x6A, 0xDE, 0x9B, 0xCC, 0xB5 - }, - { - 0xE5, 0x3F, 0x60, 0x07, 0x40, 0x22, 0x4E, 0x4D, - 0x10, 0xD3, 0x1D, 0x24, 0x38, 0x00, 0x31, 0x43, - 0xAF, 0xDB, 0x43, 0x6E, 0xB1, 0x79, 0x1B, 0x15, - 0x0D, 0xE3, 0x56, 0x76, 0xF0, 0xE3, 0x2F, 0x80, - 0xB0, 0xB6, 0x5F, 0x0A, 0xCF, 0x48, 0x1A, 0x5F, - 0xBF, 0x95, 0x96, 0xC0, 0xCB, 0x0A, 0x27, 0xC7, - 0xAF, 0xC1, 0x1D, 0x1E, 0x2C, 0x4D, 0x54, 0x02, - 0x47, 0x5E, 0x4F, 0xFC, 0xC1, 0xCD, 0xA8, 0x11 - }, - { - 0x62, 0x06, 0xB9, 0x1F, 0xC0, 0xB6, 0xF1, 0x21, - 0x1E, 0x9F, 0xDE, 0xCD, 0xC9, 0xD5, 0x1A, 0x6F, - 0x1E, 0xEE, 0x65, 0x54, 0xB1, 0x38, 0xAD, 0xCD, - 0x4A, 0x82, 0x3D, 0xF0, 0x0D, 0xDE, 0xF6, 0x75, - 0x9A, 0x9B, 0xFD, 0x7A, 0x4E, 0x98, 0x1E, 0x04, - 0x52, 0x36, 0x83, 0x8F, 0x4A, 0xF6, 0x93, 0xF6, - 0x93, 0x77, 0x93, 0x14, 0x84, 0xB3, 0xE8, 0x1E, - 0x3E, 0x3B, 0xC2, 0xCB, 0x7E, 0xF7, 0x9F, 0xE9 - }, - { - 0x76, 0xFD, 0x02, 0xDA, 0xDD, 0x96, 0x3B, 0xC0, - 0x35, 0x39, 0x91, 0x46, 0xCE, 0x42, 0x98, 0x8C, - 0xC0, 0x99, 0xD3, 0xCF, 0x4D, 0x32, 0xDF, 0x5C, - 0x0B, 0xBF, 0x64, 0x10, 0x12, 0x46, 0xB1, 0xC7, - 0x08, 0xD1, 0x67, 0xE2, 0x95, 0x95, 0xD1, 0x1D, - 0x09, 0xB3, 0xF6, 0x34, 0x86, 0xB4, 0x05, 0x26, - 0xAC, 0x1D, 0xFE, 0x31, 0xBC, 0x22, 0xDE, 0xC7, - 0x0B, 0x74, 0x5E, 0x90, 0xE2, 0xEA, 0xAF, 0x5A - }, - { - 0xF0, 0xA1, 0xFB, 0xE3, 0x11, 0x63, 0xE4, 0x21, - 0x01, 0x50, 0x72, 0x18, 0x3D, 0x68, 0xEE, 0x51, - 0x91, 0xA9, 0x9C, 0xFD, 0xA1, 0x69, 0xBA, 0x5A, - 0x19, 0x54, 0xC9, 0xF3, 0x10, 0x7D, 0x4E, 0xCA, - 0x06, 0x3E, 0x13, 0x7A, 0x71, 0x14, 0xD3, 0x97, - 0xC9, 0xDB, 0x67, 0x2B, 0x9F, 0x47, 0x8D, 0x41, - 0xC3, 0x4E, 0x99, 0x1B, 0x06, 0x69, 0xA9, 0x51, - 0x53, 0x92, 0x90, 0xC8, 0xED, 0x65, 0xE4, 0x6A - }, - { - 0x13, 0xC7, 0x2A, 0x6A, 0xA5, 0x71, 0xB1, 0x43, - 0xDC, 0xCF, 0x45, 0xAD, 0xCD, 0x98, 0xEA, 0xE6, - 0x99, 0xA1, 0x54, 0xB1, 0x10, 0xF2, 0x5E, 0x7E, - 0x9E, 0x82, 0xB7, 0x65, 0xB9, 0xA0, 0x89, 0x23, - 0x68, 0x8E, 0x8E, 0x0F, 0xF3, 0x11, 0xA6, 0x8A, - 0x77, 0x1E, 0x14, 0x50, 0x96, 0xD6, 0x07, 0x76, - 0xC6, 0xD6, 0xEE, 0x70, 0xAD, 0x6F, 0x69, 0xFA, - 0x2B, 0x76, 0x77, 0x63, 0x40, 0x55, 0xA0, 0x0E - }, - { - 0x0E, 0x06, 0x2B, 0xFE, 0x81, 0x8E, 0xE1, 0x0F, - 0x33, 0x48, 0x1D, 0xEA, 0x43, 0x02, 0x8B, 0x2C, - 0xFB, 0xB4, 0x9E, 0xC9, 0x5E, 0x0F, 0x75, 0xA9, - 0xE1, 0x6D, 0x40, 0x4B, 0xC5, 0x19, 0xB9, 0xAD, - 0x50, 0xB4, 0xA7, 0x33, 0x69, 0x2C, 0xA5, 0x4E, - 0xFB, 0x68, 0x04, 0x69, 0xED, 0x83, 0xDD, 0xEF, - 0xBD, 0xDD, 0xB1, 0x39, 0x04, 0x2E, 0x0E, 0x1C, - 0x09, 0xC3, 0xEB, 0x79, 0x03, 0xFA, 0x08, 0xDF - }, - { - 0x45, 0x3B, 0xE4, 0xAA, 0xB9, 0xF4, 0x23, 0xB3, - 0x36, 0x52, 0xA0, 0xB5, 0xD0, 0x2A, 0x9A, 0xF8, - 0x55, 0xDD, 0x0D, 0x42, 0xDD, 0x83, 0x11, 0x0B, - 0xA3, 0xBC, 0x4B, 0x39, 0x94, 0xEA, 0x3F, 0x88, - 0x5A, 0x71, 0x30, 0x89, 0x75, 0x08, 0x9B, 0x49, - 0x03, 0xE2, 0xE4, 0xD6, 0xBA, 0x6D, 0xC2, 0xE8, - 0x40, 0x31, 0xFF, 0xE9, 0xC8, 0x56, 0x39, 0x75, - 0xC8, 0x61, 0x6A, 0xCA, 0x07, 0x42, 0xE8, 0x29 - }, - { - 0x53, 0x61, 0xE3, 0xE8, 0x93, 0xDD, 0x36, 0x0B, - 0xCB, 0xF5, 0x1C, 0x79, 0x3E, 0xC0, 0x92, 0xA6, - 0xB0, 0x52, 0x05, 0x4F, 0x5F, 0x00, 0x0B, 0x9F, - 0xCE, 0x50, 0x7B, 0x66, 0x45, 0xF8, 0xD4, 0x70, - 0x13, 0xA8, 0x70, 0x6A, 0x58, 0xD4, 0xB1, 0x06, - 0x29, 0xCC, 0x82, 0xB8, 0xD2, 0xD7, 0x96, 0xFD, - 0xD3, 0x7B, 0x60, 0x8A, 0x58, 0x79, 0x52, 0xD6, - 0x55, 0x3E, 0x01, 0xD1, 0xAF, 0x0E, 0x04, 0xB8 - }, - { - 0x74, 0xB5, 0x67, 0x39, 0xF0, 0x1F, 0x82, 0x09, - 0xA4, 0x04, 0x44, 0xDF, 0x4C, 0xCD, 0xEE, 0xEA, - 0x8F, 0x97, 0xE8, 0xE7, 0x6E, 0xFA, 0x3C, 0x04, - 0x33, 0x7F, 0x69, 0x94, 0x5C, 0x4D, 0x44, 0xC0, - 0x85, 0xF1, 0xF4, 0x78, 0x96, 0x96, 0x36, 0x1E, - 0x3C, 0x97, 0x77, 0x4A, 0x93, 0x5F, 0x86, 0x0D, - 0x67, 0x46, 0x86, 0xDC, 0xBA, 0x3D, 0x45, 0xEC, - 0xD8, 0x63, 0x9A, 0x64, 0xAE, 0xA0, 0x62, 0x1B - }, - { - 0xB4, 0xD3, 0x15, 0x87, 0xB9, 0x2B, 0x53, 0x61, - 0xCD, 0xC2, 0xD3, 0xC4, 0x10, 0x86, 0xC1, 0x55, - 0x3E, 0x7B, 0x55, 0xA1, 0xF6, 0x1E, 0x94, 0xD2, - 0xBC, 0x30, 0xBC, 0x25, 0x1D, 0xAF, 0x8A, 0x5E, - 0xBF, 0xC5, 0x07, 0x09, 0xCC, 0x04, 0xCB, 0xAF, - 0x4B, 0x3B, 0x4D, 0xA2, 0xD2, 0x6B, 0x81, 0x23, - 0x8F, 0xBA, 0x71, 0x8F, 0xA9, 0x17, 0x59, 0xB8, - 0x0B, 0xD3, 0x10, 0x3A, 0xEC, 0x11, 0xE0, 0x6F - }, - { - 0xAA, 0xF6, 0x12, 0x7F, 0x00, 0xA0, 0x3D, 0x96, - 0x40, 0x6B, 0x9F, 0xB4, 0xAC, 0x70, 0x16, 0x0D, - 0xB5, 0x22, 0x42, 0x9B, 0x5C, 0xD9, 0x4E, 0x7F, - 0xA0, 0x30, 0x3A, 0x74, 0x94, 0x78, 0xFE, 0x31, - 0x89, 0xC8, 0xEA, 0x23, 0x93, 0x0A, 0x66, 0x25, - 0x2A, 0x80, 0x26, 0x74, 0xDC, 0xAF, 0x77, 0x00, - 0x46, 0x82, 0x0D, 0xD9, 0x64, 0xC6, 0x6F, 0x0F, - 0x54, 0x75, 0x1A, 0x72, 0xF9, 0x7D, 0x9C, 0x35 - }, - { - 0x2C, 0x30, 0xD4, 0x8D, 0xF9, 0x98, 0x4E, 0x02, - 0xF7, 0x5A, 0x94, 0x54, 0x92, 0x17, 0x18, 0x4D, - 0xD0, 0x2A, 0xAD, 0x3B, 0x57, 0x68, 0x3D, 0x09, - 0xB5, 0xA8, 0xC2, 0xEF, 0x53, 0xA9, 0x6A, 0xFB, - 0x73, 0xFE, 0xB6, 0xF9, 0x14, 0xE2, 0xD8, 0x15, - 0xBB, 0x3B, 0x08, 0x65, 0x43, 0x32, 0xFC, 0xFE, - 0x79, 0xF8, 0x0E, 0xC5, 0xF0, 0x51, 0xDA, 0x10, - 0xD7, 0x21, 0x41, 0x3D, 0xDD, 0xE8, 0xFA, 0x60 - }, - { - 0x92, 0xE2, 0xC5, 0xF7, 0x5D, 0x0C, 0xEA, 0xFC, - 0x81, 0x8F, 0xA7, 0x93, 0x59, 0x39, 0xE4, 0x8B, - 0x91, 0x59, 0x41, 0xEF, 0x73, 0x4D, 0x75, 0x27, - 0x0E, 0xB3, 0x21, 0xBA, 0x20, 0x80, 0xEF, 0x6D, - 0x25, 0x5E, 0x90, 0xEF, 0x96, 0xC6, 0x4C, 0xFF, - 0x1D, 0x8C, 0x18, 0xF3, 0x3C, 0x2E, 0xAB, 0x10, - 0x7F, 0xEF, 0x53, 0xE0, 0xD8, 0xBB, 0x16, 0x05, - 0x16, 0x80, 0x74, 0x80, 0xFC, 0xBA, 0x53, 0x73 - }, - { - 0x6E, 0x03, 0xA9, 0x1E, 0x20, 0x44, 0x46, 0x27, - 0xE3, 0xD2, 0xE2, 0x22, 0x26, 0xCF, 0x47, 0x00, - 0x26, 0x69, 0x44, 0x34, 0xED, 0x64, 0x79, 0x82, - 0x8C, 0xB6, 0xDC, 0x8F, 0x27, 0x96, 0x0A, 0xEE, - 0xE2, 0xF4, 0xAB, 0x87, 0x2A, 0x5C, 0xA2, 0xF7, - 0xF6, 0x52, 0xF7, 0xDC, 0x77, 0xD5, 0xF9, 0x6D, - 0x85, 0x82, 0x8B, 0x8F, 0x9C, 0x2D, 0x6C, 0x23, - 0x9E, 0x79, 0x77, 0x24, 0xA1, 0x31, 0x31, 0xB1 - }, - { - 0xBA, 0x43, 0x2D, 0xB0, 0xA3, 0x31, 0xBB, 0x8C, - 0x39, 0xB1, 0x7B, 0xEE, 0x34, 0x46, 0x2B, 0x26, - 0xDD, 0xB7, 0xAD, 0x91, 0xB6, 0xC7, 0x5A, 0xEC, - 0x27, 0x65, 0xFB, 0xAE, 0x3A, 0x0E, 0x60, 0xEC, - 0x54, 0x6D, 0x45, 0xF8, 0xE5, 0x84, 0x37, 0xB9, - 0xD7, 0x7C, 0x3D, 0x2E, 0x8D, 0x7C, 0xE0, 0x69, - 0x73, 0x15, 0x66, 0x51, 0xD4, 0x08, 0x22, 0x2A, - 0xA2, 0x90, 0xCB, 0x58, 0xCA, 0xBC, 0x0A, 0xE5 - }, - { - 0x83, 0xA0, 0x1E, 0x23, 0xAB, 0x27, 0x7B, 0x1F, - 0xC2, 0x8C, 0xD8, 0xBB, 0x8D, 0xA7, 0xE9, 0x4C, - 0x70, 0xF1, 0xDE, 0xE3, 0x2D, 0x19, 0x55, 0xCE, - 0xE2, 0x50, 0xEE, 0x58, 0x41, 0x9A, 0x1F, 0xEE, - 0x10, 0xA8, 0x99, 0x17, 0x97, 0xCE, 0x3D, 0x20, - 0x93, 0x80, 0xCA, 0x9F, 0x98, 0x93, 0x39, 0xE2, - 0xD8, 0xA8, 0x1C, 0x67, 0xD7, 0x37, 0xD8, 0x28, - 0x8C, 0x7F, 0xAE, 0x46, 0x02, 0x83, 0x4A, 0x8B - }, - { - 0x0E, 0xA3, 0x21, 0x72, 0xCC, 0x19, 0x1D, 0xFC, - 0x13, 0x1C, 0xD8, 0x8A, 0xA0, 0x3F, 0xF4, 0x18, - 0x5C, 0x0B, 0xFA, 0x7B, 0x19, 0x11, 0x12, 0x19, - 0xEE, 0xCB, 0x45, 0xB0, 0xFF, 0x60, 0x4D, 0x3E, - 0xDB, 0x00, 0x55, 0x0A, 0xBB, 0xA1, 0x11, 0x52, - 0x2B, 0x77, 0xAE, 0x61, 0xC9, 0xA8, 0xD6, 0xE9, - 0x4F, 0xCA, 0x9D, 0x96, 0xC3, 0x8D, 0x6B, 0x7C, - 0xCE, 0x27, 0x52, 0xF0, 0xD0, 0xC3, 0x7E, 0x78 - }, - { - 0x54, 0xAD, 0xD6, 0x55, 0x2B, 0x08, 0x85, 0x8B, - 0x23, 0xD6, 0x64, 0x5F, 0x6C, 0xE7, 0x9E, 0x92, - 0xF3, 0x8B, 0x66, 0xAE, 0x91, 0x86, 0x77, 0xE6, - 0xD9, 0x1F, 0x71, 0x87, 0xC4, 0x16, 0x05, 0x24, - 0xDF, 0xA8, 0xD0, 0x1F, 0x00, 0xEA, 0x93, 0xDD, - 0x29, 0x9F, 0x3C, 0xC4, 0x09, 0x01, 0xBD, 0x33, - 0x27, 0xA0, 0xF1, 0x8C, 0xCD, 0x7B, 0x6B, 0x8E, - 0x4E, 0x47, 0xCD, 0x28, 0xCF, 0x83, 0x8F, 0xAB - }, - { - 0xEF, 0x84, 0x74, 0x6D, 0xC2, 0x01, 0x56, 0xB6, - 0x6B, 0xA5, 0xC7, 0x8A, 0x50, 0x83, 0x0A, 0xBD, - 0x2A, 0xEF, 0x90, 0xE6, 0x67, 0xB9, 0x7E, 0xB5, - 0x22, 0x91, 0xBC, 0x86, 0x9D, 0x8A, 0xA2, 0x45, - 0x59, 0xA1, 0x42, 0xC6, 0x8F, 0xEA, 0x2E, 0xF3, - 0x2A, 0xF2, 0x2D, 0xFC, 0xEA, 0x4C, 0x90, 0xB3, - 0xD4, 0x90, 0x8C, 0xC9, 0xEA, 0x5C, 0xFC, 0x4E, - 0x91, 0xBF, 0x11, 0xCE, 0x6A, 0x7E, 0x57, 0x61 - }, - { - 0x5A, 0x1B, 0xF3, 0x81, 0xA0, 0x41, 0x19, 0xF9, - 0x42, 0xE4, 0x63, 0xAB, 0xA2, 0xB1, 0x64, 0x38, - 0x82, 0x46, 0x8A, 0xEC, 0xC1, 0xB1, 0xAA, 0x1E, - 0x7B, 0xCA, 0xAB, 0x3B, 0x47, 0x8F, 0xC5, 0xF0, - 0x56, 0xF1, 0x0D, 0xA9, 0x03, 0x7D, 0x40, 0xFA, - 0x7F, 0x55, 0x70, 0x8E, 0x10, 0x3B, 0xDA, 0x96, - 0x5E, 0x92, 0x0C, 0xF6, 0x7C, 0xE3, 0xAD, 0xF7, - 0xE2, 0x00, 0xE8, 0x61, 0x01, 0x4D, 0xEC, 0xC6 - }, - { - 0xAC, 0xF7, 0x8A, 0xA3, 0x28, 0x45, 0x96, 0xF3, - 0x30, 0xB7, 0xE8, 0x47, 0x51, 0xB9, 0x4C, 0x31, - 0x4C, 0xD8, 0x36, 0x36, 0x27, 0xBA, 0x99, 0x78, - 0x81, 0x30, 0x85, 0x78, 0x87, 0x37, 0x59, 0x89, - 0x5D, 0x13, 0xDF, 0xFF, 0xA5, 0xE5, 0x74, 0x50, - 0x13, 0x61, 0xF0, 0x43, 0xC7, 0x4F, 0x57, 0xD2, - 0xD0, 0xF1, 0x5C, 0x7A, 0x41, 0xC7, 0xC4, 0x5E, - 0x3C, 0x09, 0xAD, 0x89, 0xD6, 0x99, 0xA9, 0x77 - }, - { - 0x18, 0xB3, 0xE9, 0x04, 0x38, 0x44, 0xD4, 0xF3, - 0xA2, 0xD0, 0x21, 0xF5, 0x4C, 0x38, 0xFA, 0xCC, - 0x36, 0x4F, 0x84, 0xBA, 0x10, 0x58, 0xF2, 0x10, - 0x09, 0xFC, 0x37, 0x1D, 0x2E, 0x4F, 0x38, 0xC7, - 0x27, 0x51, 0x8A, 0xAB, 0xA6, 0xA2, 0x9E, 0x0F, - 0xDA, 0xE6, 0xE7, 0x60, 0xA4, 0xF1, 0xA6, 0xD7, - 0x58, 0xEB, 0xE4, 0x2C, 0x2A, 0xFC, 0x9D, 0x2C, - 0xDC, 0x6D, 0xD5, 0x80, 0x77, 0x8C, 0x4B, 0x32 - }, - { - 0x18, 0x96, 0xB2, 0x31, 0x70, 0x33, 0xCF, 0x31, - 0x04, 0x68, 0x73, 0xD8, 0x7F, 0x26, 0xE6, 0xA4, - 0x2A, 0x9D, 0x77, 0x0B, 0xBA, 0xF6, 0xE0, 0x62, - 0xDF, 0x11, 0xF9, 0xB4, 0xA0, 0xEA, 0xB2, 0x75, - 0xAA, 0xB1, 0x2C, 0xAA, 0xC2, 0xD3, 0xF5, 0x29, - 0xEB, 0x20, 0xD0, 0x70, 0xFD, 0x84, 0x4D, 0x86, - 0xD0, 0xA5, 0x71, 0xCD, 0xF6, 0x28, 0x5F, 0x80, - 0xE2, 0x30, 0x8B, 0xB8, 0x2C, 0x6C, 0x5B, 0x3B - }, - { - 0x8C, 0x3D, 0xC4, 0x01, 0x94, 0xAA, 0x02, 0x1F, - 0x3C, 0x4A, 0x1F, 0x9A, 0x05, 0x5E, 0x4D, 0x41, - 0x9E, 0xB3, 0xA2, 0x6D, 0x4C, 0x2F, 0x1A, 0x8C, - 0x7E, 0x18, 0x8B, 0x73, 0x48, 0x13, 0x40, 0x80, - 0xB6, 0x3F, 0x6E, 0x57, 0x0A, 0xD1, 0x1C, 0x28, - 0x78, 0x66, 0x53, 0x55, 0x41, 0x9C, 0x10, 0x20, - 0xDE, 0x4B, 0x65, 0x5E, 0x7A, 0x6C, 0x2C, 0xCD, - 0xE9, 0x07, 0x2C, 0xD4, 0x27, 0xFE, 0x8C, 0x4E - }, - { - 0x70, 0xAE, 0x04, 0x30, 0xD5, 0x45, 0xEC, 0x42, - 0x7F, 0x85, 0x41, 0x21, 0x1D, 0x4F, 0xE0, 0x42, - 0xB9, 0x82, 0x3A, 0xCE, 0xC0, 0x4B, 0x15, 0xC9, - 0x0B, 0x7F, 0x4B, 0x8B, 0xDD, 0x3D, 0xC7, 0x85, - 0x19, 0x90, 0xF3, 0x70, 0xE7, 0x14, 0x16, 0x75, - 0x10, 0x66, 0x49, 0xD3, 0x91, 0x51, 0x09, 0x03, - 0x18, 0x23, 0x1E, 0x4D, 0xED, 0x51, 0x22, 0x5D, - 0x9A, 0x6F, 0xA6, 0xC4, 0x24, 0x69, 0x5D, 0xE2 - }, - { - 0x07, 0x33, 0x6C, 0x42, 0xBD, 0x51, 0x49, 0x0E, - 0xF8, 0x4D, 0xFB, 0xDF, 0xAB, 0x74, 0x66, 0xF6, - 0xB6, 0x39, 0x99, 0xA5, 0xC0, 0x88, 0x72, 0xDF, - 0xED, 0xA0, 0x20, 0x6F, 0xDA, 0x80, 0xB9, 0xA6, - 0x2D, 0xE7, 0x28, 0xE3, 0xE3, 0xC3, 0xFD, 0x6B, - 0x7D, 0x21, 0xA4, 0x38, 0xAA, 0xD1, 0xB8, 0xDD, - 0x22, 0x38, 0x63, 0xC0, 0xD2, 0x6A, 0xCA, 0x27, - 0x79, 0x01, 0x74, 0xD9, 0xD4, 0x42, 0xA6, 0x4C - }, - { - 0x79, 0x26, 0x70, 0x88, 0x59, 0xE6, 0xE2, 0xAB, - 0x68, 0xF6, 0x04, 0xDA, 0x69, 0xA9, 0xFB, 0x50, - 0x87, 0xBB, 0x33, 0xF4, 0xE8, 0xD8, 0x95, 0x73, - 0x0E, 0x30, 0x1A, 0xB2, 0xD7, 0xDF, 0x74, 0x8B, - 0x67, 0xDF, 0x0B, 0x6B, 0x86, 0x22, 0xE5, 0x2D, - 0xD5, 0x7D, 0x8D, 0x3A, 0xD8, 0x7D, 0x58, 0x20, - 0xD4, 0xEC, 0xFD, 0x24, 0x17, 0x8B, 0x2D, 0x2B, - 0x78, 0xD6, 0x4F, 0x4F, 0xBD, 0x38, 0x75, 0x82 - }, - { - 0x92, 0x80, 0xF4, 0xD1, 0x15, 0x70, 0x32, 0xAB, - 0x31, 0x5C, 0x10, 0x0D, 0x63, 0x62, 0x83, 0xFB, - 0xF4, 0xFB, 0xA2, 0xFB, 0xAD, 0x0F, 0x8B, 0xC0, - 0x20, 0x72, 0x1D, 0x76, 0xBC, 0x1C, 0x89, 0x73, - 0xCE, 0xD2, 0x88, 0x71, 0xCC, 0x90, 0x7D, 0xAB, - 0x60, 0xE5, 0x97, 0x56, 0x98, 0x7B, 0x0E, 0x0F, - 0x86, 0x7F, 0xA2, 0xFE, 0x9D, 0x90, 0x41, 0xF2, - 0xC9, 0x61, 0x80, 0x74, 0xE4, 0x4F, 0xE5, 0xE9 - }, - { - 0x55, 0x30, 0xC2, 0xD5, 0x9F, 0x14, 0x48, 0x72, - 0xE9, 0x87, 0xE4, 0xE2, 0x58, 0xA7, 0xD8, 0xC3, - 0x8C, 0xE8, 0x44, 0xE2, 0xCC, 0x2E, 0xED, 0x94, - 0x0F, 0xFC, 0x68, 0x3B, 0x49, 0x88, 0x15, 0xE5, - 0x3A, 0xDB, 0x1F, 0xAA, 0xF5, 0x68, 0x94, 0x61, - 0x22, 0x80, 0x5A, 0xC3, 0xB8, 0xE2, 0xFE, 0xD4, - 0x35, 0xFE, 0xD6, 0x16, 0x2E, 0x76, 0xF5, 0x64, - 0xE5, 0x86, 0xBA, 0x46, 0x44, 0x24, 0xE8, 0x85 - }, - { - 0xDA, 0x85, 0x0A, 0x2F, 0x54, 0xE9, 0x44, 0x89, - 0x17, 0xD0, 0xDC, 0xAA, 0x63, 0x93, 0x7B, 0x95, - 0xA4, 0xDA, 0x1E, 0xAC, 0x8A, 0xF4, 0xDD, 0xF2, - 0x11, 0x3E, 0x5C, 0x8B, 0x0D, 0x4D, 0xB2, 0x66, - 0x9A, 0xF3, 0xC2, 0xAC, 0xB0, 0x80, 0x3D, 0x05, - 0x32, 0x3F, 0x3E, 0xC5, 0x5A, 0xBD, 0x33, 0xBD, - 0xF9, 0xB2, 0xBE, 0x89, 0x0E, 0xE7, 0x9E, 0x7F, - 0x3F, 0xCE, 0x4E, 0x19, 0x86, 0x96, 0xA7, 0xA3 - }, - { - 0xF1, 0x60, 0x95, 0xDD, 0x9F, 0x1E, 0xEB, 0x77, - 0xD5, 0xB9, 0x2F, 0x4B, 0x1F, 0xAC, 0x3A, 0x2C, - 0x5D, 0xA6, 0xAE, 0x5D, 0x0A, 0xB3, 0xF2, 0x54, - 0xE2, 0xA7, 0xFE, 0x52, 0x67, 0x24, 0x11, 0xD0, - 0x1C, 0xFA, 0x6A, 0xC0, 0x5B, 0xF3, 0x9E, 0xF6, - 0x5F, 0x4B, 0x22, 0x26, 0x4B, 0x41, 0xC3, 0xF3, - 0x63, 0x56, 0x3A, 0xBF, 0x0E, 0x92, 0x42, 0x90, - 0xC1, 0xC6, 0x80, 0xB1, 0x8A, 0xA6, 0x5B, 0x44 - }, - { - 0x76, 0xD0, 0x0A, 0x09, 0xC5, 0xBD, 0xD3, 0x9E, - 0xD3, 0x28, 0x71, 0x72, 0x2C, 0xFA, 0x00, 0x47, - 0x67, 0x4B, 0xEC, 0x8D, 0x35, 0x17, 0x5A, 0xF9, - 0x0D, 0x7A, 0xE9, 0x10, 0x74, 0x40, 0xA2, 0xA0, - 0x63, 0x88, 0x56, 0xD8, 0x38, 0x4C, 0x81, 0x7D, - 0x77, 0x2A, 0x4A, 0x59, 0x7A, 0x89, 0x55, 0x49, - 0xC8, 0x48, 0x66, 0x37, 0x56, 0x31, 0xCB, 0xA0, - 0x42, 0xF0, 0xEF, 0x6F, 0xFE, 0xB8, 0x9D, 0x44 - }, - { - 0xA6, 0x51, 0x13, 0x7B, 0x2C, 0x47, 0xFB, 0x79, - 0x51, 0xE7, 0xBD, 0xA7, 0x15, 0x43, 0xA6, 0xEB, - 0xC6, 0x24, 0x2A, 0xCA, 0xB4, 0x34, 0x7D, 0x38, - 0x8B, 0xE8, 0x35, 0x0F, 0x0C, 0x3F, 0xA3, 0xDF, - 0x8D, 0x95, 0x2C, 0x7C, 0x8A, 0x3D, 0xAF, 0x01, - 0xE0, 0x6C, 0x1D, 0xA6, 0x94, 0x96, 0xBB, 0xA8, - 0xDE, 0x62, 0xD8, 0x6B, 0x50, 0x93, 0x25, 0x6F, - 0x77, 0xA1, 0x87, 0xB5, 0x3D, 0xB0, 0x39, 0x88 - }, - { - 0xF3, 0x2F, 0x15, 0x0C, 0x2D, 0x67, 0xC0, 0xC4, - 0x37, 0x40, 0x1B, 0x70, 0xF6, 0x0B, 0x38, 0xF0, - 0xA3, 0xA4, 0x70, 0x59, 0x03, 0x3E, 0x75, 0x05, - 0xE6, 0x9A, 0x1D, 0x30, 0x12, 0x96, 0x03, 0x0B, - 0xC9, 0xB2, 0x95, 0x19, 0xC7, 0xF8, 0xB7, 0xD5, - 0x9A, 0x71, 0xFA, 0xB9, 0x05, 0x57, 0xDC, 0x3D, - 0xC8, 0x23, 0xFA, 0xC9, 0x5B, 0x9E, 0x85, 0xE6, - 0x52, 0x52, 0x8C, 0xBF, 0xB0, 0x1B, 0x11, 0x78 - }, - { - 0x27, 0x02, 0x56, 0x61, 0x36, 0xC4, 0x92, 0xF4, - 0x10, 0x89, 0xB0, 0x60, 0x10, 0x84, 0x60, 0xFA, - 0x30, 0x22, 0xC9, 0xC2, 0x5D, 0x34, 0x3B, 0xCB, - 0xD8, 0xAF, 0x2A, 0xF1, 0x9C, 0x17, 0xEF, 0x4C, - 0xA9, 0xF2, 0x22, 0x4F, 0xE7, 0xC4, 0x70, 0x0A, - 0x10, 0x19, 0x8E, 0xE5, 0x24, 0x8F, 0x30, 0x0B, - 0x54, 0x8E, 0xBF, 0x5C, 0x8E, 0x71, 0x16, 0x32, - 0x0C, 0xC8, 0x93, 0xFF, 0x7E, 0x23, 0x1F, 0xFB - }, - { - 0xFF, 0xE6, 0x87, 0x9F, 0x46, 0xB6, 0x29, 0x2B, - 0x21, 0x96, 0x97, 0x2E, 0x3F, 0xDF, 0x4F, 0xE9, - 0xEA, 0x4A, 0x81, 0x6D, 0x18, 0x07, 0xA3, 0x1C, - 0xAE, 0xAD, 0x6A, 0xAC, 0x5F, 0x06, 0x3C, 0x8F, - 0xE8, 0x77, 0x79, 0x75, 0x59, 0xA7, 0x59, 0xA0, - 0x0F, 0x8B, 0xA8, 0xF6, 0x68, 0xD8, 0x96, 0x8F, - 0xB3, 0x1D, 0x8A, 0x3B, 0x84, 0x57, 0x35, 0x90, - 0x2C, 0x5E, 0x42, 0xE2, 0x89, 0xEE, 0x0B, 0x62 - }, - { - 0x14, 0x48, 0x84, 0x28, 0x68, 0x22, 0xC2, 0x51, - 0x2D, 0x61, 0xB0, 0x46, 0xE6, 0x74, 0xD8, 0x6B, - 0x26, 0x4E, 0x9C, 0xC6, 0x89, 0x3E, 0xFF, 0x36, - 0x73, 0x11, 0x24, 0xF5, 0x9D, 0x1A, 0x82, 0x00, - 0x1E, 0x63, 0xF3, 0xE8, 0x05, 0x1C, 0xFE, 0x52, - 0xE7, 0x59, 0x7E, 0x28, 0x73, 0x8E, 0x3C, 0x3A, - 0x70, 0xF1, 0xBE, 0xD9, 0x68, 0x0E, 0x2C, 0x0E, - 0xF3, 0x72, 0x8B, 0x10, 0xA5, 0x6E, 0xD9, 0x87 - }, - { - 0x17, 0xC3, 0xF1, 0x46, 0xEE, 0x8D, 0xEC, 0x3B, - 0xAF, 0xCB, 0x51, 0xC0, 0xDA, 0x37, 0xF1, 0x78, - 0x71, 0xF2, 0x34, 0xC4, 0xA0, 0xFB, 0x7F, 0xA6, - 0xD0, 0x70, 0x7A, 0x54, 0x3E, 0x3C, 0xBF, 0x3A, - 0xDB, 0x81, 0xE3, 0x0C, 0x1E, 0x0A, 0xE9, 0xE1, - 0xAC, 0xE7, 0x22, 0x3B, 0xDA, 0x99, 0xBD, 0x59, - 0x19, 0xA3, 0xCF, 0xCC, 0x92, 0xC6, 0xA7, 0x55, - 0xE4, 0x56, 0xF0, 0x93, 0x82, 0x3B, 0xD3, 0x3E - }, - { - 0x1B, 0x83, 0x7A, 0xF2, 0x33, 0xA8, 0xA6, 0x8B, - 0xE7, 0x09, 0x52, 0xF7, 0x83, 0xC4, 0x96, 0x1A, - 0x81, 0x52, 0xD1, 0xE0, 0xB0, 0xFA, 0x32, 0x5F, - 0xF0, 0x86, 0xEA, 0x5B, 0x5F, 0x13, 0x12, 0xB8, - 0x9C, 0x42, 0xE0, 0x1B, 0x8C, 0x3A, 0x47, 0x7C, - 0xB5, 0x40, 0xC0, 0x6B, 0x2F, 0x37, 0xEE, 0x0E, - 0x39, 0x24, 0xD7, 0x45, 0xB4, 0xFF, 0x5C, 0x6A, - 0xF7, 0xD6, 0x1E, 0x0E, 0x37, 0xAC, 0x19, 0x31 - }, - { - 0x78, 0x97, 0x88, 0x0C, 0x1E, 0xB0, 0x0F, 0xD2, - 0x56, 0x7A, 0xE8, 0xA5, 0x9E, 0x64, 0x82, 0xAF, - 0xE1, 0x73, 0x49, 0xCF, 0x93, 0x92, 0x4A, 0x91, - 0x5F, 0x8C, 0x59, 0x26, 0x93, 0xD4, 0x52, 0x07, - 0x55, 0x19, 0x68, 0x9D, 0xFC, 0xD2, 0x93, 0xE3, - 0x76, 0x89, 0x7B, 0x3B, 0x0E, 0x03, 0x6F, 0x11, - 0x4F, 0xE8, 0x1E, 0xBC, 0xB3, 0x15, 0x36, 0x71, - 0xBD, 0x23, 0xBC, 0x2B, 0xED, 0x46, 0xF9, 0xC2 - }, - { - 0xCA, 0x7B, 0x6C, 0x77, 0x5D, 0x20, 0x1E, 0x5B, - 0x5A, 0x77, 0x22, 0x61, 0xDE, 0x52, 0x8E, 0x47, - 0x5F, 0x4B, 0xDE, 0x51, 0x76, 0x60, 0x52, 0x9F, - 0x41, 0xBE, 0xEB, 0x15, 0x78, 0xB2, 0x4B, 0xCB, - 0x94, 0xB9, 0x41, 0x0F, 0x9B, 0xF3, 0x36, 0xC1, - 0x09, 0xF9, 0xD4, 0x70, 0x93, 0xA1, 0x0B, 0xA6, - 0xDE, 0xBE, 0x50, 0x43, 0x80, 0xD9, 0xD1, 0x50, - 0x73, 0xBD, 0xD1, 0x11, 0xC8, 0xD1, 0x29, 0xFA - }, - { - 0x57, 0x18, 0xE0, 0xD4, 0x5D, 0xEB, 0xC3, 0x00, - 0x2D, 0x52, 0xB2, 0x2C, 0x52, 0x73, 0x29, 0xAE, - 0x5E, 0xBF, 0x27, 0xE8, 0xFA, 0x9C, 0x8F, 0xEA, - 0xB4, 0x6C, 0x40, 0xBC, 0x64, 0x22, 0xCA, 0x03, - 0x35, 0x30, 0x4C, 0xF9, 0xE7, 0xF1, 0x41, 0xDE, - 0x7F, 0xA6, 0xAD, 0xB6, 0x78, 0x9B, 0xDB, 0xF3, - 0x8D, 0x14, 0xDA, 0xBA, 0x3E, 0x62, 0x97, 0xD2, - 0x5B, 0xF1, 0x7D, 0xE1, 0x70, 0xD6, 0xE3, 0xC8 - }, - { - 0x48, 0xD0, 0xED, 0x24, 0x9F, 0x90, 0x28, 0x41, - 0x99, 0x7C, 0x25, 0x5D, 0xAF, 0x99, 0x08, 0x9C, - 0x9A, 0x31, 0x24, 0x69, 0x8B, 0x16, 0x4A, 0x30, - 0x28, 0x33, 0x0F, 0xDD, 0x4C, 0xEE, 0x41, 0xE1, - 0x68, 0x3F, 0xA4, 0xD9, 0xDC, 0x66, 0xB2, 0xA7, - 0x9C, 0x8A, 0xA4, 0xC8, 0x28, 0x4E, 0x27, 0xBE, - 0xE2, 0xA4, 0x28, 0xA6, 0x71, 0x9D, 0x6E, 0xC6, - 0x55, 0xED, 0x76, 0x9D, 0xCB, 0x62, 0x4E, 0x24 - }, - { - 0x79, 0x4E, 0x0B, 0x64, 0xAC, 0xE1, 0xFE, 0x5A, - 0xE3, 0x79, 0x93, 0x70, 0x68, 0xD8, 0x2D, 0xF0, - 0x48, 0x68, 0x61, 0x6C, 0xAE, 0x0C, 0x17, 0xD3, - 0x05, 0x72, 0xC2, 0x02, 0x4E, 0x77, 0x48, 0x94, - 0xE0, 0x66, 0x8C, 0x47, 0x2D, 0x62, 0x3C, 0x90, - 0x3C, 0xC5, 0x88, 0x5F, 0x17, 0x84, 0x94, 0x51, - 0x10, 0x32, 0x9E, 0xB4, 0x98, 0xA8, 0x95, 0xA9, - 0xE5, 0x9A, 0x75, 0xE5, 0x27, 0x15, 0x8A, 0x5C - }, - { - 0x21, 0x79, 0xAA, 0x82, 0x0E, 0x03, 0xFA, 0x33, - 0xD9, 0xBD, 0xE5, 0x56, 0x8C, 0x26, 0x2E, 0x2D, - 0x34, 0x17, 0xA4, 0x02, 0xE0, 0x7A, 0x59, 0x1F, - 0x9D, 0x55, 0x70, 0x68, 0x2D, 0xB5, 0xF9, 0xBB, - 0xA4, 0xBB, 0x9D, 0x5A, 0x82, 0xEE, 0x5E, 0xFD, - 0xB4, 0xF6, 0x5B, 0xBB, 0xFE, 0xEE, 0x2F, 0x4A, - 0xB9, 0xE4, 0x6C, 0xF2, 0xCE, 0x7E, 0x3B, 0x05, - 0x43, 0x27, 0xA7, 0x18, 0xD3, 0xF1, 0x08, 0x06 - }, - { - 0xB0, 0xA4, 0x8C, 0x6A, 0xDA, 0x54, 0x87, 0x25, - 0x79, 0x9B, 0x59, 0x86, 0xBA, 0xB4, 0x32, 0x69, - 0x79, 0x60, 0x92, 0x24, 0xD8, 0x97, 0x18, 0x4B, - 0x89, 0x97, 0x10, 0x4E, 0x0C, 0x6A, 0x24, 0xB3, - 0xAB, 0xE5, 0x62, 0x16, 0x54, 0x22, 0xA4, 0x5D, - 0x8A, 0xC8, 0x19, 0xB9, 0x9D, 0x37, 0x56, 0xEB, - 0xBB, 0x64, 0xF8, 0x43, 0xE3, 0xE0, 0x93, 0x4D, - 0xEC, 0x48, 0x7A, 0xED, 0x12, 0x13, 0x72, 0x79 - }, - { - 0x84, 0x8D, 0x7F, 0x2E, 0xAD, 0x41, 0x29, 0x1D, - 0x05, 0x38, 0x68, 0x0C, 0x64, 0x9D, 0x07, 0x89, - 0x7E, 0x45, 0xC7, 0x0A, 0x0A, 0xA4, 0xF9, 0x35, - 0x3F, 0x82, 0xC3, 0xF6, 0xFB, 0xB8, 0xE8, 0x48, - 0x9C, 0x75, 0x3E, 0x90, 0xDB, 0xE8, 0x89, 0x00, - 0x41, 0xA1, 0xAE, 0xEF, 0x84, 0xCD, 0x31, 0x36, - 0x43, 0x4F, 0x53, 0x0E, 0x9D, 0xD9, 0xC2, 0x3F, - 0xA5, 0x4F, 0xE1, 0x24, 0xEA, 0xFB, 0x72, 0xAD - }, - { - 0x0E, 0xD1, 0x46, 0x26, 0xEE, 0x6D, 0x0C, 0x8E, - 0xD3, 0xF0, 0xC2, 0x00, 0xC1, 0x29, 0x85, 0x0F, - 0xFF, 0x76, 0x31, 0x8F, 0xFF, 0xA1, 0xDD, 0xD7, - 0xDD, 0x56, 0x3A, 0x01, 0xB7, 0x77, 0x97, 0x06, - 0x86, 0x2B, 0x23, 0x99, 0x59, 0xB6, 0x15, 0xAE, - 0x2E, 0xBE, 0x27, 0xC4, 0x50, 0x37, 0xE6, 0xFF, - 0xAF, 0x99, 0x14, 0xDA, 0x8F, 0xF2, 0x77, 0x2B, - 0xA5, 0xEE, 0x08, 0x11, 0xCD, 0x9E, 0xD5, 0x32 - }, - { - 0x52, 0x03, 0xC0, 0x76, 0x38, 0xC4, 0xB6, 0x5F, - 0x78, 0x43, 0x1E, 0x8B, 0x02, 0xE2, 0x0F, 0x6D, - 0x68, 0x3F, 0x19, 0xFA, 0x8F, 0x83, 0xB5, 0x13, - 0x4C, 0xD0, 0xF4, 0xE4, 0x68, 0xC9, 0x7E, 0xAC, - 0xB5, 0x26, 0x7C, 0x7D, 0x3E, 0xAB, 0x58, 0x3C, - 0xCA, 0xAC, 0xD0, 0xDB, 0xA4, 0xD5, 0x8A, 0xCE, - 0x52, 0x19, 0x3A, 0x51, 0x78, 0xA7, 0xB1, 0x2D, - 0x27, 0x95, 0xF5, 0xFD, 0xE8, 0xA3, 0x7B, 0xB9 - }, - { - 0x48, 0xBE, 0x43, 0xD5, 0xE0, 0x04, 0x36, 0x88, - 0xDF, 0x35, 0x32, 0xF7, 0x12, 0x1A, 0xFF, 0xFA, - 0x16, 0x7D, 0xAB, 0xE4, 0xA4, 0x84, 0xFB, 0x75, - 0xA0, 0x3A, 0xF3, 0x04, 0xA5, 0xC6, 0xF8, 0x25, - 0xF3, 0x6C, 0xEC, 0xCB, 0xBB, 0xC0, 0x75, 0xEE, - 0xF3, 0x20, 0xC4, 0xCD, 0x8D, 0x7E, 0xF8, 0xCB, - 0x49, 0xE6, 0xDD, 0x59, 0x73, 0x37, 0x9E, 0xEC, - 0x4C, 0x23, 0x3C, 0x45, 0x43, 0xD1, 0x32, 0xCE - }, - { - 0xB5, 0x46, 0x4E, 0x6A, 0xBA, 0xF5, 0xD3, 0xD4, - 0x08, 0x3D, 0x1D, 0x7D, 0x2A, 0x8B, 0x0B, 0xAB, - 0x78, 0xB6, 0x17, 0x09, 0x50, 0x0B, 0xBF, 0x77, - 0x82, 0x3F, 0x60, 0x2D, 0x57, 0xD5, 0x13, 0xCA, - 0x9E, 0x9F, 0xFF, 0x65, 0xEF, 0xAA, 0x89, 0x9C, - 0xFE, 0x7B, 0xF8, 0x8A, 0x01, 0x88, 0x82, 0x9C, - 0x24, 0xE4, 0x98, 0xAD, 0x00, 0x23, 0x5A, 0xBE, - 0x8E, 0xEF, 0xA7, 0x19, 0xFA, 0x6A, 0xE6, 0xF6 - }, - { - 0xAF, 0xE5, 0xE5, 0xE8, 0x3F, 0x19, 0xAD, 0xAD, - 0x9E, 0x95, 0x90, 0x3E, 0xA9, 0xB2, 0x98, 0x10, - 0x7D, 0x37, 0xDD, 0x38, 0x63, 0x2C, 0x95, 0x90, - 0xBB, 0xFF, 0xC6, 0x24, 0xD4, 0xDE, 0x95, 0x8C, - 0xB6, 0xB6, 0x1A, 0xF0, 0x80, 0xF0, 0x37, 0xAD, - 0x17, 0xD0, 0x35, 0xB6, 0xBF, 0x58, 0xF7, 0x80, - 0xFA, 0xDF, 0x70, 0xF3, 0xC9, 0x59, 0x66, 0x8A, - 0x1B, 0x47, 0x21, 0x98, 0xA5, 0x9A, 0x8A, 0x00 - }, - { - 0xEF, 0xA2, 0xC7, 0xC8, 0x02, 0xE2, 0x10, 0xD2, - 0xD8, 0x0F, 0xB3, 0x50, 0xB3, 0xC2, 0xCB, 0x31, - 0x56, 0x13, 0x18, 0x11, 0xE7, 0x18, 0xEE, 0xE5, - 0xC9, 0xC6, 0x64, 0x0F, 0x87, 0x68, 0x2A, 0x55, - 0x81, 0x2B, 0x10, 0xF4, 0x03, 0x10, 0xBA, 0xA7, - 0xB8, 0x2B, 0x27, 0x3E, 0xF3, 0xAC, 0xC5, 0x5F, - 0xED, 0xE0, 0xB5, 0xF1, 0x94, 0x9D, 0xE4, 0x29, - 0x3D, 0x91, 0xB5, 0x89, 0xA2, 0x17, 0x5F, 0xF7 - }, - { - 0xD6, 0xC6, 0x2A, 0x61, 0x82, 0x71, 0xF3, 0xBC, - 0xBE, 0x00, 0x79, 0x24, 0xA0, 0xC9, 0x81, 0x2F, - 0x83, 0x17, 0x44, 0x5F, 0xB6, 0xFB, 0x19, 0xEB, - 0x58, 0x9A, 0x62, 0x9F, 0x51, 0x2F, 0xB3, 0x8A, - 0x0B, 0x4E, 0x24, 0x7D, 0xEA, 0x88, 0xC5, 0x6A, - 0x1B, 0xAF, 0x17, 0x88, 0x33, 0x65, 0xB4, 0x36, - 0xF2, 0x84, 0x46, 0xFF, 0x66, 0xEA, 0x43, 0x18, - 0x0B, 0xD0, 0x1E, 0xB5, 0xA6, 0x50, 0x9B, 0xD5 - }, - { - 0x0B, 0x41, 0x16, 0x6B, 0xE6, 0x2F, 0x65, 0xE1, - 0x93, 0xB3, 0xB8, 0x65, 0xE6, 0xC4, 0x7A, 0xAD, - 0x26, 0x0A, 0xF5, 0xFC, 0xEE, 0xC9, 0xAB, 0x44, - 0xAB, 0xAA, 0x46, 0x0A, 0x0C, 0x02, 0x46, 0xB6, - 0xC6, 0x9B, 0x67, 0xD7, 0x1D, 0x3A, 0xDF, 0xEC, - 0x60, 0xDC, 0x8E, 0x77, 0x37, 0x2F, 0x09, 0x49, - 0x52, 0x34, 0x4F, 0xE1, 0x0C, 0x0D, 0x59, 0xEF, - 0xEC, 0x0E, 0x11, 0xC4, 0xA5, 0x16, 0x93, 0x6D - }, - { - 0x79, 0xD5, 0xF9, 0xFF, 0xC0, 0x5E, 0xCF, 0x33, - 0x7D, 0xE9, 0xF1, 0xE0, 0xF1, 0xD8, 0x9B, 0x30, - 0xAC, 0xFE, 0xBB, 0xB8, 0x8A, 0x69, 0x35, 0x86, - 0x78, 0x18, 0xCD, 0x8D, 0x45, 0xDA, 0x3D, 0x25, - 0x18, 0xDE, 0x61, 0xA7, 0xFE, 0x28, 0x75, 0x1B, - 0x61, 0x8F, 0x7A, 0x87, 0x5E, 0x11, 0x89, 0x8F, - 0xFF, 0x74, 0x15, 0x7A, 0xB9, 0x06, 0x81, 0xBD, - 0x53, 0xFA, 0x69, 0x62, 0x67, 0x1E, 0xD9, 0x9D - }, - { - 0xBE, 0xA9, 0x83, 0xD7, 0x6F, 0x24, 0xB1, 0xEE, - 0xDE, 0x1D, 0x06, 0x71, 0x48, 0x05, 0x76, 0x8F, - 0xAA, 0xAD, 0x47, 0x08, 0xC9, 0xA4, 0xFF, 0x9C, - 0xD2, 0x42, 0x2F, 0x70, 0x6B, 0x6F, 0x0C, 0x30, - 0x6D, 0x8B, 0x67, 0xF3, 0x40, 0x89, 0xC6, 0x5E, - 0xD3, 0x88, 0x0C, 0x75, 0xF6, 0x7B, 0xBC, 0x4D, - 0x89, 0xAD, 0x87, 0x12, 0x0A, 0x77, 0xD0, 0xFF, - 0xE4, 0x36, 0xFB, 0x7B, 0x58, 0xB2, 0xCA, 0x41 - }, - { - 0x46, 0x6F, 0xD9, 0x15, 0xEF, 0xD9, 0x50, 0xBC, - 0x96, 0x65, 0x78, 0xCD, 0x92, 0xC6, 0x85, 0x92, - 0x9D, 0x7B, 0x51, 0xA6, 0x3D, 0xB1, 0x42, 0xC7, - 0xB9, 0xA9, 0x3D, 0x16, 0x52, 0x04, 0x95, 0x31, - 0x9B, 0x87, 0xF6, 0x58, 0xE6, 0xAF, 0xDA, 0x1B, - 0x42, 0x77, 0x3E, 0x2D, 0x49, 0xDA, 0x81, 0x45, - 0x94, 0xA5, 0x54, 0x90, 0x89, 0xEF, 0xB1, 0xF3, - 0xAB, 0x5F, 0x15, 0x90, 0xCA, 0x0A, 0x02, 0xAF - }, - { - 0xF6, 0x46, 0x11, 0x13, 0x7A, 0xD2, 0x95, 0x46, - 0x70, 0xEA, 0xEC, 0xD6, 0x26, 0xD2, 0x12, 0xCF, - 0xC5, 0xB9, 0xF6, 0xBB, 0x41, 0xAA, 0xEB, 0xB1, - 0xD7, 0x1E, 0x89, 0x79, 0x2E, 0xB1, 0x31, 0x7A, - 0xED, 0xC6, 0x38, 0x13, 0xFE, 0x63, 0xDE, 0x40, - 0x17, 0x98, 0xDF, 0x75, 0x6C, 0xA1, 0xF2, 0x20, - 0x35, 0xA0, 0xFA, 0xBD, 0x37, 0xFB, 0x11, 0x03, - 0x43, 0x7F, 0x89, 0x1E, 0xAD, 0x5E, 0x64, 0x29 - }, - { - 0x32, 0xE1, 0xF9, 0x38, 0xA2, 0x7F, 0xAA, 0xD8, - 0xAC, 0x4A, 0x13, 0xFD, 0x4F, 0x6A, 0x8B, 0xF3, - 0xDA, 0xBE, 0x4B, 0xC7, 0x2A, 0xF1, 0x1C, 0x8F, - 0x0E, 0x1A, 0x06, 0x56, 0x7E, 0xD7, 0x04, 0xB8, - 0xE7, 0x8E, 0x11, 0x40, 0xA0, 0xC7, 0x72, 0x4E, - 0x3E, 0xFB, 0x70, 0xD2, 0x38, 0x07, 0xCF, 0x38, - 0xE6, 0x27, 0xE3, 0x26, 0xAF, 0xC1, 0x64, 0xCD, - 0xED, 0x52, 0xB4, 0x41, 0x39, 0xFF, 0xB3, 0xF3 - }, - { - 0x48, 0x33, 0xAC, 0x92, 0xE3, 0x02, 0xAC, 0x2B, - 0x67, 0xB0, 0x2B, 0x88, 0x27, 0x14, 0x3B, 0xAD, - 0xA1, 0x5C, 0xED, 0x22, 0x0E, 0x1D, 0x1F, 0x5B, - 0x71, 0x12, 0x0C, 0x51, 0xEE, 0x54, 0xC1, 0x9D, - 0x30, 0x1F, 0x29, 0x60, 0xBD, 0xB5, 0xA2, 0xCE, - 0x27, 0xD4, 0x41, 0xD1, 0x4A, 0xF0, 0x80, 0xCB, - 0x01, 0x0A, 0x8A, 0x23, 0xEE, 0xFF, 0x58, 0x11, - 0xDF, 0xA4, 0x4D, 0x1D, 0x7B, 0x35, 0x8B, 0x48 - }, - { - 0x9A, 0x03, 0x88, 0xCE, 0xE1, 0xAD, 0x01, 0x46, - 0x17, 0x7C, 0x48, 0xB5, 0xA0, 0x8A, 0x2D, 0xB3, - 0xC4, 0x89, 0xE8, 0x4C, 0xE2, 0xAB, 0xA8, 0xC6, - 0x45, 0x11, 0x2A, 0x02, 0x1E, 0x41, 0x1C, 0xF8, - 0x29, 0x12, 0x7F, 0xA2, 0xF1, 0xD1, 0xAE, 0x1B, - 0xAF, 0x3A, 0x33, 0xEA, 0x53, 0x09, 0x84, 0x77, - 0xA7, 0xD1, 0x2B, 0xA7, 0x48, 0xD2, 0xAF, 0x24, - 0xD1, 0x66, 0x02, 0xE9, 0x19, 0x07, 0x76, 0x23 - }, - { - 0xE3, 0xDF, 0x00, 0x74, 0xA9, 0x37, 0x35, 0x13, - 0x0D, 0x99, 0x22, 0xD2, 0xBE, 0x91, 0x6F, 0x35, - 0x34, 0x3D, 0x98, 0x8C, 0xE5, 0x9D, 0x76, 0x97, - 0x15, 0xA9, 0x83, 0xB4, 0xBA, 0x80, 0x7C, 0xE1, - 0xEE, 0x70, 0xA3, 0x13, 0xE5, 0x92, 0x31, 0x58, - 0x4F, 0x55, 0x6E, 0xBB, 0xA1, 0xB9, 0x0B, 0x1B, - 0xB6, 0xA6, 0xC5, 0x81, 0xA4, 0xB4, 0x7C, 0x3F, - 0xF5, 0x21, 0x89, 0x65, 0x2A, 0xAB, 0x36, 0xF5 - }, - { - 0x91, 0x91, 0xCF, 0x46, 0x1B, 0x69, 0x59, 0xBE, - 0xC9, 0x3E, 0xAE, 0x7F, 0xB1, 0xC6, 0xE3, 0x70, - 0x73, 0xD1, 0xA6, 0x15, 0x27, 0xAD, 0x75, 0xD1, - 0x0B, 0x7F, 0x89, 0x49, 0xD9, 0xB8, 0xAF, 0x70, - 0xA2, 0x3A, 0xD1, 0x31, 0x2E, 0xD5, 0x1F, 0x70, - 0xF0, 0xE9, 0xDF, 0x60, 0x1D, 0xDA, 0xE2, 0x38, - 0x90, 0x6C, 0x0F, 0xE3, 0xF7, 0x66, 0xB1, 0x4F, - 0x11, 0x3B, 0x26, 0xBC, 0x85, 0x42, 0xD1, 0xD2 - }, - { - 0x2A, 0x8B, 0xAD, 0xE2, 0x72, 0xEE, 0x7A, 0xC6, - 0x43, 0xC5, 0xE3, 0x71, 0x47, 0xFA, 0xAC, 0x92, - 0xC3, 0x97, 0x0B, 0xD3, 0x86, 0x2F, 0x53, 0x1E, - 0x5D, 0xCE, 0xA5, 0xCE, 0xAC, 0xD1, 0x83, 0x74, - 0x53, 0xAA, 0x49, 0x8D, 0x78, 0x5B, 0x4D, 0x1F, - 0x89, 0xE1, 0xB2, 0xA7, 0x39, 0xCA, 0x4A, 0x38, - 0x49, 0x87, 0x30, 0x27, 0x46, 0xB4, 0xF1, 0x13, - 0x42, 0x43, 0x02, 0xC4, 0xA1, 0xE0, 0xF9, 0xDF - }, - { - 0x32, 0x3E, 0x67, 0x93, 0xC7, 0xDD, 0x9B, 0x4D, - 0x7B, 0xB7, 0xFB, 0xF2, 0x15, 0x31, 0xD3, 0x7F, - 0x72, 0x64, 0x53, 0x2C, 0x58, 0xF1, 0x22, 0x55, - 0x48, 0xD0, 0x6E, 0x69, 0x40, 0xC6, 0x3E, 0x91, - 0x27, 0x09, 0x90, 0xE7, 0xF5, 0x64, 0x32, 0x03, - 0xC9, 0x87, 0x64, 0x7E, 0x5C, 0xF6, 0x61, 0x03, - 0xE7, 0x9B, 0x71, 0x4C, 0x58, 0x1B, 0xD8, 0x77, - 0x2E, 0x19, 0xD0, 0xF0, 0x05, 0xDC, 0x86, 0x33 - }, - { - 0xF9, 0x22, 0x07, 0x6D, 0x29, 0x5D, 0x23, 0xE2, - 0x98, 0x58, 0x30, 0xAA, 0xD2, 0xF2, 0x3F, 0x65, - 0x2F, 0x7F, 0x4D, 0xB4, 0x2C, 0x11, 0x9E, 0xD2, - 0x20, 0xA5, 0x45, 0x14, 0x88, 0xA4, 0x53, 0xF5, - 0x9F, 0xA8, 0xA2, 0xDE, 0x23, 0x03, 0x00, 0x0D, - 0x6B, 0xFD, 0x8C, 0x48, 0x23, 0xA8, 0x5F, 0xAD, - 0xB4, 0xFB, 0x8E, 0x7E, 0xAC, 0x12, 0x2B, 0xF0, - 0x12, 0x47, 0xD7, 0x6F, 0x65, 0x24, 0x7D, 0x45 - }, - { - 0xDC, 0x40, 0x00, 0x95, 0x60, 0x95, 0x92, 0x91, - 0x55, 0x8E, 0xBE, 0x07, 0x20, 0x64, 0xCE, 0x67, - 0x12, 0xC9, 0x21, 0xB5, 0x40, 0x9B, 0x44, 0xE0, - 0x4F, 0x9A, 0x56, 0x5E, 0xEA, 0xDD, 0x39, 0xA7, - 0x71, 0x6E, 0x21, 0xB4, 0x6D, 0xD8, 0x61, 0x65, - 0x17, 0xA2, 0x1A, 0x0C, 0x03, 0x41, 0x9E, 0x94, - 0xDB, 0x82, 0x0A, 0x35, 0x3F, 0x15, 0x2D, 0x10, - 0x83, 0x84, 0xBE, 0x94, 0x70, 0x09, 0x3F, 0x89 - }, - { - 0x7F, 0xA4, 0xBE, 0x91, 0xCA, 0x52, 0x07, 0xFF, - 0x08, 0x7D, 0xE9, 0x2F, 0x1D, 0xB0, 0x9B, 0xF7, - 0x1A, 0x67, 0x87, 0x8B, 0xED, 0x19, 0x3A, 0x5C, - 0x2C, 0xC4, 0xE3, 0x53, 0x23, 0xB8, 0xDF, 0x99, - 0xA2, 0x6E, 0xCB, 0x98, 0x88, 0xD7, 0xB3, 0x4A, - 0x73, 0x9D, 0x64, 0x1A, 0x0E, 0xCD, 0x0A, 0x66, - 0x47, 0xA6, 0xA0, 0x64, 0x26, 0xF3, 0xCC, 0x1F, - 0xEF, 0xDF, 0x90, 0x69, 0x92, 0x2F, 0xAE, 0x4C - }, - { - 0xBA, 0xD3, 0xCD, 0x75, 0x90, 0x5D, 0x7B, 0xFD, - 0xA3, 0x32, 0x2B, 0x44, 0xA7, 0xD3, 0x58, 0x87, - 0x14, 0xD3, 0x33, 0xEE, 0x86, 0x85, 0x5A, 0x87, - 0x27, 0x47, 0xE7, 0x04, 0xF6, 0x11, 0x94, 0x84, - 0xBD, 0xB7, 0xD0, 0x77, 0xFA, 0x08, 0xED, 0xC4, - 0xA7, 0x9D, 0xE0, 0xF4, 0x3F, 0xCA, 0x8D, 0x43, - 0x6E, 0x8A, 0x10, 0x08, 0x57, 0xF5, 0x9B, 0xC7, - 0xB0, 0x55, 0xB9, 0x87, 0xF9, 0x7A, 0xC6, 0xB9 - }, - { - 0xB7, 0xDE, 0xE8, 0xE8, 0x33, 0x9D, 0xB2, 0x97, - 0xFD, 0xAA, 0x3C, 0xA5, 0xC1, 0xDC, 0x19, 0x88, - 0xD9, 0x7F, 0x5F, 0xB6, 0x20, 0x8C, 0x64, 0xDE, - 0xA9, 0x5E, 0x1C, 0x78, 0xF3, 0x37, 0xCE, 0x20, - 0xA2, 0xB4, 0xDF, 0x17, 0xA7, 0xB8, 0x23, 0x6A, - 0x90, 0xD6, 0x28, 0x67, 0x33, 0x16, 0x35, 0x72, - 0xC8, 0x67, 0xD9, 0x3D, 0xE8, 0x9E, 0xF6, 0x2F, - 0xA0, 0x5D, 0xAB, 0x70, 0x7E, 0xC3, 0xA7, 0x70 - }, - { - 0xA0, 0xF7, 0xE9, 0x3C, 0xF3, 0x25, 0x02, 0xB9, - 0xFD, 0x79, 0xEC, 0x20, 0x54, 0x62, 0x07, 0xF3, - 0x31, 0xC5, 0x29, 0x9E, 0xCE, 0xF3, 0x50, 0xD6, - 0x6E, 0xA8, 0x55, 0xC8, 0x7F, 0xBD, 0xDF, 0x18, - 0xE6, 0x91, 0xC2, 0x0D, 0x04, 0x5A, 0x30, 0x8F, - 0x83, 0xF6, 0xCB, 0x8F, 0xCA, 0x69, 0xD7, 0xE2, - 0xB3, 0x9B, 0x34, 0xD2, 0xF8, 0x77, 0x27, 0x6C, - 0x19, 0x6B, 0xF5, 0x14, 0xBA, 0xC6, 0x02, 0x70 - }, - { - 0x6F, 0x50, 0x93, 0xCF, 0xC8, 0x83, 0x00, 0xBF, - 0x68, 0x8E, 0x88, 0x4B, 0x4C, 0x5E, 0xC2, 0xC3, - 0x1A, 0x8C, 0xC2, 0x8D, 0x63, 0x31, 0xAD, 0x7C, - 0xA7, 0x1D, 0x97, 0x60, 0x21, 0x64, 0x82, 0x05, - 0x28, 0x15, 0xD4, 0x4F, 0xC6, 0x9E, 0x18, 0xA8, - 0xDC, 0x8B, 0xD7, 0x1B, 0x31, 0xF2, 0xB5, 0x89, - 0xA7, 0xC0, 0x78, 0x0B, 0x61, 0x99, 0x38, 0x5F, - 0x8D, 0xAE, 0x6C, 0x9B, 0x79, 0x74, 0xC4, 0xCB - }, - { - 0x3C, 0xFF, 0x46, 0xAC, 0x35, 0x46, 0xF6, 0x5A, - 0xD7, 0xA7, 0x20, 0x87, 0x1A, 0xFA, 0x20, 0xA9, - 0x21, 0x6D, 0xDA, 0x5C, 0x45, 0x18, 0x81, 0x56, - 0xA5, 0xBB, 0xED, 0xF2, 0x15, 0x46, 0xD4, 0xBB, - 0x39, 0x40, 0xB2, 0x1A, 0x41, 0xA3, 0x94, 0x03, - 0xE3, 0xCF, 0xD5, 0xE7, 0xA0, 0xE7, 0x90, 0x4D, - 0xA9, 0x5F, 0x4D, 0x8E, 0x0C, 0x5B, 0xF5, 0xB7, - 0x0E, 0xB0, 0x29, 0x55, 0x6E, 0xFD, 0x49, 0x7E - }, - { - 0xAF, 0x66, 0x8A, 0x80, 0x5E, 0x6D, 0x70, 0x4B, - 0x1E, 0x58, 0x1F, 0x1E, 0x8E, 0x3C, 0x00, 0xCF, - 0x4C, 0xF3, 0xE5, 0x46, 0x14, 0x7C, 0x40, 0x6D, - 0x17, 0xCA, 0x97, 0x4D, 0x19, 0xA0, 0x14, 0xC7, - 0x8B, 0x44, 0xE7, 0x2D, 0xDE, 0xEB, 0x65, 0x26, - 0x07, 0xE8, 0x6D, 0x69, 0x02, 0x59, 0xDC, 0xAB, - 0x0D, 0xDA, 0x81, 0xC7, 0x7C, 0x7E, 0xE2, 0x72, - 0x1E, 0x82, 0xBB, 0xB1, 0x39, 0x43, 0x07, 0x1D - }, - { - 0x79, 0xDD, 0xEB, 0x5C, 0x54, 0xDE, 0xD1, 0xE4, - 0x48, 0x40, 0x71, 0xC4, 0x6B, 0xB4, 0x28, 0x02, - 0xD2, 0x3B, 0x3A, 0x08, 0xC1, 0x23, 0x11, 0xBE, - 0x36, 0x3C, 0x7C, 0x7A, 0x02, 0x5A, 0x17, 0x64, - 0xC8, 0xD8, 0x50, 0x69, 0xFD, 0xA8, 0xD5, 0x17, - 0x77, 0x7D, 0x8D, 0xD8, 0x09, 0xE3, 0xD4, 0xA9, - 0x56, 0x04, 0x1A, 0x70, 0x79, 0xF9, 0x16, 0x7B, - 0x0F, 0xE9, 0x71, 0x2E, 0x5F, 0x12, 0x29, 0xF5 - }, - { - 0x99, 0x8E, 0x82, 0xF4, 0x26, 0x3D, 0x53, 0xAE, - 0xDA, 0xC9, 0x39, 0xEB, 0xB6, 0xEB, 0x8B, 0x19, - 0x69, 0x74, 0x6C, 0xB8, 0x15, 0xBD, 0x72, 0x1F, - 0x17, 0xA4, 0x8B, 0xEE, 0x9E, 0xCF, 0xF2, 0xFE, - 0x59, 0x8C, 0x53, 0x9C, 0x41, 0x9A, 0x60, 0xE0, - 0xD5, 0xA0, 0x4F, 0x1C, 0xB5, 0x23, 0xA2, 0xFD, - 0x05, 0x38, 0xBB, 0x17, 0x8E, 0x44, 0x75, 0x8D, - 0x31, 0x59, 0xAB, 0x9E, 0x02, 0x84, 0x01, 0xA3 - }, - { - 0x33, 0x96, 0xCF, 0xD5, 0xCD, 0xE1, 0x4A, 0xEC, - 0x1A, 0xAE, 0xD3, 0xE1, 0x22, 0x52, 0xCF, 0xD6, - 0xE3, 0x42, 0xED, 0x25, 0x5E, 0x8E, 0x9E, 0x1B, - 0xE1, 0x0F, 0x1F, 0x27, 0x38, 0x77, 0xF3, 0x63, - 0x33, 0x81, 0xE3, 0xC9, 0x61, 0xE6, 0x7E, 0xC4, - 0x1E, 0x8F, 0x9E, 0x16, 0x11, 0x0F, 0xC0, 0x3D, - 0xDE, 0x88, 0xBF, 0xC0, 0x96, 0xFC, 0x15, 0x14, - 0x46, 0x1D, 0x70, 0xD0, 0xBE, 0xCE, 0x0A, 0xF6 - }, - { - 0x77, 0x7D, 0x9D, 0xC5, 0x5A, 0x2F, 0x57, 0xA4, - 0x6E, 0xA0, 0x6A, 0x2F, 0x4C, 0xB9, 0x76, 0x0D, - 0x00, 0xD7, 0xA8, 0x62, 0xD0, 0xA2, 0xAA, 0x19, - 0x46, 0x7B, 0x57, 0x0F, 0x7C, 0x7D, 0x5E, 0xA7, - 0x62, 0x9A, 0x95, 0xEB, 0x20, 0x0E, 0x1F, 0x9D, - 0xB0, 0x66, 0x10, 0xCF, 0x8E, 0x30, 0xD5, 0xE6, - 0xAD, 0x0A, 0x7B, 0x63, 0x29, 0x77, 0xFC, 0x21, - 0xBB, 0x17, 0x89, 0x67, 0xF3, 0xB0, 0xE0, 0x9B - }, - { - 0x32, 0xEE, 0x35, 0x7F, 0xC9, 0x16, 0x36, 0xA8, - 0x55, 0xBA, 0x01, 0xA0, 0xB8, 0xDA, 0x6F, 0x35, - 0x53, 0xB1, 0xD5, 0x20, 0xAD, 0xCF, 0xE8, 0xFE, - 0x9D, 0xEB, 0xCC, 0xB2, 0x6C, 0x5C, 0x4C, 0xE8, - 0x50, 0x5B, 0xB1, 0xEF, 0xB5, 0xED, 0x5B, 0xAA, - 0x4C, 0x52, 0x45, 0xB5, 0x0D, 0x74, 0x46, 0x3F, - 0x07, 0x67, 0xB2, 0xC7, 0x83, 0xC4, 0x7A, 0x93, - 0xB0, 0xFD, 0xA6, 0x68, 0x95, 0x69, 0x3C, 0xE6 - }, - { - 0x34, 0x0C, 0x0A, 0x7C, 0xE4, 0x96, 0xFE, 0xBD, - 0xA1, 0x3F, 0xA2, 0x40, 0x7A, 0x21, 0xDC, 0x19, - 0x83, 0x9B, 0xED, 0xAE, 0x1A, 0x08, 0x6A, 0xD0, - 0xFE, 0xD3, 0x91, 0x7D, 0xF9, 0xBF, 0x40, 0x94, - 0x4A, 0x78, 0x7F, 0x64, 0x1E, 0x90, 0xDD, 0xBA, - 0xE0, 0x3A, 0x93, 0x37, 0x72, 0x3E, 0x51, 0x66, - 0x8F, 0xB8, 0x93, 0x77, 0x2C, 0x0F, 0xBD, 0xB3, - 0xEB, 0x7E, 0xF7, 0x90, 0xDF, 0xCB, 0xB9, 0xAB - }, - { - 0xD8, 0x6A, 0x5B, 0xAA, 0x33, 0x65, 0xAB, 0xD8, - 0xF4, 0x42, 0xCD, 0x6E, 0xBB, 0x93, 0x11, 0x38, - 0x19, 0xF0, 0xB4, 0x60, 0x61, 0xE1, 0x34, 0x04, - 0xEF, 0xAA, 0x1A, 0x58, 0xE1, 0xFF, 0x27, 0x2A, - 0xD4, 0xBF, 0xD3, 0x08, 0x15, 0xAD, 0xD8, 0x8A, - 0xD9, 0x8F, 0xCE, 0x9A, 0xF0, 0x18, 0x37, 0x4C, - 0xA6, 0x0D, 0x89, 0x79, 0x0F, 0x71, 0xA6, 0x07, - 0x5F, 0x3D, 0x68, 0xD3, 0x20, 0x21, 0xA9, 0xEB - }, - { - 0xA6, 0x7E, 0x6E, 0xC6, 0x57, 0xC9, 0x5E, 0xAB, - 0x3C, 0x3C, 0x32, 0xE4, 0x1F, 0xBF, 0x39, 0xCF, - 0x20, 0x33, 0xAB, 0x4B, 0xE2, 0xE2, 0xB8, 0x21, - 0x10, 0x4A, 0xDB, 0xE6, 0x9D, 0x16, 0xE9, 0x48, - 0xDC, 0xE4, 0xC4, 0xC6, 0xA3, 0xCF, 0x22, 0x76, - 0x90, 0x1F, 0x7D, 0x4F, 0xFD, 0x69, 0x65, 0x46, - 0x49, 0x88, 0x2C, 0x01, 0x4D, 0x2C, 0x10, 0xA1, - 0x30, 0x2B, 0x79, 0xC6, 0x15, 0x69, 0xCD, 0x36 - }, - { - 0x55, 0xCE, 0x19, 0x2A, 0xE4, 0xB3, 0xEA, 0xF8, - 0x55, 0x59, 0x0E, 0x2D, 0x44, 0xE6, 0x25, 0xD9, - 0xBA, 0x14, 0x6E, 0xB7, 0x50, 0x48, 0xE6, 0xB5, - 0x6E, 0x02, 0x50, 0x31, 0xEF, 0xBA, 0x0B, 0xDA, - 0x8A, 0xAA, 0xFA, 0x04, 0x70, 0xB7, 0xAC, 0x3D, - 0x40, 0x6E, 0x5A, 0xBA, 0x3E, 0x83, 0x2F, 0x27, - 0xA5, 0x07, 0x24, 0x6D, 0x1B, 0x5F, 0x33, 0xDE, - 0xA1, 0xF7, 0x24, 0xE2, 0xB8, 0x1B, 0x0C, 0x98 - }, - { - 0xB3, 0xA2, 0x0C, 0x1F, 0xB0, 0xB4, 0xF0, 0xD3, - 0x77, 0x26, 0xC2, 0x3B, 0x58, 0x77, 0xDD, 0x8E, - 0x72, 0xF6, 0x98, 0x86, 0xE0, 0x9A, 0x8C, 0x68, - 0xCF, 0xC3, 0x01, 0xD2, 0xA3, 0xF2, 0xF9, 0x5C, - 0xEF, 0xCF, 0xAB, 0xB8, 0x88, 0x99, 0x03, 0xC7, - 0x32, 0xF4, 0xE8, 0x14, 0x32, 0xD3, 0xF6, 0x78, - 0xCC, 0xDF, 0xC3, 0x98, 0xAC, 0xD8, 0xA2, 0xF0, - 0x66, 0x41, 0x10, 0x04, 0x50, 0xD8, 0x9F, 0x32 - }, - { - 0xF7, 0x27, 0x2D, 0x93, 0xC7, 0x01, 0x2D, 0x38, - 0xB2, 0x7F, 0x0C, 0x9A, 0xE2, 0x01, 0x79, 0x58, - 0xBB, 0xA6, 0x66, 0xA9, 0xDE, 0x1E, 0x88, 0x12, - 0xE9, 0x74, 0x37, 0xAE, 0xB2, 0xE0, 0x3C, 0x99, - 0x94, 0x38, 0xF0, 0xBE, 0x33, 0x3D, 0x09, 0xAD, - 0xDB, 0xCF, 0xAA, 0xC7, 0xAA, 0x73, 0xF7, 0xB6, - 0xCC, 0xEC, 0x67, 0xDC, 0x07, 0x79, 0x98, 0xDE, - 0xDB, 0x8C, 0x13, 0x32, 0xBA, 0xC0, 0xFB, 0xA8 - }, - { - 0x1F, 0xE7, 0xB3, 0xDE, 0x34, 0xC0, 0x47, 0x9C, - 0xA8, 0x40, 0x5F, 0x3C, 0xBC, 0xD2, 0xDB, 0x64, - 0xBB, 0x18, 0xDB, 0xB2, 0x91, 0xA5, 0xFE, 0xAA, - 0x16, 0xC5, 0x22, 0x8C, 0x93, 0xEE, 0x21, 0xC7, - 0x11, 0xD6, 0x8A, 0x01, 0x0C, 0x2A, 0xE8, 0x80, - 0x05, 0xEB, 0xAC, 0x95, 0x9E, 0x3A, 0x32, 0x24, - 0x52, 0xF8, 0x62, 0xDD, 0xE9, 0x4B, 0xB9, 0x41, - 0x81, 0x3E, 0x52, 0x4D, 0x23, 0x47, 0xFE, 0xEE - }, - { - 0x4E, 0xE1, 0xD3, 0x88, 0x05, 0xC3, 0x22, 0x84, - 0xEC, 0xEB, 0xE9, 0x2E, 0x3D, 0xF6, 0xCD, 0x98, - 0xC7, 0xD6, 0x68, 0x0E, 0xAB, 0x0D, 0x68, 0x66, - 0x4F, 0x96, 0x70, 0x6C, 0x45, 0x63, 0x3B, 0x1E, - 0x26, 0x82, 0x22, 0xAA, 0x5A, 0x52, 0x79, 0xEF, - 0x01, 0xFC, 0x28, 0x54, 0x32, 0xAB, 0xEE, 0xD7, - 0x4B, 0xA3, 0xDF, 0x18, 0x9F, 0x50, 0xA9, 0x89, - 0xD5, 0x8E, 0x71, 0x30, 0x62, 0x2D, 0xAA, 0x59 - }, - { - 0x0E, 0x14, 0x05, 0x87, 0x1C, 0x87, 0xA5, 0xEA, - 0x40, 0x83, 0x42, 0xF3, 0x9D, 0x34, 0x94, 0xF9, - 0x39, 0xF7, 0x3C, 0x22, 0x60, 0xC2, 0xA4, 0x3A, - 0x5C, 0x9F, 0x1B, 0x57, 0x33, 0x0C, 0xCA, 0x40, - 0x93, 0xFC, 0x1F, 0x42, 0xF9, 0x6D, 0x83, 0x00, - 0x56, 0x77, 0x03, 0x7D, 0xB5, 0x1A, 0xEF, 0x26, - 0xF0, 0x54, 0x38, 0x05, 0x7A, 0xE7, 0x9E, 0xD1, - 0x44, 0x64, 0xFD, 0x8E, 0x57, 0xD1, 0x55, 0x86 - }, - { - 0x17, 0xC5, 0xCA, 0xB4, 0x09, 0x10, 0x73, 0x62, - 0x1B, 0x5C, 0x24, 0xC3, 0x36, 0x31, 0x6D, 0x0C, - 0xF6, 0x49, 0xBA, 0x1E, 0xFF, 0xEB, 0xFC, 0x87, - 0xE0, 0x43, 0x9C, 0xDF, 0x57, 0x88, 0x87, 0xB2, - 0x21, 0x65, 0x6D, 0x33, 0x9A, 0x6F, 0xD1, 0x98, - 0xAB, 0xAE, 0xE6, 0x7E, 0xA1, 0x88, 0xDD, 0x66, - 0x56, 0x78, 0x23, 0xFC, 0x22, 0x0C, 0x52, 0xB5, - 0x74, 0x90, 0x25, 0x14, 0x69, 0xD2, 0x5D, 0x8C - }, - { - 0x57, 0xDC, 0x27, 0x97, 0xD1, 0x42, 0x68, 0x1C, - 0x94, 0xFE, 0x48, 0x86, 0x26, 0x98, 0x6E, 0xD4, - 0xB2, 0x67, 0x03, 0xCB, 0xF6, 0xBF, 0xE5, 0x93, - 0x91, 0x64, 0x36, 0x57, 0x06, 0x5B, 0x2D, 0x46, - 0xE4, 0xB1, 0xDD, 0xB3, 0xAA, 0x83, 0x2C, 0x9B, - 0xD4, 0x49, 0x75, 0x5A, 0xC8, 0xB1, 0xBF, 0x93, - 0x68, 0x97, 0xFB, 0xC6, 0xAD, 0xE3, 0x78, 0xF2, - 0xBD, 0x64, 0x93, 0xE4, 0x86, 0xF4, 0x20, 0x29 - }, - { - 0x44, 0x12, 0xDD, 0x6B, 0xED, 0x6D, 0xB2, 0xA8, - 0x03, 0xC2, 0xE0, 0xDF, 0x8F, 0x58, 0x29, 0xE7, - 0xA4, 0xB0, 0x41, 0x78, 0x89, 0x51, 0x0D, 0xF7, - 0xDF, 0xEE, 0x49, 0x57, 0x4A, 0x71, 0xEC, 0x0D, - 0x9E, 0x0D, 0x46, 0x06, 0x50, 0x17, 0xC7, 0x2D, - 0xD9, 0x74, 0x39, 0x33, 0xCA, 0x83, 0x9A, 0x76, - 0x8D, 0xD1, 0x5A, 0xB0, 0xB7, 0xC1, 0x4C, 0x62, - 0x6A, 0x35, 0x41, 0x09, 0x69, 0x01, 0x96, 0xAE - }, - { - 0xD0, 0xEB, 0xC7, 0x71, 0x03, 0x1B, 0x7C, 0x16, - 0x00, 0x21, 0xC9, 0xB6, 0xFB, 0xB2, 0xB6, 0x70, - 0xE3, 0xB4, 0x02, 0x70, 0x02, 0x69, 0x07, 0xA3, - 0x91, 0x63, 0xDB, 0x18, 0x73, 0xEC, 0xC3, 0xB8, - 0x00, 0x11, 0x1D, 0xD7, 0xBF, 0x13, 0x8F, 0x83, - 0xA6, 0x10, 0xDC, 0x04, 0x6D, 0xA2, 0x68, 0xB7, - 0x2B, 0x8C, 0x90, 0x86, 0x92, 0x23, 0x77, 0xDB, - 0xED, 0x73, 0x94, 0x82, 0x43, 0xCA, 0x1E, 0x14 - }, - { - 0x10, 0xC4, 0xBA, 0x31, 0x55, 0x91, 0x69, 0x8D, - 0xFB, 0x91, 0xA5, 0x73, 0x37, 0x63, 0x18, 0x84, - 0xB4, 0x73, 0x8D, 0x9F, 0x59, 0x80, 0x78, 0x51, - 0xA6, 0x79, 0x84, 0x0C, 0xC2, 0x87, 0xAC, 0xE3, - 0x01, 0x1C, 0xCD, 0xC8, 0xF4, 0xA4, 0x85, 0xBB, - 0x19, 0x73, 0x40, 0x4E, 0xF9, 0xEE, 0x9B, 0x9C, - 0xF1, 0xEA, 0xDB, 0xC5, 0x40, 0x74, 0xC6, 0xD1, - 0x13, 0xDE, 0x8F, 0xC9, 0x1D, 0x07, 0x97, 0xEB - }, - { - 0x14, 0x64, 0x34, 0x7B, 0xE3, 0x2C, 0x79, 0x59, - 0x17, 0x2B, 0x74, 0x72, 0xD1, 0x1F, 0xE0, 0x78, - 0x44, 0xA5, 0x2E, 0x2D, 0x3B, 0x2D, 0x05, 0x8C, - 0xC6, 0xBC, 0xC0, 0xA8, 0xA2, 0x75, 0xD6, 0xB8, - 0x2B, 0x2D, 0x62, 0x63, 0x75, 0x5E, 0xAF, 0x2A, - 0x65, 0x88, 0xB6, 0xA1, 0xEB, 0x79, 0x9A, 0xF8, - 0x3A, 0x4C, 0xE7, 0x53, 0xF8, 0xC7, 0x5A, 0x22, - 0x84, 0xD0, 0x28, 0x5B, 0xAB, 0x5F, 0x7C, 0x1C - }, - { - 0xF4, 0x09, 0x23, 0x1E, 0xD1, 0x87, 0xF5, 0xC4, - 0xE8, 0x33, 0xFA, 0x9E, 0x30, 0x42, 0xAC, 0xA6, - 0xC8, 0x58, 0xB0, 0x8B, 0x49, 0x6B, 0x25, 0x31, - 0xF8, 0x4F, 0xD5, 0xCE, 0xA9, 0x3E, 0xCD, 0x06, - 0xDA, 0xFE, 0x0A, 0x10, 0xC3, 0xFF, 0x23, 0x76, - 0xC7, 0x4D, 0xC8, 0x0D, 0xA0, 0x7D, 0xA0, 0x18, - 0x64, 0xFB, 0xF2, 0x68, 0x59, 0x60, 0xB5, 0x40, - 0xB3, 0xA2, 0xE9, 0x42, 0xCB, 0x8D, 0x90, 0x9F - }, - { - 0x39, 0x51, 0x32, 0xC5, 0x80, 0xC3, 0x55, 0xB5, - 0xB0, 0xE2, 0x35, 0x33, 0x6C, 0x8D, 0xC1, 0x08, - 0x5E, 0x59, 0x59, 0x64, 0x04, 0x3D, 0x38, 0x9E, - 0x08, 0x1E, 0xFE, 0x48, 0x5B, 0xA4, 0xC6, 0x37, - 0x72, 0xDB, 0x8D, 0x7E, 0x0F, 0x18, 0x6C, 0x50, - 0x98, 0x2E, 0x12, 0x23, 0xEA, 0x78, 0x5A, 0xDC, - 0x74, 0x0B, 0x0C, 0xF2, 0x18, 0x70, 0x74, 0x58, - 0xB8, 0xB8, 0x03, 0x40, 0x42, 0xF9, 0x23, 0xC2 - }, - { - 0xF9, 0x2A, 0xBA, 0xCA, 0x21, 0x32, 0x29, 0x66, - 0x06, 0x49, 0xEF, 0x2D, 0x8F, 0x88, 0x11, 0x5B, - 0x5B, 0xED, 0x8A, 0xB5, 0xB9, 0xBC, 0xA9, 0xA1, - 0xB4, 0xC5, 0x24, 0x57, 0x03, 0x53, 0x10, 0xC4, - 0x1A, 0x6B, 0xEA, 0x2B, 0x23, 0xB7, 0x91, 0x8B, - 0x5B, 0x8B, 0xF3, 0x8B, 0x52, 0xEA, 0xC6, 0xFF, - 0x3B, 0x62, 0x13, 0xA5, 0x22, 0xF3, 0x81, 0xBE, - 0x7F, 0xF0, 0x90, 0x6D, 0xBA, 0x7B, 0xD0, 0x0C - }, - { - 0xCB, 0xAD, 0xE7, 0xAD, 0x3B, 0x5D, 0xEE, 0x0F, - 0xF1, 0xA4, 0x6B, 0x08, 0x2C, 0xF4, 0xE1, 0xE1, - 0xDC, 0x21, 0x62, 0x0D, 0xD2, 0xCC, 0x0E, 0xDC, - 0x2C, 0x70, 0x7A, 0x21, 0x62, 0xD2, 0x14, 0x99, - 0x69, 0xAB, 0xBB, 0x29, 0xC5, 0x72, 0x0B, 0x04, - 0xBD, 0x15, 0x68, 0xA9, 0x55, 0x61, 0x95, 0xE6, - 0x7F, 0x24, 0x32, 0x2D, 0xD9, 0xAA, 0x4E, 0x83, - 0x65, 0x19, 0x1A, 0xA5, 0xB6, 0xC4, 0x45, 0x79 - }, - { - 0xF5, 0x1B, 0x4A, 0xE4, 0xD4, 0xC5, 0x4A, 0x29, - 0xCF, 0x71, 0x35, 0xA8, 0xFE, 0x1E, 0xAB, 0xD5, - 0xE1, 0xBC, 0xBF, 0x82, 0x08, 0x96, 0x96, 0x7D, - 0xC4, 0x1E, 0x38, 0x49, 0xDA, 0xC2, 0x25, 0x07, - 0x69, 0x42, 0x10, 0xCA, 0x11, 0xC4, 0xEB, 0xF1, - 0xC2, 0x9A, 0x8D, 0x4F, 0x71, 0xB3, 0x0F, 0x76, - 0xC9, 0xB6, 0x01, 0x0A, 0xD9, 0x5B, 0xDF, 0xB0, - 0xDE, 0x83, 0x79, 0x25, 0xF0, 0x61, 0x25, 0x97 - }, - { - 0xCE, 0x38, 0x72, 0x11, 0x5D, 0x83, 0x3B, 0x34, - 0x56, 0xCA, 0x94, 0x2E, 0x6E, 0x38, 0x5F, 0x28, - 0xA9, 0x03, 0xBE, 0xAB, 0xFB, 0x75, 0x3F, 0x8A, - 0xFC, 0xCC, 0x12, 0xF2, 0x58, 0x2C, 0xE1, 0xF3, - 0x62, 0x12, 0xBD, 0x05, 0xE0, 0x5A, 0x46, 0xFC, - 0x88, 0xD3, 0x19, 0x50, 0xB4, 0x91, 0x1A, 0xE5, - 0xDC, 0xD8, 0xFF, 0x7A, 0x0B, 0x50, 0x47, 0x4C, - 0xB4, 0x88, 0xCC, 0xF2, 0xA8, 0x9C, 0xD0, 0xEB - }, - { - 0x9B, 0xB7, 0x4C, 0xBD, 0x47, 0xA6, 0x24, 0xCB, - 0xEA, 0xFC, 0xC1, 0x6D, 0x46, 0x29, 0x47, 0xBB, - 0xEA, 0x13, 0x70, 0xB8, 0x5C, 0x96, 0x1A, 0x40, - 0x7D, 0xF9, 0x86, 0x3E, 0x54, 0xE6, 0xD9, 0xE6, - 0xA8, 0xD2, 0xEF, 0x0C, 0x64, 0x97, 0x20, 0x5E, - 0x5E, 0xB7, 0xC3, 0xE5, 0x9E, 0x69, 0x8D, 0x99, - 0x24, 0x63, 0xCA, 0x9D, 0xD4, 0xCF, 0x28, 0xCF, - 0x9A, 0x2D, 0x4E, 0x30, 0xC1, 0x33, 0xE8, 0x55 - }, - { - 0x72, 0x96, 0x33, 0x82, 0x0B, 0xF0, 0x13, 0xD9, - 0xD2, 0xBD, 0x37, 0x3C, 0xCA, 0xC7, 0xBC, 0x9F, - 0x37, 0x16, 0xF6, 0x9E, 0x16, 0xA4, 0x4E, 0x94, - 0x9C, 0x7A, 0x9A, 0x93, 0xDC, 0xA1, 0x26, 0xBB, - 0x1A, 0xA5, 0x4E, 0x5E, 0x70, 0x40, 0x70, 0x7F, - 0x02, 0x87, 0x6A, 0xFD, 0x02, 0x0A, 0xF4, 0x72, - 0x63, 0x9D, 0x49, 0xF5, 0x42, 0x0D, 0x29, 0x4C, - 0x3A, 0xA3, 0x1D, 0x06, 0x7E, 0x3E, 0x85, 0x75 - }, - { - 0x06, 0x86, 0x1D, 0xB3, 0x07, 0xC6, 0x78, 0x08, - 0x6E, 0x8B, 0x2A, 0xEC, 0xDF, 0x18, 0x29, 0xD2, - 0x88, 0x3D, 0x28, 0xB7, 0x31, 0xAB, 0xD0, 0xF1, - 0xE7, 0x2F, 0x1C, 0xED, 0x6C, 0x7A, 0xD4, 0x17, - 0x2E, 0xCA, 0x63, 0x22, 0xA8, 0x3F, 0xB6, 0xA6, - 0x5A, 0xFA, 0x37, 0xE9, 0x4A, 0x3E, 0x2B, 0xA2, - 0x05, 0xB8, 0x7B, 0xF3, 0x82, 0xD9, 0x15, 0x88, - 0x49, 0x7A, 0x46, 0x50, 0x88, 0x3B, 0xD8, 0x75 - }, - { - 0x35, 0x6E, 0xCE, 0xAF, 0x17, 0x02, 0xB3, 0x70, - 0xF4, 0xAA, 0xB8, 0xEA, 0x82, 0x84, 0x86, 0xF3, - 0x30, 0x13, 0xF7, 0x44, 0xB3, 0x9E, 0x7E, 0xA2, - 0x6C, 0x69, 0x18, 0xD6, 0x0E, 0x1A, 0xBC, 0xF4, - 0x4F, 0xB1, 0x6E, 0xDC, 0xA7, 0x72, 0x0A, 0xCF, - 0xC6, 0xA7, 0x01, 0xBF, 0x1E, 0x2C, 0x35, 0xDD, - 0xBD, 0x69, 0x5A, 0x8D, 0x40, 0x8E, 0x8C, 0x96, - 0x32, 0xE8, 0xCD, 0x27, 0x23, 0x0C, 0xAD, 0x8D - }, - { - 0x48, 0x9A, 0x39, 0xD0, 0xFC, 0x3C, 0xDE, 0xAF, - 0x42, 0x89, 0x2E, 0xD8, 0x03, 0x85, 0xC1, 0x1C, - 0xE2, 0x93, 0xC9, 0x32, 0x21, 0x5B, 0xB2, 0x31, - 0x88, 0x69, 0x2A, 0x86, 0xE6, 0x1B, 0xCA, 0xD9, - 0x2C, 0x2A, 0x1D, 0x11, 0x42, 0x60, 0x1B, 0x1B, - 0xDF, 0x09, 0x82, 0xD1, 0xCD, 0x1E, 0x05, 0xC0, - 0x52, 0xDE, 0x81, 0x9E, 0x64, 0xF2, 0x47, 0xDB, - 0x35, 0x91, 0x5D, 0xD1, 0xDB, 0x79, 0xA3, 0xB5 - }, - { - 0xC0, 0x2F, 0x46, 0x4B, 0x4D, 0xD1, 0x81, 0x17, - 0xE3, 0x0A, 0x8D, 0xB8, 0xEF, 0x1D, 0xA0, 0x67, - 0x13, 0x4B, 0x60, 0x4E, 0xFA, 0x19, 0x51, 0x76, - 0x7E, 0xE6, 0x32, 0xDC, 0x02, 0x4D, 0x64, 0xC0, - 0x0F, 0x24, 0x49, 0xF0, 0x42, 0xDB, 0x3A, 0xEA, - 0x01, 0x74, 0xEB, 0xCD, 0xBB, 0x4F, 0xF5, 0x9D, - 0xAE, 0x75, 0x4F, 0x72, 0x39, 0x46, 0xF1, 0xB9, - 0x0A, 0x77, 0xFD, 0x95, 0x23, 0x69, 0x0B, 0x7B - }, - { - 0xFB, 0x31, 0xE6, 0xDD, 0xB8, 0x6D, 0xBF, 0xF3, - 0x72, 0x64, 0x6D, 0x1E, 0x3A, 0x3F, 0x31, 0xDD, - 0x61, 0x15, 0x9F, 0xC3, 0x93, 0x65, 0x8C, 0x2E, - 0xE9, 0x57, 0x10, 0x3B, 0xF2, 0x11, 0x6B, 0xDE, - 0xF8, 0x2C, 0x33, 0xE8, 0x69, 0xF3, 0xC8, 0x3A, - 0xC3, 0xC2, 0xF6, 0x38, 0x0C, 0xF6, 0x92, 0xF7, - 0xB1, 0xDC, 0xBA, 0xE0, 0xBB, 0x22, 0x7A, 0xD3, - 0x47, 0xE7, 0x54, 0x13, 0x74, 0x66, 0xC6, 0x9F - }, - { - 0x00, 0x60, 0x62, 0xAB, 0xE1, 0x6C, 0x2F, 0xE7, - 0x9A, 0xF8, 0x80, 0x85, 0xE0, 0xB5, 0x82, 0xB1, - 0x06, 0xE7, 0xF7, 0x9F, 0x01, 0xA4, 0x39, 0x46, - 0xC7, 0x8B, 0x19, 0xF9, 0xBD, 0xD7, 0x25, 0x99, - 0x76, 0x36, 0xA3, 0x32, 0xEB, 0x9A, 0x3A, 0xAA, - 0x6D, 0xE0, 0xD4, 0xA8, 0xE9, 0xE2, 0x8E, 0x8C, - 0x77, 0x87, 0x74, 0x22, 0x4C, 0x66, 0x5B, 0xF7, - 0xBC, 0x36, 0x44, 0xFC, 0xE4, 0x11, 0x22, 0x8C - }, - { - 0xD4, 0x4A, 0x6D, 0xB3, 0xDE, 0x9F, 0xD4, 0xE4, - 0xA7, 0xEF, 0x15, 0x5A, 0x01, 0xBC, 0xCB, 0x91, - 0xC1, 0xBC, 0xF1, 0xCB, 0x53, 0x22, 0x56, 0x89, - 0xA7, 0x7A, 0x0D, 0x23, 0xB4, 0xD3, 0x9A, 0x89, - 0xA1, 0x89, 0xF2, 0x89, 0x80, 0xF9, 0x1C, 0x56, - 0xEA, 0xC5, 0x87, 0x9E, 0xAE, 0x93, 0x3C, 0xED, - 0x7F, 0x26, 0x7E, 0x2F, 0x70, 0x40, 0xEB, 0x38, - 0x0F, 0xDB, 0xBF, 0x34, 0xA6, 0xB7, 0xB6, 0x15 - }, - { - 0x5A, 0xFB, 0xFE, 0xA1, 0xDE, 0xDA, 0x5A, 0xEA, - 0xB9, 0x2E, 0x4D, 0x0C, 0x31, 0xD1, 0x6A, 0x9A, - 0x86, 0xBF, 0x7C, 0x75, 0x23, 0x27, 0x4A, 0x05, - 0xC5, 0x05, 0x29, 0xF5, 0xC1, 0x39, 0xDB, 0x10, - 0x93, 0x3A, 0x52, 0xC6, 0x22, 0x9C, 0xD3, 0x11, - 0x08, 0xF0, 0x83, 0xFB, 0x0C, 0x85, 0xCF, 0x52, - 0x83, 0x1B, 0x5A, 0x05, 0xF2, 0x55, 0x0A, 0x77, - 0xB5, 0x70, 0x3C, 0xC6, 0x68, 0x91, 0x2D, 0xBC - }, - { - 0xD1, 0x7F, 0xCA, 0xD4, 0xE0, 0xD8, 0xBD, 0xE2, - 0xED, 0xFD, 0xA1, 0x68, 0xBA, 0x47, 0x10, 0x4B, - 0xBC, 0xA4, 0xD2, 0x6D, 0xA2, 0xD3, 0x1A, 0x07, - 0x0B, 0x0F, 0xBA, 0x0B, 0x26, 0xEE, 0xDD, 0x95, - 0xEE, 0xC1, 0xFC, 0x34, 0xD7, 0x6C, 0xD4, 0xA1, - 0xCB, 0x15, 0xF2, 0x62, 0x16, 0x88, 0xA9, 0xCC, - 0x0E, 0x96, 0x35, 0x8D, 0xE9, 0x93, 0x22, 0x2B, - 0xB3, 0xE3, 0xCD, 0x0B, 0xFD, 0xCB, 0x74, 0x6C - }, - { - 0xBD, 0x6A, 0x59, 0x21, 0x63, 0x37, 0xB4, 0x5D, - 0x6B, 0x71, 0xAE, 0xAC, 0x01, 0x36, 0x6B, 0xFE, - 0x96, 0x60, 0xE0, 0xFB, 0xC2, 0x95, 0x9A, 0xDB, - 0xB6, 0x8D, 0x52, 0x6C, 0x43, 0xD4, 0x8F, 0xFF, - 0xFE, 0x2F, 0xFC, 0x43, 0x05, 0x88, 0xE7, 0x8E, - 0x66, 0x54, 0x6A, 0x3C, 0x70, 0x9B, 0x0A, 0xCE, - 0xA1, 0x7C, 0xBC, 0x5A, 0x21, 0x8C, 0x53, 0xCD, - 0x47, 0xAA, 0x48, 0x71, 0xC1, 0xDD, 0x98, 0x4A - }, - { - 0x83, 0xEA, 0x5A, 0xE1, 0x89, 0x11, 0x45, 0xC4, - 0x1A, 0x7C, 0x6C, 0x87, 0xFE, 0x92, 0x24, 0x87, - 0xF5, 0xD2, 0x82, 0x93, 0x35, 0x69, 0xB7, 0xAE, - 0x0E, 0x34, 0x56, 0x53, 0x38, 0x1E, 0xDE, 0x6D, - 0x4B, 0x16, 0xE1, 0x44, 0xD1, 0xC3, 0xE8, 0xF0, - 0x60, 0x5D, 0xAA, 0x0D, 0xB5, 0x96, 0x5A, 0x7B, - 0x79, 0xD9, 0x1A, 0x8A, 0xFE, 0x11, 0xF1, 0xE0, - 0xBC, 0x54, 0x9A, 0xC0, 0x74, 0xA0, 0x1A, 0xB7 - }, - { - 0x37, 0x50, 0x50, 0xCF, 0x2E, 0x43, 0x0D, 0x0E, - 0x29, 0x87, 0x58, 0x35, 0x20, 0x8E, 0x89, 0x06, - 0xD7, 0x05, 0x2E, 0x47, 0x29, 0x2C, 0x5A, 0x38, - 0xA6, 0x30, 0x82, 0x87, 0x3D, 0x31, 0xD5, 0x83, - 0x13, 0x5C, 0x07, 0xA2, 0x0C, 0x52, 0xD9, 0x5B, - 0x2D, 0x5D, 0xC3, 0xEA, 0xDE, 0x6B, 0xE1, 0x43, - 0xCA, 0x34, 0x38, 0xF4, 0x4D, 0x02, 0x0A, 0xAE, - 0x16, 0x0E, 0xD7, 0x7A, 0xB9, 0x88, 0x4F, 0x7D - }, - { - 0x30, 0x28, 0xB0, 0xE8, 0x24, 0x95, 0x7F, 0xF3, - 0xB3, 0x05, 0xE9, 0x7F, 0xF5, 0x92, 0xAA, 0x8E, - 0xF2, 0x9B, 0x3B, 0xEC, 0x1D, 0xC4, 0x7B, 0x76, - 0x13, 0x3D, 0x10, 0x3F, 0xFE, 0x38, 0x71, 0xBF, - 0x05, 0x12, 0xA2, 0x31, 0xAF, 0xCB, 0x1D, 0xF8, - 0x65, 0x97, 0xEC, 0x5E, 0x46, 0xE9, 0x23, 0xC8, - 0xB9, 0x85, 0xC2, 0x85, 0x08, 0x57, 0xC6, 0x40, - 0x01, 0xB2, 0xC5, 0x51, 0xEA, 0x83, 0x3D, 0x0E - }, - { - 0x08, 0x7C, 0xCB, 0x1E, 0x5B, 0xD1, 0x72, 0x22, - 0xB8, 0xAF, 0x20, 0x6D, 0xD6, 0x39, 0x08, 0xF8, - 0x91, 0x72, 0x97, 0x62, 0x1A, 0x8C, 0xB9, 0x33, - 0x0A, 0xE0, 0xBA, 0x4A, 0xF3, 0xE9, 0xD6, 0x0C, - 0x98, 0xFC, 0xF1, 0xEF, 0xFC, 0xEC, 0x20, 0x13, - 0x6B, 0x4F, 0x91, 0x88, 0x12, 0x6D, 0xFA, 0x04, - 0x4E, 0x1C, 0x1C, 0xCD, 0xA3, 0xCE, 0xD8, 0x73, - 0x73, 0xD9, 0x37, 0x9C, 0xCB, 0xED, 0xBD, 0xB3 - }, - { - 0x7F, 0x17, 0x06, 0x24, 0x98, 0xBF, 0xA2, 0xBB, - 0x58, 0x56, 0xCD, 0x0A, 0x62, 0xC5, 0x68, 0xC5, - 0xC6, 0xB8, 0x97, 0x43, 0x24, 0x74, 0xEF, 0xB2, - 0xE6, 0xA2, 0xEE, 0x18, 0xCA, 0xFF, 0xD2, 0x1E, - 0x1E, 0xF3, 0x0D, 0x06, 0x47, 0x23, 0x85, 0x0F, - 0x79, 0x90, 0xD2, 0x1B, 0xA3, 0x4E, 0x8F, 0x2B, - 0x3B, 0xB0, 0x67, 0x02, 0x3A, 0x77, 0x27, 0x82, - 0x15, 0x8A, 0x27, 0xC6, 0xC4, 0x67, 0xC9, 0x28 - }, - { - 0x6B, 0xA9, 0x86, 0xA9, 0x42, 0x49, 0x7F, 0xD3, - 0x84, 0x62, 0x97, 0x2F, 0x50, 0xA6, 0x19, 0x68, - 0xC0, 0x65, 0x2D, 0xAC, 0x56, 0xCE, 0x9B, 0x9A, - 0xC1, 0xBC, 0x06, 0x1A, 0xB6, 0x34, 0xFE, 0x5A, - 0x77, 0xAC, 0xD0, 0x27, 0x5F, 0x83, 0x96, 0xE3, - 0xC0, 0xBE, 0xF0, 0x12, 0xAE, 0x93, 0xB7, 0x27, - 0x58, 0xB8, 0xD7, 0x67, 0x9C, 0x87, 0xE8, 0x47, - 0xE6, 0x30, 0x17, 0xB5, 0x5A, 0x69, 0xC5, 0xC6 - }, - { - 0x96, 0x7C, 0x81, 0xF5, 0x61, 0x95, 0x18, 0x33, - 0xFA, 0x56, 0x6F, 0x6B, 0x36, 0x07, 0x7E, 0xAD, - 0xB2, 0xA6, 0x15, 0xCC, 0x15, 0xF0, 0xED, 0xBB, - 0xAE, 0x4F, 0x84, 0x4D, 0xDC, 0x8E, 0x9C, 0x1F, - 0xB8, 0x3D, 0x31, 0xA9, 0x3F, 0xCB, 0x17, 0x74, - 0xD7, 0x40, 0xD6, 0x92, 0x08, 0xCA, 0x59, 0x30, - 0xBC, 0xFA, 0xC4, 0xA1, 0xF9, 0x44, 0x46, 0x9F, - 0xEF, 0xD1, 0x9B, 0x6E, 0x93, 0x75, 0xE0, 0xB5 - }, - { - 0xE8, 0xAE, 0xF1, 0x78, 0xE6, 0xDA, 0x3E, 0xF5, - 0xCA, 0xED, 0x65, 0x30, 0xF7, 0xEB, 0x25, 0x60, - 0x82, 0x56, 0xC2, 0x37, 0x7C, 0x4C, 0xF9, 0x6B, - 0x0C, 0xFD, 0x0D, 0x76, 0xEE, 0xB4, 0xBB, 0x86, - 0xEE, 0xFF, 0x7B, 0x7D, 0xF1, 0x58, 0x5C, 0x8D, - 0x7A, 0x20, 0xC0, 0x63, 0x3A, 0x67, 0x90, 0x7F, - 0x6D, 0x28, 0x67, 0xC3, 0x26, 0x4A, 0x91, 0xC0, - 0x51, 0xAB, 0xAE, 0x6E, 0xEA, 0x5A, 0x91, 0xD8 - }, - { - 0x64, 0x81, 0xDC, 0xC8, 0x15, 0x7A, 0xE6, 0x28, - 0xB5, 0xCD, 0x52, 0x6B, 0xAC, 0x8F, 0x93, 0x31, - 0x56, 0xDE, 0xDA, 0xC9, 0x56, 0xA2, 0xB2, 0x2A, - 0x97, 0x4B, 0xF5, 0xF7, 0xEC, 0x2D, 0xB5, 0x80, - 0x6F, 0x53, 0xDD, 0x0E, 0x2D, 0xD5, 0x3D, 0xB8, - 0x7C, 0xD8, 0xF5, 0x8A, 0x58, 0x6F, 0x9B, 0x3C, - 0x5C, 0x52, 0x23, 0x31, 0xA3, 0x11, 0x74, 0xC4, - 0xE7, 0xB9, 0xB6, 0xF7, 0xF0, 0x57, 0xC2, 0x8F - }, - { - 0xA7, 0x1E, 0xA4, 0x5C, 0xE6, 0x61, 0x6A, 0x3D, - 0x2F, 0x0A, 0x59, 0x2D, 0x5D, 0x02, 0x86, 0x93, - 0x2D, 0xA6, 0x3C, 0x6D, 0xB1, 0x1D, 0x59, 0xC6, - 0x69, 0x1C, 0x35, 0xA5, 0x6F, 0x7E, 0xE4, 0xF8, - 0x0B, 0x6F, 0xC3, 0x40, 0xB4, 0xDB, 0xC1, 0x84, - 0x4C, 0x50, 0x40, 0xE6, 0x68, 0xD2, 0x89, 0x2F, - 0x4A, 0x4A, 0xE8, 0x53, 0x3F, 0x1B, 0x67, 0x71, - 0xBC, 0xFC, 0xE7, 0xC3, 0xA2, 0x3E, 0x0D, 0x97 - }, - { - 0x96, 0x93, 0x44, 0x87, 0x70, 0xFE, 0xAE, 0x42, - 0x17, 0x26, 0xEB, 0x20, 0x3B, 0x01, 0xC7, 0x08, - 0x23, 0xD5, 0xF4, 0x4C, 0xC5, 0x21, 0x3E, 0x6A, - 0x68, 0x28, 0x47, 0x29, 0xBD, 0x11, 0x7D, 0x9B, - 0xD1, 0x8F, 0xEC, 0x4A, 0x0A, 0x82, 0x4A, 0x24, - 0x08, 0x0F, 0x29, 0x8B, 0xAC, 0xD2, 0x96, 0xD7, - 0xB4, 0x97, 0x83, 0x8F, 0xBD, 0x7B, 0x0D, 0x57, - 0x5C, 0x52, 0x49, 0x2B, 0x3E, 0x6F, 0x92, 0x6B - }, - { - 0x37, 0xA1, 0x50, 0x66, 0xF2, 0xB9, 0xF9, 0x4C, - 0x24, 0x61, 0x1B, 0xC4, 0x53, 0xED, 0x02, 0x74, - 0x07, 0x8D, 0x1F, 0x70, 0xB2, 0xD3, 0x4C, 0x8B, - 0x96, 0x36, 0x08, 0x48, 0x9D, 0xCB, 0xE8, 0xDF, - 0x44, 0x8E, 0xDD, 0x9C, 0x73, 0x36, 0x2B, 0xB2, - 0xB6, 0x6B, 0xEE, 0xF6, 0x1F, 0xCE, 0x60, 0x10, - 0x6F, 0x70, 0x19, 0xED, 0x37, 0x3C, 0x69, 0x22, - 0x59, 0xD9, 0x55, 0x6A, 0x94, 0x0B, 0x1A, 0x06 - }, - { - 0xBD, 0x44, 0xE7, 0x39, 0xE1, 0xF9, 0xDB, 0x1C, - 0x6B, 0xAF, 0x42, 0xCA, 0x4A, 0x12, 0xAC, 0x09, - 0x9B, 0x96, 0xF6, 0xB3, 0x6C, 0x4B, 0xCB, 0x1B, - 0x72, 0xEE, 0xFF, 0x08, 0xA6, 0x49, 0x68, 0x35, - 0xEC, 0x65, 0x15, 0x0B, 0xE8, 0xFE, 0x16, 0xCB, - 0xE3, 0x27, 0x07, 0xE3, 0x47, 0x54, 0x7D, 0xC5, - 0xA5, 0x83, 0xD2, 0x65, 0x74, 0x6F, 0xA5, 0x95, - 0xC5, 0xE7, 0x73, 0x0F, 0xCF, 0x24, 0x58, 0x1E - }, - { - 0xFA, 0xB2, 0x03, 0x8E, 0x94, 0x98, 0xA1, 0xC3, - 0x9E, 0x05, 0x78, 0xA0, 0xA5, 0xEA, 0x6B, 0x44, - 0xF3, 0xC1, 0xB4, 0x1A, 0xE5, 0x67, 0xF9, 0x91, - 0x4A, 0x95, 0xB1, 0x31, 0xC4, 0x8D, 0x12, 0x1E, - 0xCA, 0xCE, 0xA8, 0x95, 0xA0, 0x9B, 0x1D, 0x4E, - 0x04, 0x42, 0xBE, 0xC9, 0xC5, 0x0C, 0x50, 0xE0, - 0x0A, 0x9F, 0xAF, 0xEF, 0xFA, 0xE0, 0x70, 0x88, - 0x4C, 0x26, 0x25, 0xA8, 0xB1, 0xA2, 0x17, 0x26 - }, - { - 0x05, 0xA1, 0xB7, 0x6B, 0x2F, 0xD5, 0x62, 0x11, - 0xE0, 0xF2, 0xD7, 0x5A, 0x25, 0x16, 0x54, 0xA7, - 0x72, 0xF5, 0x5E, 0x18, 0xCA, 0x02, 0x2A, 0xF5, - 0x2C, 0xB3, 0x30, 0x19, 0x1E, 0x98, 0xA3, 0xB8, - 0xEB, 0x87, 0xE5, 0x11, 0x7B, 0xAE, 0x58, 0x04, - 0x4D, 0x94, 0x4C, 0x1F, 0x18, 0x85, 0x45, 0x12, - 0x25, 0x41, 0x77, 0x35, 0xFC, 0x72, 0xF7, 0x39, - 0x36, 0x69, 0x3C, 0xFF, 0x45, 0x46, 0x9F, 0x8C - }, - { - 0x2A, 0x30, 0xC9, 0x6B, 0xDA, 0xC7, 0x8A, 0x39, - 0x94, 0xEE, 0xCA, 0xA5, 0xA5, 0x3F, 0x82, 0x7F, - 0x58, 0xE1, 0x32, 0x31, 0xA0, 0xD1, 0x13, 0x08, - 0x6C, 0x06, 0xB1, 0xBD, 0xAB, 0xDA, 0x38, 0xD0, - 0x8F, 0x1A, 0xE2, 0x7D, 0xE2, 0x5F, 0xD2, 0x2E, - 0xEA, 0x70, 0xC0, 0x5F, 0x01, 0x32, 0xBF, 0x7A, - 0x50, 0x1C, 0x82, 0xAE, 0x62, 0x15, 0xBF, 0xEF, - 0x3C, 0x01, 0x63, 0x98, 0xBA, 0xF2, 0xCB, 0x62 - }, - { - 0x48, 0xDB, 0x53, 0x76, 0x5B, 0x82, 0xBD, 0x6F, - 0x25, 0x33, 0xEA, 0xE1, 0x7F, 0x67, 0x69, 0xD7, - 0xA4, 0xE3, 0xB2, 0x43, 0x74, 0x60, 0x1C, 0xDD, - 0x8E, 0xC0, 0xCA, 0x3A, 0xAB, 0x30, 0x93, 0xFD, - 0x2B, 0x99, 0x24, 0x38, 0x46, 0x0B, 0xAF, 0x8D, - 0xA5, 0x8F, 0xB9, 0xA8, 0x9B, 0x2C, 0x58, 0xF9, - 0x68, 0xE6, 0x36, 0x17, 0xCB, 0xEB, 0x18, 0x44, - 0xB0, 0x2D, 0x6A, 0x27, 0xC5, 0xB4, 0xAD, 0x41 - }, - { - 0x5C, 0x8B, 0x2E, 0x0E, 0x1B, 0x5C, 0x8F, 0x45, - 0x7D, 0x7F, 0x7B, 0xD9, 0xF0, 0x5A, 0x97, 0xE5, - 0x8D, 0xDA, 0x1D, 0x28, 0xDB, 0x9F, 0x34, 0xD1, - 0xCE, 0x73, 0x25, 0x28, 0xF9, 0x68, 0xBE, 0xDD, - 0x9E, 0x1C, 0xC9, 0x35, 0x2D, 0x0A, 0x5D, 0xF6, - 0x67, 0x29, 0x28, 0xBD, 0xD3, 0xEA, 0x6F, 0x5C, - 0xB0, 0x60, 0x77, 0xCF, 0x3A, 0xD3, 0xA7, 0x6E, - 0x29, 0xB2, 0x2E, 0x82, 0xBA, 0xC6, 0x7B, 0x61 - }, - { - 0x5B, 0x73, 0x91, 0xAA, 0x52, 0xF2, 0x76, 0xFA, - 0xB9, 0xC1, 0x38, 0x77, 0xF1, 0x22, 0x32, 0x70, - 0x84, 0x97, 0xFC, 0x02, 0x8F, 0xAA, 0x17, 0x32, - 0xA5, 0xDB, 0x07, 0x9E, 0x7F, 0xE0, 0x73, 0xED, - 0x0C, 0xC9, 0x52, 0x9C, 0xFC, 0x86, 0x3A, 0x4E, - 0xCB, 0xA4, 0xDC, 0x2F, 0x1E, 0xA9, 0xF6, 0xBD, - 0x69, 0x04, 0xF3, 0xA0, 0xC1, 0x07, 0x19, 0x3C, - 0x5E, 0x71, 0x1C, 0xB9, 0x11, 0xF3, 0x80, 0x25 - }, - { - 0x1D, 0x5A, 0xF7, 0x0F, 0x09, 0xA5, 0xFC, 0x69, - 0x16, 0xEF, 0x59, 0xA3, 0x8A, 0x86, 0x92, 0x6D, - 0xCA, 0xAE, 0x39, 0xA8, 0x95, 0x4D, 0x73, 0xFC, - 0x80, 0xA3, 0x50, 0x75, 0x1A, 0xDD, 0xA3, 0x8C, - 0x9D, 0x59, 0x75, 0x06, 0xDC, 0x05, 0xE1, 0xED, - 0x37, 0xBD, 0x2D, 0xB1, 0x59, 0x0F, 0x99, 0xAA, - 0x29, 0x6A, 0xEA, 0x13, 0xAB, 0x84, 0x43, 0xD5, - 0xA9, 0x23, 0x47, 0xFB, 0x85, 0xFC, 0x81, 0x6D - }, - { - 0x80, 0xE3, 0x70, 0x92, 0x97, 0xD4, 0x41, 0x14, - 0xB9, 0xFB, 0xDF, 0x55, 0x67, 0xF0, 0x5F, 0x33, - 0x00, 0x94, 0xCF, 0x09, 0xF4, 0xC0, 0xEF, 0xCF, - 0xAC, 0x05, 0x09, 0x5C, 0x36, 0x08, 0x10, 0x77, - 0x30, 0xC1, 0xAA, 0x07, 0xFF, 0x23, 0x00, 0x25, - 0x62, 0xC7, 0xE8, 0x41, 0xA9, 0xF5, 0x66, 0x24, - 0xFF, 0xE2, 0xAB, 0xEC, 0x61, 0x1E, 0xB9, 0xE7, - 0x3E, 0x1C, 0xCB, 0xD8, 0xF6, 0x2B, 0x11, 0x49 - }, - { - 0xF9, 0x94, 0x5C, 0x19, 0x06, 0x77, 0x84, 0x61, - 0x94, 0x13, 0x2B, 0x49, 0x6E, 0xC6, 0x01, 0x2C, - 0x08, 0x75, 0x0E, 0x02, 0x5F, 0xD5, 0x52, 0xED, - 0x32, 0x4D, 0x3A, 0x49, 0xD8, 0x63, 0x66, 0xC0, - 0x3D, 0xCC, 0xDE, 0x8D, 0x5B, 0x5A, 0xC9, 0xA4, - 0xBC, 0xB7, 0x19, 0x5E, 0x63, 0xBC, 0xAA, 0x93, - 0x9E, 0x8E, 0xDA, 0x18, 0xF1, 0x16, 0x94, 0xB6, - 0xFA, 0x69, 0x37, 0x39, 0x3B, 0xFF, 0xDB, 0xF4 - }, - { - 0x8D, 0x8F, 0x2E, 0xD9, 0xAE, 0x39, 0x80, 0x9A, - 0xAC, 0xAD, 0x2F, 0xCE, 0xDB, 0xD2, 0xDC, 0xA7, - 0x30, 0xC7, 0x83, 0xE6, 0x2F, 0xF7, 0x0B, 0x8D, - 0x3C, 0x53, 0x62, 0xF0, 0x73, 0xF8, 0x34, 0x67, - 0x19, 0x7D, 0x37, 0x56, 0xB4, 0x45, 0x19, 0x5F, - 0xE7, 0x52, 0x11, 0x73, 0x64, 0xD9, 0x2C, 0xF4, - 0x2C, 0x02, 0x6E, 0x40, 0x9D, 0x5F, 0xF7, 0xA9, - 0x53, 0x3E, 0xAB, 0x78, 0xF1, 0x75, 0x4A, 0x2D - }, - { - 0x3A, 0xC9, 0x9A, 0xC5, 0x3A, 0xC4, 0x9A, 0x56, - 0xFA, 0xA1, 0x86, 0x46, 0xB8, 0xE0, 0x8A, 0x2D, - 0x35, 0xBE, 0x80, 0xDF, 0x3E, 0xFB, 0xBB, 0xA6, - 0xBD, 0xA4, 0xAE, 0x90, 0x2B, 0x8D, 0x3E, 0x17, - 0x0A, 0x7B, 0xE8, 0x60, 0x5C, 0x34, 0xA4, 0xDC, - 0x9A, 0x73, 0x62, 0xB1, 0xC2, 0x01, 0xD7, 0x02, - 0x39, 0x1B, 0xD7, 0xD5, 0x20, 0x7F, 0x95, 0xFA, - 0x39, 0x0C, 0xE3, 0x3C, 0x43, 0x14, 0xD4, 0x11 - }, - { - 0xE4, 0x69, 0x4B, 0xDB, 0x31, 0x01, 0x6F, 0x25, - 0x53, 0x2C, 0x04, 0x3C, 0x5C, 0x63, 0x08, 0xCC, - 0x61, 0x9B, 0x0F, 0x87, 0x16, 0xF0, 0xC2, 0x9E, - 0xEB, 0x9F, 0x34, 0x0F, 0x47, 0xB0, 0x7B, 0x4A, - 0x4C, 0xE0, 0x98, 0x4C, 0x47, 0x24, 0xB1, 0x2A, - 0xB3, 0xD3, 0x2A, 0xF5, 0x16, 0xAD, 0xA2, 0x64, - 0x4C, 0xA6, 0x55, 0x8C, 0x1C, 0xB5, 0x81, 0x5C, - 0x12, 0x12, 0xA9, 0xB5, 0xFA, 0x83, 0x44, 0x12 - }, - { - 0xC6, 0x3C, 0x70, 0x3E, 0x62, 0x10, 0x8A, 0xA0, - 0xED, 0xC6, 0x83, 0xF3, 0x67, 0x8A, 0x00, 0x78, - 0x8F, 0xB1, 0x00, 0xC0, 0x96, 0x0B, 0x4E, 0x98, - 0xB7, 0x6A, 0x48, 0xE4, 0xE5, 0x92, 0x3D, 0x34, - 0x13, 0x44, 0x8D, 0xB8, 0x87, 0x5E, 0x3B, 0xCE, - 0xA7, 0xB6, 0xB8, 0x5D, 0x9E, 0x3E, 0xEA, 0xB7, - 0x2C, 0xD1, 0x50, 0x96, 0xFB, 0xBB, 0x2C, 0xC4, - 0x27, 0x03, 0x17, 0xFC, 0x34, 0xD4, 0x04, 0x71 - }, - { - 0x90, 0x80, 0xB7, 0xE8, 0x41, 0xEF, 0x51, 0x9C, - 0x54, 0x17, 0xE6, 0x90, 0xAA, 0xF4, 0x32, 0x79, - 0x07, 0xA8, 0x3D, 0xBC, 0xB7, 0x38, 0xD0, 0xF7, - 0x30, 0x8B, 0x1D, 0x61, 0x1D, 0xEF, 0x16, 0x9A, - 0x4F, 0x47, 0x42, 0x3E, 0x69, 0x0F, 0x27, 0xA7, - 0xE2, 0x74, 0x1A, 0xE7, 0x86, 0x5D, 0xA2, 0x3C, - 0x5D, 0x3F, 0x13, 0xC3, 0x16, 0x06, 0x3C, 0x7A, - 0xA1, 0xA9, 0x58, 0xE5, 0xBE, 0x83, 0x8F, 0x04 - }, - { - 0x29, 0x8D, 0xF6, 0x46, 0x91, 0x5F, 0x04, 0xD6, - 0x65, 0xE9, 0x67, 0x5E, 0x6A, 0x10, 0x31, 0x87, - 0x0D, 0x28, 0xEB, 0x7A, 0x04, 0x05, 0x66, 0x3E, - 0xAC, 0x3B, 0x10, 0xD1, 0xB4, 0xFA, 0x2E, 0x86, - 0x8E, 0x63, 0x73, 0xA5, 0x86, 0xCD, 0x73, 0xE0, - 0x6D, 0x8E, 0x7A, 0xD7, 0x71, 0xB4, 0xFB, 0x0A, - 0x8B, 0x4F, 0xC2, 0xDC, 0x6C, 0xE0, 0x9C, 0x64, - 0x2E, 0xE8, 0x99, 0x26, 0xFD, 0xC6, 0x52, 0x60 - }, - { - 0x4F, 0x2D, 0xE9, 0xC4, 0xF4, 0x34, 0x8B, 0xDB, - 0x32, 0x3A, 0x66, 0x83, 0x72, 0xE7, 0x71, 0x42, - 0x99, 0xC7, 0x76, 0xF9, 0x60, 0x2F, 0x3A, 0xF8, - 0xFB, 0x77, 0x46, 0xF1, 0x76, 0x86, 0x8D, 0xF3, - 0x54, 0x2B, 0x2F, 0xA6, 0x9E, 0xAE, 0x38, 0xB6, - 0xA2, 0x6A, 0x06, 0xCA, 0x89, 0x42, 0xF8, 0x82, - 0x78, 0xC6, 0x4E, 0x3D, 0x01, 0x7F, 0xEE, 0x67, - 0xA9, 0x4E, 0xA0, 0x23, 0xB2, 0xB5, 0xBE, 0x5F - }, - { - 0x40, 0x18, 0xC5, 0xEE, 0x90, 0x93, 0xA6, 0x81, - 0x11, 0x2F, 0x4C, 0xE1, 0x93, 0xA1, 0xD6, 0x5E, - 0x05, 0x48, 0x72, 0x5F, 0x96, 0xAE, 0x31, 0x53, - 0x87, 0xCD, 0x76, 0x5C, 0x2B, 0x9C, 0x30, 0x68, - 0xAE, 0x4C, 0xBE, 0x5C, 0xD5, 0x40, 0x2C, 0x11, - 0xC5, 0x5A, 0x9D, 0x78, 0x5F, 0xFD, 0xFC, 0x2B, - 0xDE, 0x6E, 0x7A, 0xCF, 0x19, 0x61, 0x74, 0x75, - 0xDA, 0xE0, 0xEB, 0x01, 0x44, 0x56, 0xCE, 0x45 - }, - { - 0x6F, 0xCE, 0x66, 0x75, 0xE8, 0x6D, 0x7E, 0x85, - 0x70, 0x4C, 0x96, 0xC2, 0x95, 0x70, 0x3C, 0xD9, - 0x54, 0x98, 0x59, 0x0E, 0x50, 0x76, 0x4D, 0x23, - 0xD7, 0xA7, 0xA3, 0xA3, 0x22, 0x68, 0xA0, 0xB3, - 0xC9, 0x91, 0xE8, 0xF7, 0x84, 0x87, 0x69, 0x9A, - 0x55, 0x4B, 0x58, 0x1E, 0x33, 0x9C, 0x09, 0xAE, - 0xC9, 0x82, 0xE0, 0xBA, 0xA4, 0x31, 0x87, 0x93, - 0x62, 0x06, 0x35, 0xE1, 0xE2, 0xC8, 0xD9, 0xF2 - }, - { - 0xEB, 0xA9, 0x37, 0x85, 0x91, 0x97, 0xC7, 0xFD, - 0x41, 0x2D, 0xBC, 0x9A, 0xFC, 0x0D, 0x67, 0xCC, - 0x19, 0x81, 0x60, 0xB5, 0xA9, 0xCC, 0xEE, 0x87, - 0xC4, 0x1A, 0x86, 0x64, 0x85, 0x9F, 0x3E, 0xFD, - 0x96, 0x13, 0x66, 0xA8, 0x09, 0xC7, 0xC6, 0xBC, - 0x6F, 0xA8, 0x44, 0x92, 0x68, 0x14, 0xE0, 0xB4, - 0xEF, 0xA3, 0x7E, 0xDE, 0x2C, 0x88, 0x44, 0x26, - 0x8D, 0x7F, 0x35, 0x56, 0xE4, 0x46, 0x58, 0x1D - }, - { - 0x83, 0xF4, 0x33, 0xE4, 0xF1, 0xC5, 0x07, 0x97, - 0x49, 0x3C, 0x58, 0xC2, 0x64, 0xCF, 0xFA, 0x70, - 0xC4, 0xA7, 0xA2, 0x4C, 0x33, 0x4D, 0xBA, 0xA3, - 0xC5, 0x74, 0x89, 0xD9, 0x70, 0xD4, 0x9D, 0x69, - 0x49, 0xFE, 0x45, 0xB7, 0x04, 0xF2, 0x65, 0xEF, - 0xD2, 0xAE, 0xE1, 0xAC, 0x1B, 0x46, 0xF4, 0xAA, - 0x3E, 0x4F, 0xAD, 0x68, 0xB3, 0x79, 0x61, 0xD2, - 0xC7, 0x28, 0x0A, 0xE1, 0x96, 0x72, 0xC8, 0x50 - }, - { - 0xB5, 0x57, 0xEC, 0xE1, 0x22, 0x72, 0x49, 0x3D, - 0xC2, 0x7E, 0x88, 0xA0, 0x5A, 0xDC, 0xD8, 0x61, - 0x87, 0x5A, 0x0C, 0xD0, 0x0B, 0xD6, 0x8A, 0xDC, - 0x3A, 0x30, 0x1D, 0x26, 0x3A, 0x9C, 0xD9, 0x93, - 0xA9, 0x6A, 0xE1, 0x4C, 0xFC, 0xDD, 0xCB, 0x99, - 0x7C, 0xC9, 0x86, 0x23, 0x93, 0x50, 0x50, 0xEA, - 0x43, 0x55, 0x2A, 0x34, 0x11, 0x07, 0x18, 0x7D, - 0xE7, 0x5C, 0x4E, 0xDE, 0xD7, 0xC7, 0x86, 0xBD - }, - { - 0x95, 0x89, 0xC0, 0x81, 0x3B, 0x73, 0x93, 0xDB, - 0xAA, 0xAF, 0xE4, 0x7A, 0xF5, 0xB4, 0x08, 0xB2, - 0x3C, 0x8A, 0x8C, 0x8B, 0xAC, 0x62, 0x55, 0x4B, - 0x8F, 0xA1, 0x32, 0xA3, 0x58, 0xCE, 0x30, 0x83, - 0xB1, 0xD4, 0xE3, 0x97, 0x07, 0xCD, 0x54, 0xA5, - 0x5F, 0x67, 0x3D, 0x48, 0x11, 0x6E, 0xB1, 0xF9, - 0xED, 0x8D, 0xE9, 0xC9, 0x43, 0xCD, 0x2D, 0xE4, - 0x60, 0xA6, 0x8B, 0xDD, 0xF7, 0x1E, 0x98, 0x03 - }, - { - 0xAE, 0x4C, 0xCF, 0x27, 0xAB, 0x00, 0xA4, 0x0C, - 0x36, 0x37, 0xD3, 0xD2, 0xCE, 0x51, 0xA8, 0x3E, - 0xFB, 0xA6, 0x2D, 0x4A, 0x6F, 0xDA, 0xD6, 0x95, - 0x06, 0x3F, 0xBC, 0x60, 0xA2, 0xD8, 0x2E, 0xC5, - 0xA5, 0x4A, 0xCB, 0xE0, 0x9B, 0xA9, 0x38, 0x8F, - 0x49, 0xAA, 0xC2, 0x7C, 0x99, 0x2D, 0x84, 0x63, - 0x20, 0x36, 0xE1, 0xBD, 0xD4, 0xC5, 0x29, 0xBB, - 0xF1, 0x85, 0x1E, 0xAE, 0x0C, 0x6E, 0xA9, 0x02 - }, - { - 0xA3, 0x94, 0x4B, 0x2C, 0x31, 0xCB, 0x49, 0x40, - 0x80, 0xB7, 0xEE, 0x1D, 0xB0, 0x81, 0x68, 0x53, - 0xE4, 0x25, 0xB5, 0x4C, 0x48, 0xD6, 0x31, 0x44, - 0x7E, 0xA5, 0x2C, 0x1D, 0x29, 0x52, 0x07, 0x9B, - 0xD8, 0x8F, 0xAB, 0x9E, 0xD0, 0xB7, 0xD8, 0xC0, - 0xBA, 0xAF, 0x0C, 0x4E, 0xCA, 0x19, 0x10, 0xDB, - 0x6F, 0x98, 0x53, 0x4F, 0x0D, 0x42, 0xE5, 0xEB, - 0xB6, 0xC0, 0xA7, 0x5E, 0xF0, 0xD8, 0xB2, 0xC0 - }, - { - 0xCF, 0xA1, 0xA2, 0x24, 0x68, 0x5A, 0x5F, 0xB2, - 0x01, 0x04, 0x58, 0x20, 0x1C, 0xEB, 0x0C, 0xDA, - 0x21, 0xC8, 0x2B, 0x16, 0x02, 0xDC, 0x41, 0x35, - 0x85, 0xFB, 0xCE, 0x80, 0x97, 0x6F, 0x06, 0x1C, - 0x23, 0x5B, 0x13, 0x67, 0x71, 0x24, 0x98, 0x14, - 0x4A, 0xC1, 0x6A, 0x98, 0x54, 0xF6, 0xFB, 0x32, - 0x3C, 0xBE, 0xB6, 0x23, 0x69, 0xCF, 0x9B, 0x75, - 0x2B, 0x92, 0x52, 0xA2, 0xA7, 0xAC, 0xE1, 0xFD - }, - { - 0xFA, 0x62, 0xC6, 0xCF, 0xC8, 0xF0, 0x79, 0xE5, - 0x8F, 0x3D, 0x3F, 0xEF, 0xD7, 0xC2, 0x24, 0xE7, - 0x1E, 0xBC, 0x69, 0xA9, 0x5B, 0x18, 0x35, 0xCC, - 0xC3, 0x2F, 0x35, 0x07, 0x77, 0x05, 0x11, 0x02, - 0x61, 0x54, 0x92, 0xD6, 0x7F, 0xB6, 0xDE, 0x62, - 0xCF, 0x2A, 0xD5, 0xB1, 0x84, 0x67, 0xFE, 0x87, - 0x15, 0x74, 0x88, 0x82, 0xDB, 0x89, 0xFF, 0x86, - 0xEF, 0xDF, 0x2F, 0x96, 0xF8, 0x13, 0x5E, 0xD2 - }, - { - 0xCC, 0x63, 0x3F, 0xD4, 0xEA, 0x6A, 0xC4, 0x08, - 0xC3, 0x87, 0x57, 0x56, 0xB9, 0x01, 0x28, 0x8A, - 0x1D, 0xE1, 0x91, 0x89, 0x28, 0x32, 0xBE, 0x2E, - 0x90, 0x26, 0xDC, 0x65, 0xC2, 0xFF, 0x00, 0x00, - 0x9F, 0x14, 0x36, 0xDD, 0xFF, 0x42, 0x06, 0x26, - 0x0A, 0x3D, 0x66, 0xEF, 0x61, 0x92, 0x14, 0x3E, - 0x57, 0x2F, 0x1E, 0x4B, 0xB8, 0xE5, 0xA7, 0x4B, - 0x12, 0x05, 0x5E, 0x42, 0x41, 0x1C, 0x18, 0xBC - }, - { - 0x44, 0xD2, 0xBF, 0x7F, 0x36, 0x96, 0xB8, 0x93, - 0x3F, 0x25, 0x5B, 0x9B, 0xE1, 0xA4, 0xA6, 0xAE, - 0x33, 0x16, 0xC2, 0x5D, 0x03, 0x95, 0xF5, 0x90, - 0xB9, 0xB9, 0x89, 0x8F, 0x12, 0x7E, 0x40, 0xD3, - 0xF4, 0x12, 0x4D, 0x7B, 0xDB, 0xC8, 0x72, 0x5F, - 0x00, 0xB0, 0xD2, 0x81, 0x50, 0xFF, 0x05, 0xB4, - 0xA7, 0x9E, 0x5E, 0x04, 0xE3, 0x4A, 0x47, 0xE9, - 0x08, 0x7B, 0x3F, 0x79, 0xD4, 0x13, 0xAB, 0x7F - }, - { - 0x96, 0xFB, 0xCB, 0xB6, 0x0B, 0xD3, 0x13, 0xB8, - 0x84, 0x50, 0x33, 0xE5, 0xBC, 0x05, 0x8A, 0x38, - 0x02, 0x74, 0x38, 0x57, 0x2D, 0x7E, 0x79, 0x57, - 0xF3, 0x68, 0x4F, 0x62, 0x68, 0xAA, 0xDD, 0x3A, - 0xD0, 0x8D, 0x21, 0x76, 0x7E, 0xD6, 0x87, 0x86, - 0x85, 0x33, 0x1B, 0xA9, 0x85, 0x71, 0x48, 0x7E, - 0x12, 0x47, 0x0A, 0xAD, 0x66, 0x93, 0x26, 0x71, - 0x6E, 0x46, 0x66, 0x7F, 0x69, 0xF8, 0xD7, 0xE8 - }, -}; - - - - -#endif - - - diff --git a/Modules/_blake2/impl/blake2b-test.c b/Modules/_blake2/impl/blake2b-test.c deleted file mode 100644 index 9310a273a51728..00000000000000 --- a/Modules/_blake2/impl/blake2b-test.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - BLAKE2 reference source code package - optimized C implementations - - Written in 2012 by Samuel Neves - - To the extent possible under law, the author(s) have dedicated all copyright - and related and neighboring rights to this software to the public domain - worldwide. This software is distributed without any warranty. - - You should have received a copy of the CC0 Public Domain Dedication along with - this software. If not, see . -*/ -#include -#include -#include "blake2.h" -#include "blake2-kat.h" -int main( int argc, char **argv ) -{ - uint8_t key[BLAKE2B_KEYBYTES]; - uint8_t buf[KAT_LENGTH]; - - for( size_t i = 0; i < BLAKE2B_KEYBYTES; ++i ) - key[i] = ( uint8_t )i; - - for( size_t i = 0; i < KAT_LENGTH; ++i ) - buf[i] = ( uint8_t )i; - - for( size_t i = 0; i < KAT_LENGTH; ++i ) - { - uint8_t hash[BLAKE2B_OUTBYTES]; - - if( blake2b( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES ) < 0 || - 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) ) - { - puts( "error" ); - return -1; - } - } - - puts( "ok" ); - return 0; -} - diff --git a/Modules/_blake2/impl/blake2bp-test.c b/Modules/_blake2/impl/blake2bp-test.c deleted file mode 100644 index 849666cc1d5ecc..00000000000000 --- a/Modules/_blake2/impl/blake2bp-test.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - BLAKE2 reference source code package - optimized C implementations - - Written in 2012 by Samuel Neves - - To the extent possible under law, the author(s) have dedicated all copyright - and related and neighboring rights to this software to the public domain - worldwide. This software is distributed without any warranty. - - You should have received a copy of the CC0 Public Domain Dedication along with - this software. If not, see . -*/ -#include -#include -#include "blake2.h" -#include "blake2-kat.h" - -int main( int argc, char **argv ) -{ - uint8_t key[BLAKE2B_KEYBYTES]; - uint8_t buf[KAT_LENGTH]; - - for( size_t i = 0; i < BLAKE2B_KEYBYTES; ++i ) - key[i] = ( uint8_t )i; - - for( size_t i = 0; i < KAT_LENGTH; ++i ) - buf[i] = ( uint8_t )i; - - for( size_t i = 0; i < KAT_LENGTH; ++i ) - { - uint8_t hash[BLAKE2B_OUTBYTES]; - - if( blake2bp( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES ) < 0 || - 0 != memcmp( hash, blake2bp_keyed_kat[i], BLAKE2B_OUTBYTES ) ) - { - puts( "error" ); - return -1; - } - } - - puts( "ok" ); - return 0; -} - diff --git a/Modules/_blake2/impl/blake2bp.c b/Modules/_blake2/impl/blake2bp.c deleted file mode 100644 index 45221611710108..00000000000000 --- a/Modules/_blake2/impl/blake2bp.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - BLAKE2 reference source code package - optimized C implementations - - Written in 2012 by Samuel Neves - - To the extent possible under law, the author(s) have dedicated all copyright - and related and neighboring rights to this software to the public domain - worldwide. This software is distributed without any warranty. - - You should have received a copy of the CC0 Public Domain Dedication along with - this software. If not, see . -*/ - -#include -#include -#include -#include - -#if defined(_OPENMP) -#include -#endif - -#include "blake2.h" -#include "blake2-impl.h" - -#define PARALLELISM_DEGREE 4 - -static int blake2bp_init_leaf( blake2b_state *S, uint8_t outlen, uint8_t keylen, uint64_t offset ) -{ - blake2b_param P[1]; - P->digest_length = outlen; - P->key_length = keylen; - P->fanout = PARALLELISM_DEGREE; - P->depth = 2; - store32(&P->leaf_length, 0); - store64(&P->node_offset, offset); - P->node_depth = 0; - P->inner_length = BLAKE2B_OUTBYTES; - memset( P->reserved, 0, sizeof( P->reserved ) ); - memset( P->salt, 0, sizeof( P->salt ) ); - memset( P->personal, 0, sizeof( P->personal ) ); - blake2b_init_param( S, P ); - S->outlen = P->inner_length; - return 0; -} - -static int blake2bp_init_root( blake2b_state *S, uint8_t outlen, uint8_t keylen ) -{ - blake2b_param P[1]; - P->digest_length = outlen; - P->key_length = keylen; - P->fanout = PARALLELISM_DEGREE; - P->depth = 2; - store32(&P->leaf_length, 0); - store64(&P->node_offset, 0); - P->node_depth = 1; - P->inner_length = BLAKE2B_OUTBYTES; - memset( P->reserved, 0, sizeof( P->reserved ) ); - memset( P->salt, 0, sizeof( P->salt ) ); - memset( P->personal, 0, sizeof( P->personal ) ); - blake2b_init_param( S, P ); - S->outlen = P->digest_length; - return 0; -} - - -int blake2bp_init( blake2bp_state *S, size_t outlen ) -{ - if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; - - memset( S->buf, 0, sizeof( S->buf ) ); - S->buflen = 0; - - if( blake2bp_init_root( S->R, ( uint8_t ) outlen, 0 ) < 0 ) - return -1; - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - if( blake2bp_init_leaf( S->S[i], ( uint8_t ) outlen, 0, i ) < 0 ) return -1; - - S->R->last_node = 1; - S->S[PARALLELISM_DEGREE - 1]->last_node = 1; - S->outlen = ( uint8_t ) outlen; - return 0; -} - -int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen ) -{ - if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; - - if( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1; - - memset( S->buf, 0, sizeof( S->buf ) ); - S->buflen = 0; - - if( blake2bp_init_root( S->R, ( uint8_t ) outlen, ( uint8_t ) keylen ) < 0 ) - return -1; - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - if( blake2bp_init_leaf( S->S[i], ( uint8_t ) outlen, ( uint8_t ) keylen, i ) < 0 ) - return -1; - - S->R->last_node = 1; - S->S[PARALLELISM_DEGREE - 1]->last_node = 1; - S->outlen = ( uint8_t ) outlen; - { - uint8_t block[BLAKE2B_BLOCKBYTES]; - memset( block, 0, BLAKE2B_BLOCKBYTES ); - memcpy( block, key, keylen ); - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - blake2b_update( S->S[i], block, BLAKE2B_BLOCKBYTES ); - - secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ - } - return 0; -} - - -int blake2bp_update( blake2bp_state *S, const uint8_t *in, size_t inlen ) -{ - size_t left = S->buflen; - size_t fill = sizeof( S->buf ) - left; - - if( left && inlen >= fill ) - { - memcpy( S->buf + left, in, fill ); - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); - - in += fill; - inlen -= fill; - left = 0; - } - -#if defined(_OPENMP) - omp_set_num_threads(PARALLELISM_DEGREE); - #pragma omp parallel shared(S) -#else - for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ ) -#endif - { -#if defined(_OPENMP) - size_t id__ = ( size_t ) omp_get_thread_num(); -#endif - size_t inlen__ = inlen; - const uint8_t *in__ = ( const uint8_t * )in; - in__ += id__ * BLAKE2B_BLOCKBYTES; - - while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ) - { - blake2b_update( S->S[id__], in__, BLAKE2B_BLOCKBYTES ); - in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; - inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; - } - } - - in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ); - inlen %= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; - - if( inlen > 0 ) - memcpy( S->buf + left, in, inlen ); - - S->buflen = ( uint32_t ) left + ( uint32_t ) inlen; - return 0; -} - - - -int blake2bp_final( blake2bp_state *S, uint8_t *out, size_t outlen ) -{ - uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES]; - - if(S->outlen != outlen) return -1; - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - { - if( S->buflen > i * BLAKE2B_BLOCKBYTES ) - { - size_t left = S->buflen - i * BLAKE2B_BLOCKBYTES; - - if( left > BLAKE2B_BLOCKBYTES ) left = BLAKE2B_BLOCKBYTES; - - blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, left ); - } - - blake2b_final( S->S[i], hash[i], BLAKE2B_OUTBYTES ); - } - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - blake2b_update( S->R, hash[i], BLAKE2B_OUTBYTES ); - - return blake2b_final( S->R, out, outlen ); -} - -int blake2bp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) -{ - uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES]; - blake2b_state S[PARALLELISM_DEGREE][1]; - blake2b_state FS[1]; - - /* Verify parameters */ - if ( NULL == in && inlen > 0 ) return -1; - - if ( NULL == out ) return -1; - - if ( NULL == key && keylen > 0) return -1; - - if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; - - if( keylen > BLAKE2B_KEYBYTES ) return -1; - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - if( blake2bp_init_leaf( S[i], ( uint8_t ) outlen, ( uint8_t ) keylen, i ) < 0 ) - return -1; - - S[PARALLELISM_DEGREE - 1]->last_node = 1; // mark last node - - if( keylen > 0 ) - { - uint8_t block[BLAKE2B_BLOCKBYTES]; - memset( block, 0, BLAKE2B_BLOCKBYTES ); - memcpy( block, key, keylen ); - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - blake2b_update( S[i], block, BLAKE2B_BLOCKBYTES ); - - secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ - } - -#if defined(_OPENMP) - omp_set_num_threads(PARALLELISM_DEGREE); - #pragma omp parallel shared(S,hash) -#else - for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ ) -#endif - { -#if defined(_OPENMP) - size_t id__ = ( size_t ) omp_get_thread_num(); -#endif - size_t inlen__ = inlen; - const uint8_t *in__ = ( const uint8_t * )in; - in__ += id__ * BLAKE2B_BLOCKBYTES; - - while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ) - { - blake2b_update( S[id__], in__, BLAKE2B_BLOCKBYTES ); - in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; - inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; - } - - if( inlen__ > id__ * BLAKE2B_BLOCKBYTES ) - { - const size_t left = inlen__ - id__ * BLAKE2B_BLOCKBYTES; - const size_t len = left <= BLAKE2B_BLOCKBYTES ? left : BLAKE2B_BLOCKBYTES; - blake2b_update( S[id__], in__, len ); - } - - blake2b_final( S[id__], hash[id__], BLAKE2B_OUTBYTES ); - } - - if( blake2bp_init_root( FS, ( uint8_t ) outlen, ( uint8_t ) keylen ) < 0 ) - return -1; - - FS->last_node = 1; // Mark as last node - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - blake2b_update( FS, hash[i], BLAKE2B_OUTBYTES ); - - return blake2b_final( FS, out, outlen ); -} - - - diff --git a/Modules/_blake2/impl/blake2s-test.c b/Modules/_blake2/impl/blake2s-test.c deleted file mode 100644 index 5c3f1f189d79cd..00000000000000 --- a/Modules/_blake2/impl/blake2s-test.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - BLAKE2 reference source code package - optimized C implementations - - Written in 2012 by Samuel Neves - - To the extent possible under law, the author(s) have dedicated all copyright - and related and neighboring rights to this software to the public domain - worldwide. This software is distributed without any warranty. - - You should have received a copy of the CC0 Public Domain Dedication along with - this software. If not, see . -*/ -#include -#include -#include "blake2.h" -#include "blake2-kat.h" -int main( int argc, char **argv ) -{ - uint8_t key[BLAKE2S_KEYBYTES]; - uint8_t buf[KAT_LENGTH]; - - for( size_t i = 0; i < BLAKE2S_KEYBYTES; ++i ) - key[i] = ( uint8_t )i; - - for( size_t i = 0; i < KAT_LENGTH; ++i ) - buf[i] = ( uint8_t )i; - - for( size_t i = 0; i < KAT_LENGTH; ++i ) - { - uint8_t hash[BLAKE2S_OUTBYTES]; - - if( blake2s( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES ) < 0 || - 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) ) - { - puts( "error" ); - return -1; - } - } - - puts( "ok" ); - return 0; -} - diff --git a/Modules/_blake2/impl/blake2sp-test.c b/Modules/_blake2/impl/blake2sp-test.c deleted file mode 100644 index 621e3506cfbdf7..00000000000000 --- a/Modules/_blake2/impl/blake2sp-test.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - BLAKE2 reference source code package - optimized C implementations - - Written in 2012 by Samuel Neves - - To the extent possible under law, the author(s) have dedicated all copyright - and related and neighboring rights to this software to the public domain - worldwide. This software is distributed without any warranty. - - You should have received a copy of the CC0 Public Domain Dedication along with - this software. If not, see . -*/ -#include -#include -#include "blake2.h" -#include "blake2-kat.h" - -int main( int argc, char **argv ) -{ - uint8_t key[BLAKE2S_KEYBYTES]; - uint8_t buf[KAT_LENGTH]; - - for( size_t i = 0; i < BLAKE2S_KEYBYTES; ++i ) - key[i] = ( uint8_t )i; - - for( size_t i = 0; i < KAT_LENGTH; ++i ) - buf[i] = ( uint8_t )i; - - for( size_t i = 0; i < KAT_LENGTH; ++i ) - { - uint8_t hash[BLAKE2S_OUTBYTES]; - if( blake2sp( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES ) < 0 || - 0 != memcmp( hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES ) ) - { - puts( "error" ); - return -1; - } - } - - puts( "ok" ); - return 0; -} - diff --git a/Modules/_blake2/impl/blake2sp.c b/Modules/_blake2/impl/blake2sp.c deleted file mode 100644 index 2f32bf3a226bf6..00000000000000 --- a/Modules/_blake2/impl/blake2sp.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - BLAKE2 reference source code package - optimized C implementations - - Written in 2012 by Samuel Neves - - To the extent possible under law, the author(s) have dedicated all copyright - and related and neighboring rights to this software to the public domain - worldwide. This software is distributed without any warranty. - - You should have received a copy of the CC0 Public Domain Dedication along with - this software. If not, see . -*/ - -#include -#include -#include - -#if defined(_OPENMP) -#include -#endif - -#include "blake2.h" -#include "blake2-impl.h" - -#define PARALLELISM_DEGREE 8 - -static int blake2sp_init_leaf( blake2s_state *S, uint8_t outlen, uint8_t keylen, uint64_t offset ) -{ - blake2s_param P[1]; - P->digest_length = outlen; - P->key_length = keylen; - P->fanout = PARALLELISM_DEGREE; - P->depth = 2; - P->leaf_length = 0; - store48( P->node_offset, offset ); - P->node_depth = 0; - P->inner_length = BLAKE2S_OUTBYTES; - memset( P->salt, 0, sizeof( P->salt ) ); - memset( P->personal, 0, sizeof( P->personal ) ); - blake2s_init_param( S, P ); - S->outlen = P->inner_length; - return 0; -} - -static int blake2sp_init_root( blake2s_state *S, uint8_t outlen, uint8_t keylen ) -{ - blake2s_param P[1]; - P->digest_length = outlen; - P->key_length = keylen; - P->fanout = PARALLELISM_DEGREE; - P->depth = 2; - P->leaf_length = 0; - store48( P->node_offset, 0ULL ); - P->node_depth = 1; - P->inner_length = BLAKE2S_OUTBYTES; - memset( P->salt, 0, sizeof( P->salt ) ); - memset( P->personal, 0, sizeof( P->personal ) ); - blake2s_init_param( S, P ); - S->outlen = P->digest_length; - return 0; -} - - -int blake2sp_init( blake2sp_state *S, size_t outlen ) -{ - if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; - - memset( S->buf, 0, sizeof( S->buf ) ); - S->buflen = 0; - - if( blake2sp_init_root( S->R, ( uint8_t ) outlen, 0 ) < 0 ) - return -1; - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - if( blake2sp_init_leaf( S->S[i], ( uint8_t ) outlen, 0, i ) < 0 ) return -1; - - S->R->last_node = 1; - S->S[PARALLELISM_DEGREE - 1]->last_node = 1; - S->outlen = ( uint8_t ) outlen; - return 0; -} - -int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen ) -{ - if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; - - if( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1; - - memset( S->buf, 0, sizeof( S->buf ) ); - S->buflen = 0; - - if( blake2sp_init_root( S->R, ( uint8_t ) outlen, ( uint8_t ) keylen ) < 0 ) - return -1; - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - if( blake2sp_init_leaf( S->S[i], ( uint8_t ) outlen, ( uint8_t ) keylen, i ) < 0 ) - return -1; - - S->R->last_node = 1; - S->S[PARALLELISM_DEGREE - 1]->last_node = 1; - S->outlen = ( uint8_t ) outlen; - { - uint8_t block[BLAKE2S_BLOCKBYTES]; - memset( block, 0, BLAKE2S_BLOCKBYTES ); - memcpy( block, key, keylen ); - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - blake2s_update( S->S[i], block, BLAKE2S_BLOCKBYTES ); - - secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ - } - return 0; -} - - -int blake2sp_update( blake2sp_state *S, const uint8_t *in, size_t inlen ) -{ - size_t left = S->buflen; - size_t fill = sizeof( S->buf ) - left; - - if( left && inlen >= fill ) - { - memcpy( S->buf + left, in, fill ); - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); - - in += fill; - inlen -= fill; - left = 0; - } - -#if defined(_OPENMP) - omp_set_num_threads(PARALLELISM_DEGREE); - #pragma omp parallel shared(S) -#else - for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ ) -#endif - { -#if defined(_OPENMP) - size_t id__ = ( size_t ) omp_get_thread_num(); -#endif - size_t inlen__ = inlen; - const uint8_t *in__ = ( const uint8_t * )in; - in__ += id__ * BLAKE2S_BLOCKBYTES; - - while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ) - { - blake2s_update( S->S[id__], in__, BLAKE2S_BLOCKBYTES ); - in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; - inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; - } - } - - in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ); - inlen %= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; - - if( inlen > 0 ) - memcpy( S->buf + left, in, inlen ); - - S->buflen = ( uint32_t ) left + ( uint32_t ) inlen; - return 0; -} - - -int blake2sp_final( blake2sp_state *S, uint8_t *out, size_t outlen ) -{ - uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES]; - - if(S->outlen != outlen) return -1; - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - { - if( S->buflen > i * BLAKE2S_BLOCKBYTES ) - { - size_t left = S->buflen - i * BLAKE2S_BLOCKBYTES; - - if( left > BLAKE2S_BLOCKBYTES ) left = BLAKE2S_BLOCKBYTES; - - blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, left ); - } - - blake2s_final( S->S[i], hash[i], BLAKE2S_OUTBYTES ); - } - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - blake2s_update( S->R, hash[i], BLAKE2S_OUTBYTES ); - - blake2s_final( S->R, out, outlen ); - return 0; -} - - -int blake2sp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) -{ - uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES]; - blake2s_state S[PARALLELISM_DEGREE][1]; - blake2s_state FS[1]; - - /* Verify parameters */ - if ( NULL == in && inlen > 0 ) return -1; - - if ( NULL == out ) return -1; - - if ( NULL == key && keylen > 0 ) return -1; - - if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; - - if( keylen > BLAKE2S_KEYBYTES ) return -1; - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - if( blake2sp_init_leaf( S[i], ( uint8_t ) outlen, ( uint8_t ) keylen, i ) < 0 ) - return -1; - - S[PARALLELISM_DEGREE - 1]->last_node = 1; // mark last node - - if( keylen > 0 ) - { - uint8_t block[BLAKE2S_BLOCKBYTES]; - memset( block, 0, BLAKE2S_BLOCKBYTES ); - memcpy( block, key, keylen ); - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - blake2s_update( S[i], block, BLAKE2S_BLOCKBYTES ); - - secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ - } - -#if defined(_OPENMP) - omp_set_num_threads(PARALLELISM_DEGREE); - #pragma omp parallel shared(S,hash) -#else - - for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ ) -#endif - { -#if defined(_OPENMP) - size_t id__ = ( size_t ) omp_get_thread_num(); -#endif - size_t inlen__ = inlen; - const uint8_t *in__ = ( const uint8_t * )in; - in__ += id__ * BLAKE2S_BLOCKBYTES; - - while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ) - { - blake2s_update( S[id__], in__, BLAKE2S_BLOCKBYTES ); - in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; - inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; - } - - if( inlen__ > id__ * BLAKE2S_BLOCKBYTES ) - { - const size_t left = inlen__ - id__ * BLAKE2S_BLOCKBYTES; - const size_t len = left <= BLAKE2S_BLOCKBYTES ? left : BLAKE2S_BLOCKBYTES; - blake2s_update( S[id__], in__, len ); - } - - blake2s_final( S[id__], hash[id__], BLAKE2S_OUTBYTES ); - } - - if( blake2sp_init_root( FS, ( uint8_t ) outlen, ( uint8_t ) keylen ) < 0 ) - return -1; - - FS->last_node = 1; - - for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) - blake2s_update( FS, hash[i], BLAKE2S_OUTBYTES ); - - return blake2s_final( FS, out, outlen ); -} - - - - diff --git a/configure b/configure index 00f5c7ba4cc728..17f52996f4fd75 100755 --- a/configure +++ b/configure @@ -777,6 +777,8 @@ MODULE__IO_TRUE MODULES_SETUP_STDLIB MODULE_BUILDTYPE TEST_MODULES +LIBB2_LIBS +LIBB2_CFLAGS OPENSSL_RPATH OPENSSL_LDFLAGS OPENSSL_LIBS @@ -1084,7 +1086,9 @@ BZIP2_LIBS LIBLZMA_CFLAGS LIBLZMA_LIBS LIBCRYPT_CFLAGS -LIBCRYPT_LIBS' +LIBCRYPT_LIBS +LIBB2_CFLAGS +LIBB2_LIBS' # Initialize some variables set by options. @@ -1891,6 +1895,9 @@ Some influential environment variables: C compiler flags for LIBCRYPT, overriding pkg-config LIBCRYPT_LIBS linker flags for LIBCRYPT, overriding pkg-config + LIBB2_CFLAGS + C compiler flags for LIBB2, overriding pkg-config + LIBB2_LIBS linker flags for LIBB2, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. @@ -21340,6 +21347,87 @@ esac done IFS=$as_save_IFS +if test "x$with_builtin_blake2" = xyes; then : + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBB2" >&5 +$as_echo_n "checking for LIBB2... " >&6; } + +if test -n "$LIBB2_CFLAGS"; then + pkg_cv_LIBB2_CFLAGS="$LIBB2_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libb2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libb2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBB2_CFLAGS=`$PKG_CONFIG --cflags "libb2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBB2_LIBS"; then + pkg_cv_LIBB2_LIBS="$LIBB2_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libb2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libb2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBB2_LIBS=`$PKG_CONFIG --libs "libb2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBB2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libb2" 2>&1` + else + LIBB2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libb2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBB2_PKG_ERRORS" >&5 + + have_libb2=no +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + have_libb2=no +else + LIBB2_CFLAGS=$pkg_cv_LIBB2_CFLAGS + LIBB2_LIBS=$pkg_cv_LIBB2_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + + have_libb2=yes + +$as_echo "#define HAVE_LIBB2 1" >>confdefs.h + + +fi + +fi + # --with-experimental-isolated-subinterpreters { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-experimental-isolated-subinterpreters" >&5 @@ -22915,8 +23003,8 @@ fi as_fn_append MODULE_BLOCK "MODULE__BLAKE2=$py_cv_module__blake2$as_nl" if test "x$py_cv_module__blake2" = xyes; then : - - + as_fn_append MODULE_BLOCK "MODULE__BLAKE2_CFLAGS=$LIBB2_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__BLAKE2_LDFLAGS=$LIBB2_LIBS$as_nl" fi if test "$py_cv_module__blake2" = yes; then diff --git a/configure.ac b/configure.ac index 094866136dda72..566ff80aed3c7f 100644 --- a/configure.ac +++ b/configure.ac @@ -6391,6 +6391,15 @@ for builtin_hash in $with_builtin_hashlib_hashes; do done IFS=$as_save_IFS +dnl libb2 for blake2. _blake2 module falls back to vendored copy. +AS_VAR_IF([with_builtin_blake2], [yes], [ + PKG_CHECK_MODULES([LIBB2], [libb2], [ + have_libb2=yes + AC_DEFINE([HAVE_LIBB2], [1], + [Define to 1 if you want to build _blake2 module with libb2]) + ], [have_libb2=no]) +]) + # --with-experimental-isolated-subinterpreters AH_TEMPLATE(EXPERIMENTAL_ISOLATED_SUBINTERPRETERS, [Better isolate subinterpreters, experimental build mode.]) @@ -6668,7 +6677,9 @@ PY_STDLIB_MOD([_sha1], [test "$with_builtin_sha1" = yes]) PY_STDLIB_MOD([_sha256], [test "$with_builtin_sha256" = yes]) PY_STDLIB_MOD([_sha512], [test "$with_builtin_sha512" = yes]) PY_STDLIB_MOD([_sha3], [test "$with_builtin_sha3" = yes]) -PY_STDLIB_MOD([_blake2], [test "$with_builtin_blake2" = yes]) +PY_STDLIB_MOD([_blake2], + [test "$with_builtin_blake2" = yes], [], + [$LIBB2_CFLAGS], [$LIBB2_LIBS]) PY_STDLIB_MOD([_crypt], [], [test "$ac_cv_crypt_crypt" = yes], diff --git a/pyconfig.h.in b/pyconfig.h.in index ccbf90041d1c46..ba77a27333d0c3 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -622,6 +622,9 @@ /* Define to 1 if you have the `lchown' function. */ #undef HAVE_LCHOWN +/* Define to 1 if you want to build _blake2 module with libb2 */ +#undef HAVE_LIBB2 + /* Define to 1 if you have the `db' library (-ldb). */ #undef HAVE_LIBDB From webhook-mailer at python.org Sat Mar 26 16:36:14 2022 From: webhook-mailer at python.org (tiran) Date: Sat, 26 Mar 2022 20:36:14 -0000 Subject: [Python-checkins] bpo-47098: Replace Keccak Code Package with tiny_sha3 (GH-32060) Message-ID: https://github.com/python/cpython/commit/5fd8c574e016aec85725ddc5ced8742267b0e1b3 commit: 5fd8c574e016aec85725ddc5ced8742267b0e1b3 branch: main author: Christian Heimes committer: tiran date: 2022-03-26T21:36:08+01:00 summary: bpo-47098: Replace Keccak Code Package with tiny_sha3 (GH-32060) files: A Misc/NEWS.d/next/Library/2022-03-23-10-07-41.bpo-47098.7AN_qp.rst A Modules/_sha3/LICENSE A Modules/_sha3/sha3.c A Modules/_sha3/sha3.h D Modules/_sha3/cleanup.py D Modules/_sha3/kcp/KeccakHash.c D Modules/_sha3/kcp/KeccakHash.h D Modules/_sha3/kcp/KeccakP-1600-64.macros D Modules/_sha3/kcp/KeccakP-1600-SnP-opt32.h D Modules/_sha3/kcp/KeccakP-1600-SnP-opt64.h D Modules/_sha3/kcp/KeccakP-1600-SnP.h D Modules/_sha3/kcp/KeccakP-1600-inplace32BI.c D Modules/_sha3/kcp/KeccakP-1600-opt64-config.h D Modules/_sha3/kcp/KeccakP-1600-opt64.c D Modules/_sha3/kcp/KeccakP-1600-unrolling.macros D Modules/_sha3/kcp/KeccakSponge.c D Modules/_sha3/kcp/KeccakSponge.h D Modules/_sha3/kcp/KeccakSponge.inc D Modules/_sha3/kcp/PlSnP-Fallback.inc D Modules/_sha3/kcp/SnP-Relaned.h D Modules/_sha3/kcp/align.h M Doc/whatsnew/3.11.rst M Makefile.pre.in M Modules/_sha3/README.txt M Modules/_sha3/sha3module.c diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 9a137f3ca99d8..41e4659b0f779 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -252,6 +252,13 @@ hashlib over Python's vendored copy. (Contributed by Christian Heimes in :issue:`47095`.) +* The internal ``_sha3`` module with SHA3 and SHAKE algorithms now uses + *tiny_sha3* instead of the *Keccak Code Package* to reduce code and binary + size. The :mod:`hashlib` module prefers optimized SHA3 and SHAKE + implementations from OpenSSL. The change affects only installations without + OpenSSL support. + (Contributed by Christian Heimes in :issue:`47098`.) + IDLE and idlelib ---------------- diff --git a/Makefile.pre.in b/Makefile.pre.in index ff7442af316e5..fb5dd6a066c7d 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -667,7 +667,6 @@ coverage-lcov: '*/Modules/_blake2/impl/*' \ '*/Modules/_ctypes/libffi*/*' \ '*/Modules/_decimal/libmpdec/*' \ - '*/Modules/_sha3/kcp/*' \ '*/Modules/expat/*' \ '*/Modules/zlib/*' \ '*/Include/*' \ @@ -2491,7 +2490,7 @@ MODULE__IO_DEPS=$(srcdir)/Modules/_io/_iomodule.h MODULE__MD5_DEPS=$(srcdir)/Modules/hashlib.h MODULE__SHA1_DEPS=$(srcdir)/Modules/hashlib.h MODULE__SHA256_DEPS=$(srcdir)/Modules/hashlib.h -MODULE__SHA3_DEPS=$(srcdir)/Modules/_sha3/kcp/KeccakHash.c $(srcdir)/Modules/_sha3/kcp/KeccakHash.h $(srcdir)/Modules/_sha3/kcp/KeccakP-1600-64.macros $(srcdir)/Modules/_sha3/kcp/KeccakP-1600-SnP-opt32.h $(srcdir)/Modules/_sha3/kcp/KeccakP-1600-SnP-opt64.h $(srcdir)/Modules/_sha3/kcp/KeccakP-1600-SnP.h $(srcdir)/Modules/_sha3/kcp/KeccakP-1600-inplace32BI.c $(srcdir)/Modules/_sha3/kcp/KeccakP-1600-opt64-config.h $(srcdir)/Modules/_sha3/kcp/KeccakP-1600-opt64.c $(srcdir)/Modules/_sha3/kcp/KeccakP-1600-unrolling.macros $(srcdir)/Modules/_sha3/kcp/KeccakSponge.c $(srcdir)/Modules/_sha3/kcp/KeccakSponge.h $(srcdir)/Modules/_sha3/kcp/KeccakSponge.inc $(srcdir)/Modules/_sha3/kcp/PlSnP-Fallback.inc $(srcdir)/Modules/_sha3/kcp/SnP-Relaned.h $(srcdir)/Modules/_sha3/kcp/align.h $(srcdir)/Modules/hashlib.h +MODULE__SHA3_DEPS=$(srcdir)/Modules/_sha3/sha3.c $(srcdir)/Modules/_sha3/sha3.h $(srcdir)/Modules/hashlib.h MODULE__SHA512_DEPS=$(srcdir)/Modules/hashlib.h MODULE__SOCKET_DEPS=$(srcdir)/Modules/socketmodule.h MODULE__SSL_DEPS=$(srcdir)/Modules/_ssl.h $(srcdir)/Modules/_ssl/cert.c $(srcdir)/Modules/_ssl/debughelpers.c $(srcdir)/Modules/_ssl/misc.c $(srcdir)/Modules/_ssl_data.h $(srcdir)/Modules/_ssl_data_111.h $(srcdir)/Modules/_ssl_data_300.h $(srcdir)/Modules/socketmodule.h diff --git a/Misc/NEWS.d/next/Library/2022-03-23-10-07-41.bpo-47098.7AN_qp.rst b/Misc/NEWS.d/next/Library/2022-03-23-10-07-41.bpo-47098.7AN_qp.rst new file mode 100644 index 0000000000000..dbb71bfb0f28b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-23-10-07-41.bpo-47098.7AN_qp.rst @@ -0,0 +1,3 @@ +The Keccak Code Package for :mod:`hashlib`'s internal ``_sha3`` module has +been replaced with tiny_sha3. The module is used as fallback when Python is +built without OpenSSL. diff --git a/Modules/_sha3/LICENSE b/Modules/_sha3/LICENSE new file mode 100644 index 0000000000000..d2d484d8820dc --- /dev/null +++ b/Modules/_sha3/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Markku-Juhani O. Saarinen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/Modules/_sha3/README.txt b/Modules/_sha3/README.txt index e34b1d12f702f..b35919b01677d 100644 --- a/Modules/_sha3/README.txt +++ b/Modules/_sha3/README.txt @@ -1,11 +1,8 @@ -Keccak Code Package -=================== +tiny_sha3 +========= -The files in kcp are taken from the Keccak Code Package. They have been -slightly to be C89 compatible. The architecture specific header file -KeccakP-1600-SnP.h ha been renamed to KeccakP-1600-SnP-opt32.h or -KeccakP-1600-SnP-opt64.h. - -The 64bit files were generated with generic64lc/libkeccak.a.pack target, the -32bit files with generic32lc/libkeccak.a.pack. +https://github.com/mjosaarinen/tiny_sha3 +commit dcbb3192047c2a721f5f851db591871d428036a9 +- All functions have been converted to static functions. +- sha3() function is commented out. diff --git a/Modules/_sha3/cleanup.py b/Modules/_sha3/cleanup.py deleted file mode 100755 index 4f53681b49e67..0000000000000 --- a/Modules/_sha3/cleanup.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2012 Christian Heimes (christian at python.org) -# Licensed to PSF under a Contributor Agreement. -# -# cleanup Keccak sources - -import os -import re - -CPP1 = re.compile("^//(.*)") -CPP2 = re.compile(r"\ //(.*)") - -STATICS = ("void ", "int ", "HashReturn ", - "const UINT64 ", "UINT16 ", " int prefix##") - -HERE = os.path.dirname(os.path.abspath(__file__)) -KECCAK = os.path.join(HERE, "kcp") - -def getfiles(): - for name in os.listdir(KECCAK): - name = os.path.join(KECCAK, name) - if os.path.isfile(name): - yield name - -def cleanup(f): - buf = [] - for line in f: - # mark all functions and global data as static - #if line.startswith(STATICS): - # buf.append("static " + line) - # continue - # remove UINT64 typedef, we have our own - if line.startswith("typedef unsigned long long int"): - buf.append("/* %s */\n" % line.strip()) - continue - ## remove #include "brg_endian.h" - if "brg_endian.h" in line: - buf.append("/* %s */\n" % line.strip()) - continue - # transform C++ comments into ANSI C comments - line = CPP1.sub(r"/*\1 */\n", line) - line = CPP2.sub(r" /*\1 */\n", line) - buf.append(line) - return "".join(buf) - -for name in getfiles(): - with open(name) as f: - res = cleanup(f) - with open(name, "w") as f: - f.write(res) diff --git a/Modules/_sha3/kcp/KeccakHash.c b/Modules/_sha3/kcp/KeccakHash.c deleted file mode 100644 index e09fb43cacea1..0000000000000 --- a/Modules/_sha3/kcp/KeccakHash.c +++ /dev/null @@ -1,82 +0,0 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Micha?l Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#include -#include "KeccakHash.h" - -/* ---------------------------------------------------------------- */ - -HashReturn Keccak_HashInitialize(Keccak_HashInstance *instance, unsigned int rate, unsigned int capacity, unsigned int hashbitlen, unsigned char delimitedSuffix) -{ - HashReturn result; - - if (delimitedSuffix == 0) - return FAIL; - result = (HashReturn)KeccakWidth1600_SpongeInitialize(&instance->sponge, rate, capacity); - if (result != SUCCESS) - return result; - instance->fixedOutputLength = hashbitlen; - instance->delimitedSuffix = delimitedSuffix; - return SUCCESS; -} - -/* ---------------------------------------------------------------- */ - -HashReturn Keccak_HashUpdate(Keccak_HashInstance *instance, const BitSequence *data, DataLength databitlen) -{ - if ((databitlen % 8) == 0) - return (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, data, databitlen/8); - else { - HashReturn ret = (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, data, databitlen/8); - if (ret == SUCCESS) { - /* The last partial byte is assumed to be aligned on the least significant bits */ - - unsigned char lastByte = data[databitlen/8]; - /* Concatenate the last few bits provided here with those of the suffix */ - - unsigned short delimitedLastBytes = (unsigned short)((unsigned short)lastByte | ((unsigned short)instance->delimitedSuffix << (databitlen % 8))); - if ((delimitedLastBytes & 0xFF00) == 0x0000) { - instance->delimitedSuffix = delimitedLastBytes & 0xFF; - } - else { - unsigned char oneByte[1]; - oneByte[0] = delimitedLastBytes & 0xFF; - ret = (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, oneByte, 1); - instance->delimitedSuffix = (delimitedLastBytes >> 8) & 0xFF; - } - } - return ret; - } -} - -/* ---------------------------------------------------------------- */ - -HashReturn Keccak_HashFinal(Keccak_HashInstance *instance, BitSequence *hashval) -{ - HashReturn ret = (HashReturn)KeccakWidth1600_SpongeAbsorbLastFewBits(&instance->sponge, instance->delimitedSuffix); - if (ret == SUCCESS) - return (HashReturn)KeccakWidth1600_SpongeSqueeze(&instance->sponge, hashval, instance->fixedOutputLength/8); - else - return ret; -} - -/* ---------------------------------------------------------------- */ - -HashReturn Keccak_HashSqueeze(Keccak_HashInstance *instance, BitSequence *data, DataLength databitlen) -{ - if ((databitlen % 8) != 0) - return FAIL; - return (HashReturn)KeccakWidth1600_SpongeSqueeze(&instance->sponge, data, databitlen/8); -} diff --git a/Modules/_sha3/kcp/KeccakHash.h b/Modules/_sha3/kcp/KeccakHash.h deleted file mode 100644 index bbd3dc64a2285..0000000000000 --- a/Modules/_sha3/kcp/KeccakHash.h +++ /dev/null @@ -1,114 +0,0 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Micha?l Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#ifndef _KeccakHashInterface_h_ -#define _KeccakHashInterface_h_ - -#ifndef KeccakP1600_excluded - -#include "KeccakSponge.h" -#include - -typedef unsigned char BitSequence; -typedef size_t DataLength; -typedef enum { SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2 } HashReturn; - -typedef struct { - KeccakWidth1600_SpongeInstance sponge; - unsigned int fixedOutputLength; - unsigned char delimitedSuffix; -} Keccak_HashInstance; - -/** - * Function to initialize the Keccak[r, c] sponge function instance used in sequential hashing mode. - * @param hashInstance Pointer to the hash instance to be initialized. - * @param rate The value of the rate r. - * @param capacity The value of the capacity c. - * @param hashbitlen The desired number of output bits, - * or 0 for an arbitrarily-long output. - * @param delimitedSuffix Bits that will be automatically appended to the end - * of the input message, as in domain separation. - * This is a byte containing from 0 to 7 bits - * formatted like the @a delimitedData parameter of - * the Keccak_SpongeAbsorbLastFewBits() function. - * @pre One must have r+c=1600 and the rate a multiple of 8 bits in this implementation. - * @return SUCCESS if successful, FAIL otherwise. - */ -HashReturn Keccak_HashInitialize(Keccak_HashInstance *hashInstance, unsigned int rate, unsigned int capacity, unsigned int hashbitlen, unsigned char delimitedSuffix); - -/** Macro to initialize a SHAKE128 instance as specified in the FIPS 202 standard. - */ -#define Keccak_HashInitialize_SHAKE128(hashInstance) Keccak_HashInitialize(hashInstance, 1344, 256, 0, 0x1F) - -/** Macro to initialize a SHAKE256 instance as specified in the FIPS 202 standard. - */ -#define Keccak_HashInitialize_SHAKE256(hashInstance) Keccak_HashInitialize(hashInstance, 1088, 512, 0, 0x1F) - -/** Macro to initialize a SHA3-224 instance as specified in the FIPS 202 standard. - */ -#define Keccak_HashInitialize_SHA3_224(hashInstance) Keccak_HashInitialize(hashInstance, 1152, 448, 224, 0x06) - -/** Macro to initialize a SHA3-256 instance as specified in the FIPS 202 standard. - */ -#define Keccak_HashInitialize_SHA3_256(hashInstance) Keccak_HashInitialize(hashInstance, 1088, 512, 256, 0x06) - -/** Macro to initialize a SHA3-384 instance as specified in the FIPS 202 standard. - */ -#define Keccak_HashInitialize_SHA3_384(hashInstance) Keccak_HashInitialize(hashInstance, 832, 768, 384, 0x06) - -/** Macro to initialize a SHA3-512 instance as specified in the FIPS 202 standard. - */ -#define Keccak_HashInitialize_SHA3_512(hashInstance) Keccak_HashInitialize(hashInstance, 576, 1024, 512, 0x06) - -/** - * Function to give input data to be absorbed. - * @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize(). - * @param data Pointer to the input data. - * When @a databitLen is not a multiple of 8, the last bits of data must be - * in the least significant bits of the last byte (little-endian convention). - * @param databitLen The number of input bits provided in the input data. - * @pre In the previous call to Keccak_HashUpdate(), databitlen was a multiple of 8. - * @return SUCCESS if successful, FAIL otherwise. - */ -HashReturn Keccak_HashUpdate(Keccak_HashInstance *hashInstance, const BitSequence *data, DataLength databitlen); - -/** - * Function to call after all input blocks have been input and to get - * output bits if the length was specified when calling Keccak_HashInitialize(). - * @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize(). - * If @a hashbitlen was not 0 in the call to Keccak_HashInitialize(), the number of - * output bits is equal to @a hashbitlen. - * If @a hashbitlen was 0 in the call to Keccak_HashInitialize(), the output bits - * must be extracted using the Keccak_HashSqueeze() function. - * @param state Pointer to the state of the sponge function initialized by Init(). - * @param hashval Pointer to the buffer where to store the output data. - * @return SUCCESS if successful, FAIL otherwise. - */ -HashReturn Keccak_HashFinal(Keccak_HashInstance *hashInstance, BitSequence *hashval); - - /** - * Function to squeeze output data. - * @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize(). - * @param data Pointer to the buffer where to store the output data. - * @param databitlen The number of output bits desired (must be a multiple of 8). - * @pre Keccak_HashFinal() must have been already called. - * @pre @a databitlen is a multiple of 8. - * @return SUCCESS if successful, FAIL otherwise. - */ -HashReturn Keccak_HashSqueeze(Keccak_HashInstance *hashInstance, BitSequence *data, DataLength databitlen); - -#endif - -#endif diff --git a/Modules/_sha3/kcp/KeccakP-1600-64.macros b/Modules/_sha3/kcp/KeccakP-1600-64.macros deleted file mode 100644 index 1f11fe3e79fbb..0000000000000 --- a/Modules/_sha3/kcp/KeccakP-1600-64.macros +++ /dev/null @@ -1,2208 +0,0 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Micha?l Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#define declareABCDE \ - UINT64 Aba, Abe, Abi, Abo, Abu; \ - UINT64 Aga, Age, Agi, Ago, Agu; \ - UINT64 Aka, Ake, Aki, Ako, Aku; \ - UINT64 Ama, Ame, Ami, Amo, Amu; \ - UINT64 Asa, Ase, Asi, Aso, Asu; \ - UINT64 Bba, Bbe, Bbi, Bbo, Bbu; \ - UINT64 Bga, Bge, Bgi, Bgo, Bgu; \ - UINT64 Bka, Bke, Bki, Bko, Bku; \ - UINT64 Bma, Bme, Bmi, Bmo, Bmu; \ - UINT64 Bsa, Bse, Bsi, Bso, Bsu; \ - UINT64 Ca, Ce, Ci, Co, Cu; \ - UINT64 Da, De, Di, Do, Du; \ - UINT64 Eba, Ebe, Ebi, Ebo, Ebu; \ - UINT64 Ega, Ege, Egi, Ego, Egu; \ - UINT64 Eka, Eke, Eki, Eko, Eku; \ - UINT64 Ema, Eme, Emi, Emo, Emu; \ - UINT64 Esa, Ese, Esi, Eso, Esu; \ - -#define prepareTheta \ - Ca = Aba^Aga^Aka^Ama^Asa; \ - Ce = Abe^Age^Ake^Ame^Ase; \ - Ci = Abi^Agi^Aki^Ami^Asi; \ - Co = Abo^Ago^Ako^Amo^Aso; \ - Cu = Abu^Agu^Aku^Amu^Asu; \ - -#ifdef UseBebigokimisa -/* --- Code for round, with prepare-theta (lane complementing pattern 'bebigokimisa') */ - -/* --- 64-bit lanes mapped to 64-bit words */ - -#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ - Da = Cu^ROL64(Ce, 1); \ - De = Ca^ROL64(Ci, 1); \ - Di = Ce^ROL64(Co, 1); \ - Do = Ci^ROL64(Cu, 1); \ - Du = Co^ROL64(Ca, 1); \ -\ - A##ba ^= Da; \ - Bba = A##ba; \ - A##ge ^= De; \ - Bbe = ROL64(A##ge, 44); \ - A##ki ^= Di; \ - Bbi = ROL64(A##ki, 43); \ - A##mo ^= Do; \ - Bbo = ROL64(A##mo, 21); \ - A##su ^= Du; \ - Bbu = ROL64(A##su, 14); \ - E##ba = Bba ^( Bbe | Bbi ); \ - E##ba ^= KeccakF1600RoundConstants[i]; \ - Ca = E##ba; \ - E##be = Bbe ^((~Bbi)| Bbo ); \ - Ce = E##be; \ - E##bi = Bbi ^( Bbo & Bbu ); \ - Ci = E##bi; \ - E##bo = Bbo ^( Bbu | Bba ); \ - Co = E##bo; \ - E##bu = Bbu ^( Bba & Bbe ); \ - Cu = E##bu; \ -\ - A##bo ^= Do; \ - Bga = ROL64(A##bo, 28); \ - A##gu ^= Du; \ - Bge = ROL64(A##gu, 20); \ - A##ka ^= Da; \ - Bgi = ROL64(A##ka, 3); \ - A##me ^= De; \ - Bgo = ROL64(A##me, 45); \ - A##si ^= Di; \ - Bgu = ROL64(A##si, 61); \ - E##ga = Bga ^( Bge | Bgi ); \ - Ca ^= E##ga; \ - E##ge = Bge ^( Bgi & Bgo ); \ - Ce ^= E##ge; \ - E##gi = Bgi ^( Bgo |(~Bgu)); \ - Ci ^= E##gi; \ - E##go = Bgo ^( Bgu | Bga ); \ - Co ^= E##go; \ - E##gu = Bgu ^( Bga & Bge ); \ - Cu ^= E##gu; \ -\ - A##be ^= De; \ - Bka = ROL64(A##be, 1); \ - A##gi ^= Di; \ - Bke = ROL64(A##gi, 6); \ - A##ko ^= Do; \ - Bki = ROL64(A##ko, 25); \ - A##mu ^= Du; \ - Bko = ROL64(A##mu, 8); \ - A##sa ^= Da; \ - Bku = ROL64(A##sa, 18); \ - E##ka = Bka ^( Bke | Bki ); \ - Ca ^= E##ka; \ - E##ke = Bke ^( Bki & Bko ); \ - Ce ^= E##ke; \ - E##ki = Bki ^((~Bko)& Bku ); \ - Ci ^= E##ki; \ - E##ko = (~Bko)^( Bku | Bka ); \ - Co ^= E##ko; \ - E##ku = Bku ^( Bka & Bke ); \ - Cu ^= E##ku; \ -\ - A##bu ^= Du; \ - Bma = ROL64(A##bu, 27); \ - A##ga ^= Da; \ - Bme = ROL64(A##ga, 36); \ - A##ke ^= De; \ - Bmi = ROL64(A##ke, 10); \ - A##mi ^= Di; \ - Bmo = ROL64(A##mi, 15); \ - A##so ^= Do; \ - Bmu = ROL64(A##so, 56); \ - E##ma = Bma ^( Bme & Bmi ); \ - Ca ^= E##ma; \ - E##me = Bme ^( Bmi | Bmo ); \ - Ce ^= E##me; \ - E##mi = Bmi ^((~Bmo)| Bmu ); \ - Ci ^= E##mi; \ - E##mo = (~Bmo)^( Bmu & Bma ); \ - Co ^= E##mo; \ - E##mu = Bmu ^( Bma | Bme ); \ - Cu ^= E##mu; \ -\ - A##bi ^= Di; \ - Bsa = ROL64(A##bi, 62); \ - A##go ^= Do; \ - Bse = ROL64(A##go, 55); \ - A##ku ^= Du; \ - Bsi = ROL64(A##ku, 39); \ - A##ma ^= Da; \ - Bso = ROL64(A##ma, 41); \ - A##se ^= De; \ - Bsu = ROL64(A##se, 2); \ - E##sa = Bsa ^((~Bse)& Bsi ); \ - Ca ^= E##sa; \ - E##se = (~Bse)^( Bsi | Bso ); \ - Ce ^= E##se; \ - E##si = Bsi ^( Bso & Bsu ); \ - Ci ^= E##si; \ - E##so = Bso ^( Bsu | Bsa ); \ - Co ^= E##so; \ - E##su = Bsu ^( Bsa & Bse ); \ - Cu ^= E##su; \ -\ - -/* --- Code for round (lane complementing pattern 'bebigokimisa') */ - -/* --- 64-bit lanes mapped to 64-bit words */ - -#define thetaRhoPiChiIota(i, A, E) \ - Da = Cu^ROL64(Ce, 1); \ - De = Ca^ROL64(Ci, 1); \ - Di = Ce^ROL64(Co, 1); \ - Do = Ci^ROL64(Cu, 1); \ - Du = Co^ROL64(Ca, 1); \ -\ - A##ba ^= Da; \ - Bba = A##ba; \ - A##ge ^= De; \ - Bbe = ROL64(A##ge, 44); \ - A##ki ^= Di; \ - Bbi = ROL64(A##ki, 43); \ - A##mo ^= Do; \ - Bbo = ROL64(A##mo, 21); \ - A##su ^= Du; \ - Bbu = ROL64(A##su, 14); \ - E##ba = Bba ^( Bbe | Bbi ); \ - E##ba ^= KeccakF1600RoundConstants[i]; \ - E##be = Bbe ^((~Bbi)| Bbo ); \ - E##bi = Bbi ^( Bbo & Bbu ); \ - E##bo = Bbo ^( Bbu | Bba ); \ - E##bu = Bbu ^( Bba & Bbe ); \ -\ - A##bo ^= Do; \ - Bga = ROL64(A##bo, 28); \ - A##gu ^= Du; \ - Bge = ROL64(A##gu, 20); \ - A##ka ^= Da; \ - Bgi = ROL64(A##ka, 3); \ - A##me ^= De; \ - Bgo = ROL64(A##me, 45); \ - A##si ^= Di; \ - Bgu = ROL64(A##si, 61); \ - E##ga = Bga ^( Bge | Bgi ); \ - E##ge = Bge ^( Bgi & Bgo ); \ - E##gi = Bgi ^( Bgo |(~Bgu)); \ - E##go = Bgo ^( Bgu | Bga ); \ - E##gu = Bgu ^( Bga & Bge ); \ -\ - A##be ^= De; \ - Bka = ROL64(A##be, 1); \ - A##gi ^= Di; \ - Bke = ROL64(A##gi, 6); \ - A##ko ^= Do; \ - Bki = ROL64(A##ko, 25); \ - A##mu ^= Du; \ - Bko = ROL64(A##mu, 8); \ - A##sa ^= Da; \ - Bku = ROL64(A##sa, 18); \ - E##ka = Bka ^( Bke | Bki ); \ - E##ke = Bke ^( Bki & Bko ); \ - E##ki = Bki ^((~Bko)& Bku ); \ - E##ko = (~Bko)^( Bku | Bka ); \ - E##ku = Bku ^( Bka & Bke ); \ -\ - A##bu ^= Du; \ - Bma = ROL64(A##bu, 27); \ - A##ga ^= Da; \ - Bme = ROL64(A##ga, 36); \ - A##ke ^= De; \ - Bmi = ROL64(A##ke, 10); \ - A##mi ^= Di; \ - Bmo = ROL64(A##mi, 15); \ - A##so ^= Do; \ - Bmu = ROL64(A##so, 56); \ - E##ma = Bma ^( Bme & Bmi ); \ - E##me = Bme ^( Bmi | Bmo ); \ - E##mi = Bmi ^((~Bmo)| Bmu ); \ - E##mo = (~Bmo)^( Bmu & Bma ); \ - E##mu = Bmu ^( Bma | Bme ); \ -\ - A##bi ^= Di; \ - Bsa = ROL64(A##bi, 62); \ - A##go ^= Do; \ - Bse = ROL64(A##go, 55); \ - A##ku ^= Du; \ - Bsi = ROL64(A##ku, 39); \ - A##ma ^= Da; \ - Bso = ROL64(A##ma, 41); \ - A##se ^= De; \ - Bsu = ROL64(A##se, 2); \ - E##sa = Bsa ^((~Bse)& Bsi ); \ - E##se = (~Bse)^( Bsi | Bso ); \ - E##si = Bsi ^( Bso & Bsu ); \ - E##so = Bso ^( Bsu | Bsa ); \ - E##su = Bsu ^( Bsa & Bse ); \ -\ - -#else /* UseBebigokimisa */ - -/* --- Code for round, with prepare-theta */ - -/* --- 64-bit lanes mapped to 64-bit words */ - -#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ - Da = Cu^ROL64(Ce, 1); \ - De = Ca^ROL64(Ci, 1); \ - Di = Ce^ROL64(Co, 1); \ - Do = Ci^ROL64(Cu, 1); \ - Du = Co^ROL64(Ca, 1); \ -\ - A##ba ^= Da; \ - Bba = A##ba; \ - A##ge ^= De; \ - Bbe = ROL64(A##ge, 44); \ - A##ki ^= Di; \ - Bbi = ROL64(A##ki, 43); \ - A##mo ^= Do; \ - Bbo = ROL64(A##mo, 21); \ - A##su ^= Du; \ - Bbu = ROL64(A##su, 14); \ - E##ba = Bba ^((~Bbe)& Bbi ); \ - E##ba ^= KeccakF1600RoundConstants[i]; \ - Ca = E##ba; \ - E##be = Bbe ^((~Bbi)& Bbo ); \ - Ce = E##be; \ - E##bi = Bbi ^((~Bbo)& Bbu ); \ - Ci = E##bi; \ - E##bo = Bbo ^((~Bbu)& Bba ); \ - Co = E##bo; \ - E##bu = Bbu ^((~Bba)& Bbe ); \ - Cu = E##bu; \ -\ - A##bo ^= Do; \ - Bga = ROL64(A##bo, 28); \ - A##gu ^= Du; \ - Bge = ROL64(A##gu, 20); \ - A##ka ^= Da; \ - Bgi = ROL64(A##ka, 3); \ - A##me ^= De; \ - Bgo = ROL64(A##me, 45); \ - A##si ^= Di; \ - Bgu = ROL64(A##si, 61); \ - E##ga = Bga ^((~Bge)& Bgi ); \ - Ca ^= E##ga; \ - E##ge = Bge ^((~Bgi)& Bgo ); \ - Ce ^= E##ge; \ - E##gi = Bgi ^((~Bgo)& Bgu ); \ - Ci ^= E##gi; \ - E##go = Bgo ^((~Bgu)& Bga ); \ - Co ^= E##go; \ - E##gu = Bgu ^((~Bga)& Bge ); \ - Cu ^= E##gu; \ -\ - A##be ^= De; \ - Bka = ROL64(A##be, 1); \ - A##gi ^= Di; \ - Bke = ROL64(A##gi, 6); \ - A##ko ^= Do; \ - Bki = ROL64(A##ko, 25); \ - A##mu ^= Du; \ - Bko = ROL64(A##mu, 8); \ - A##sa ^= Da; \ - Bku = ROL64(A##sa, 18); \ - E##ka = Bka ^((~Bke)& Bki ); \ - Ca ^= E##ka; \ - E##ke = Bke ^((~Bki)& Bko ); \ - Ce ^= E##ke; \ - E##ki = Bki ^((~Bko)& Bku ); \ - Ci ^= E##ki; \ - E##ko = Bko ^((~Bku)& Bka ); \ - Co ^= E##ko; \ - E##ku = Bku ^((~Bka)& Bke ); \ - Cu ^= E##ku; \ -\ - A##bu ^= Du; \ - Bma = ROL64(A##bu, 27); \ - A##ga ^= Da; \ - Bme = ROL64(A##ga, 36); \ - A##ke ^= De; \ - Bmi = ROL64(A##ke, 10); \ - A##mi ^= Di; \ - Bmo = ROL64(A##mi, 15); \ - A##so ^= Do; \ - Bmu = ROL64(A##so, 56); \ - E##ma = Bma ^((~Bme)& Bmi ); \ - Ca ^= E##ma; \ - E##me = Bme ^((~Bmi)& Bmo ); \ - Ce ^= E##me; \ - E##mi = Bmi ^((~Bmo)& Bmu ); \ - Ci ^= E##mi; \ - E##mo = Bmo ^((~Bmu)& Bma ); \ - Co ^= E##mo; \ - E##mu = Bmu ^((~Bma)& Bme ); \ - Cu ^= E##mu; \ -\ - A##bi ^= Di; \ - Bsa = ROL64(A##bi, 62); \ - A##go ^= Do; \ - Bse = ROL64(A##go, 55); \ - A##ku ^= Du; \ - Bsi = ROL64(A##ku, 39); \ - A##ma ^= Da; \ - Bso = ROL64(A##ma, 41); \ - A##se ^= De; \ - Bsu = ROL64(A##se, 2); \ - E##sa = Bsa ^((~Bse)& Bsi ); \ - Ca ^= E##sa; \ - E##se = Bse ^((~Bsi)& Bso ); \ - Ce ^= E##se; \ - E##si = Bsi ^((~Bso)& Bsu ); \ - Ci ^= E##si; \ - E##so = Bso ^((~Bsu)& Bsa ); \ - Co ^= E##so; \ - E##su = Bsu ^((~Bsa)& Bse ); \ - Cu ^= E##su; \ -\ - -/* --- Code for round */ - -/* --- 64-bit lanes mapped to 64-bit words */ - -#define thetaRhoPiChiIota(i, A, E) \ - Da = Cu^ROL64(Ce, 1); \ - De = Ca^ROL64(Ci, 1); \ - Di = Ce^ROL64(Co, 1); \ - Do = Ci^ROL64(Cu, 1); \ - Du = Co^ROL64(Ca, 1); \ -\ - A##ba ^= Da; \ - Bba = A##ba; \ - A##ge ^= De; \ - Bbe = ROL64(A##ge, 44); \ - A##ki ^= Di; \ - Bbi = ROL64(A##ki, 43); \ - A##mo ^= Do; \ - Bbo = ROL64(A##mo, 21); \ - A##su ^= Du; \ - Bbu = ROL64(A##su, 14); \ - E##ba = Bba ^((~Bbe)& Bbi ); \ - E##ba ^= KeccakF1600RoundConstants[i]; \ - E##be = Bbe ^((~Bbi)& Bbo ); \ - E##bi = Bbi ^((~Bbo)& Bbu ); \ - E##bo = Bbo ^((~Bbu)& Bba ); \ - E##bu = Bbu ^((~Bba)& Bbe ); \ -\ - A##bo ^= Do; \ - Bga = ROL64(A##bo, 28); \ - A##gu ^= Du; \ - Bge = ROL64(A##gu, 20); \ - A##ka ^= Da; \ - Bgi = ROL64(A##ka, 3); \ - A##me ^= De; \ - Bgo = ROL64(A##me, 45); \ - A##si ^= Di; \ - Bgu = ROL64(A##si, 61); \ - E##ga = Bga ^((~Bge)& Bgi ); \ - E##ge = Bge ^((~Bgi)& Bgo ); \ - E##gi = Bgi ^((~Bgo)& Bgu ); \ - E##go = Bgo ^((~Bgu)& Bga ); \ - E##gu = Bgu ^((~Bga)& Bge ); \ -\ - A##be ^= De; \ - Bka = ROL64(A##be, 1); \ - A##gi ^= Di; \ - Bke = ROL64(A##gi, 6); \ - A##ko ^= Do; \ - Bki = ROL64(A##ko, 25); \ - A##mu ^= Du; \ - Bko = ROL64(A##mu, 8); \ - A##sa ^= Da; \ - Bku = ROL64(A##sa, 18); \ - E##ka = Bka ^((~Bke)& Bki ); \ - E##ke = Bke ^((~Bki)& Bko ); \ - E##ki = Bki ^((~Bko)& Bku ); \ - E##ko = Bko ^((~Bku)& Bka ); \ - E##ku = Bku ^((~Bka)& Bke ); \ -\ - A##bu ^= Du; \ - Bma = ROL64(A##bu, 27); \ - A##ga ^= Da; \ - Bme = ROL64(A##ga, 36); \ - A##ke ^= De; \ - Bmi = ROL64(A##ke, 10); \ - A##mi ^= Di; \ - Bmo = ROL64(A##mi, 15); \ - A##so ^= Do; \ - Bmu = ROL64(A##so, 56); \ - E##ma = Bma ^((~Bme)& Bmi ); \ - E##me = Bme ^((~Bmi)& Bmo ); \ - E##mi = Bmi ^((~Bmo)& Bmu ); \ - E##mo = Bmo ^((~Bmu)& Bma ); \ - E##mu = Bmu ^((~Bma)& Bme ); \ -\ - A##bi ^= Di; \ - Bsa = ROL64(A##bi, 62); \ - A##go ^= Do; \ - Bse = ROL64(A##go, 55); \ - A##ku ^= Du; \ - Bsi = ROL64(A##ku, 39); \ - A##ma ^= Da; \ - Bso = ROL64(A##ma, 41); \ - A##se ^= De; \ - Bsu = ROL64(A##se, 2); \ - E##sa = Bsa ^((~Bse)& Bsi ); \ - E##se = Bse ^((~Bsi)& Bso ); \ - E##si = Bsi ^((~Bso)& Bsu ); \ - E##so = Bso ^((~Bsu)& Bsa ); \ - E##su = Bsu ^((~Bsa)& Bse ); \ -\ - -#endif /* UseBebigokimisa */ - - -#define copyFromState(X, state) \ - X##ba = state[ 0]; \ - X##be = state[ 1]; \ - X##bi = state[ 2]; \ - X##bo = state[ 3]; \ - X##bu = state[ 4]; \ - X##ga = state[ 5]; \ - X##ge = state[ 6]; \ - X##gi = state[ 7]; \ - X##go = state[ 8]; \ - X##gu = state[ 9]; \ - X##ka = state[10]; \ - X##ke = state[11]; \ - X##ki = state[12]; \ - X##ko = state[13]; \ - X##ku = state[14]; \ - X##ma = state[15]; \ - X##me = state[16]; \ - X##mi = state[17]; \ - X##mo = state[18]; \ - X##mu = state[19]; \ - X##sa = state[20]; \ - X##se = state[21]; \ - X##si = state[22]; \ - X##so = state[23]; \ - X##su = state[24]; \ - -#define copyToState(state, X) \ - state[ 0] = X##ba; \ - state[ 1] = X##be; \ - state[ 2] = X##bi; \ - state[ 3] = X##bo; \ - state[ 4] = X##bu; \ - state[ 5] = X##ga; \ - state[ 6] = X##ge; \ - state[ 7] = X##gi; \ - state[ 8] = X##go; \ - state[ 9] = X##gu; \ - state[10] = X##ka; \ - state[11] = X##ke; \ - state[12] = X##ki; \ - state[13] = X##ko; \ - state[14] = X##ku; \ - state[15] = X##ma; \ - state[16] = X##me; \ - state[17] = X##mi; \ - state[18] = X##mo; \ - state[19] = X##mu; \ - state[20] = X##sa; \ - state[21] = X##se; \ - state[22] = X##si; \ - state[23] = X##so; \ - state[24] = X##su; \ - -#define copyStateVariables(X, Y) \ - X##ba = Y##ba; \ - X##be = Y##be; \ - X##bi = Y##bi; \ - X##bo = Y##bo; \ - X##bu = Y##bu; \ - X##ga = Y##ga; \ - X##ge = Y##ge; \ - X##gi = Y##gi; \ - X##go = Y##go; \ - X##gu = Y##gu; \ - X##ka = Y##ka; \ - X##ke = Y##ke; \ - X##ki = Y##ki; \ - X##ko = Y##ko; \ - X##ku = Y##ku; \ - X##ma = Y##ma; \ - X##me = Y##me; \ - X##mi = Y##mi; \ - X##mo = Y##mo; \ - X##mu = Y##mu; \ - X##sa = Y##sa; \ - X##se = Y##se; \ - X##si = Y##si; \ - X##so = Y##so; \ - X##su = Y##su; \ - -#define copyFromStateAndAdd(X, state, input, laneCount) \ - if (laneCount < 16) { \ - if (laneCount < 8) { \ - if (laneCount < 4) { \ - if (laneCount < 2) { \ - if (laneCount < 1) { \ - X##ba = state[ 0]; \ - } \ - else { \ - X##ba = state[ 0]^input[ 0]; \ - } \ - X##be = state[ 1]; \ - X##bi = state[ 2]; \ - } \ - else { \ - X##ba = state[ 0]^input[ 0]; \ - X##be = state[ 1]^input[ 1]; \ - if (laneCount < 3) { \ - X##bi = state[ 2]; \ - } \ - else { \ - X##bi = state[ 2]^input[ 2]; \ - } \ - } \ - X##bo = state[ 3]; \ - X##bu = state[ 4]; \ - X##ga = state[ 5]; \ - X##ge = state[ 6]; \ - } \ - else { \ - X##ba = state[ 0]^input[ 0]; \ - X##be = state[ 1]^input[ 1]; \ - X##bi = state[ 2]^input[ 2]; \ - X##bo = state[ 3]^input[ 3]; \ - if (laneCount < 6) { \ - if (laneCount < 5) { \ - X##bu = state[ 4]; \ - } \ - else { \ - X##bu = state[ 4]^input[ 4]; \ - } \ - X##ga = state[ 5]; \ - X##ge = state[ 6]; \ - } \ - else { \ - X##bu = state[ 4]^input[ 4]; \ - X##ga = state[ 5]^input[ 5]; \ - if (laneCount < 7) { \ - X##ge = state[ 6]; \ - } \ - else { \ - X##ge = state[ 6]^input[ 6]; \ - } \ - } \ - } \ - X##gi = state[ 7]; \ - X##go = state[ 8]; \ - X##gu = state[ 9]; \ - X##ka = state[10]; \ - X##ke = state[11]; \ - X##ki = state[12]; \ - X##ko = state[13]; \ - X##ku = state[14]; \ - } \ - else { \ - X##ba = state[ 0]^input[ 0]; \ - X##be = state[ 1]^input[ 1]; \ - X##bi = state[ 2]^input[ 2]; \ - X##bo = state[ 3]^input[ 3]; \ - X##bu = state[ 4]^input[ 4]; \ - X##ga = state[ 5]^input[ 5]; \ - X##ge = state[ 6]^input[ 6]; \ - X##gi = state[ 7]^input[ 7]; \ - if (laneCount < 12) { \ - if (laneCount < 10) { \ - if (laneCount < 9) { \ - X##go = state[ 8]; \ - } \ - else { \ - X##go = state[ 8]^input[ 8]; \ - } \ - X##gu = state[ 9]; \ - X##ka = state[10]; \ - } \ - else { \ - X##go = state[ 8]^input[ 8]; \ - X##gu = state[ 9]^input[ 9]; \ - if (laneCount < 11) { \ - X##ka = state[10]; \ - } \ - else { \ - X##ka = state[10]^input[10]; \ - } \ - } \ - X##ke = state[11]; \ - X##ki = state[12]; \ - X##ko = state[13]; \ - X##ku = state[14]; \ - } \ - else { \ - X##go = state[ 8]^input[ 8]; \ - X##gu = state[ 9]^input[ 9]; \ - X##ka = state[10]^input[10]; \ - X##ke = state[11]^input[11]; \ - if (laneCount < 14) { \ - if (laneCount < 13) { \ - X##ki = state[12]; \ - } \ - else { \ - X##ki = state[12]^input[12]; \ - } \ - X##ko = state[13]; \ - X##ku = state[14]; \ - } \ - else { \ - X##ki = state[12]^input[12]; \ - X##ko = state[13]^input[13]; \ - if (laneCount < 15) { \ - X##ku = state[14]; \ - } \ - else { \ - X##ku = state[14]^input[14]; \ - } \ - } \ - } \ - } \ - X##ma = state[15]; \ - X##me = state[16]; \ - X##mi = state[17]; \ - X##mo = state[18]; \ - X##mu = state[19]; \ - X##sa = state[20]; \ - X##se = state[21]; \ - X##si = state[22]; \ - X##so = state[23]; \ - X##su = state[24]; \ - } \ - else { \ - X##ba = state[ 0]^input[ 0]; \ - X##be = state[ 1]^input[ 1]; \ - X##bi = state[ 2]^input[ 2]; \ - X##bo = state[ 3]^input[ 3]; \ - X##bu = state[ 4]^input[ 4]; \ - X##ga = state[ 5]^input[ 5]; \ - X##ge = state[ 6]^input[ 6]; \ - X##gi = state[ 7]^input[ 7]; \ - X##go = state[ 8]^input[ 8]; \ - X##gu = state[ 9]^input[ 9]; \ - X##ka = state[10]^input[10]; \ - X##ke = state[11]^input[11]; \ - X##ki = state[12]^input[12]; \ - X##ko = state[13]^input[13]; \ - X##ku = state[14]^input[14]; \ - X##ma = state[15]^input[15]; \ - if (laneCount < 24) { \ - if (laneCount < 20) { \ - if (laneCount < 18) { \ - if (laneCount < 17) { \ - X##me = state[16]; \ - } \ - else { \ - X##me = state[16]^input[16]; \ - } \ - X##mi = state[17]; \ - X##mo = state[18]; \ - } \ - else { \ - X##me = state[16]^input[16]; \ - X##mi = state[17]^input[17]; \ - if (laneCount < 19) { \ - X##mo = state[18]; \ - } \ - else { \ - X##mo = state[18]^input[18]; \ - } \ - } \ - X##mu = state[19]; \ - X##sa = state[20]; \ - X##se = state[21]; \ - X##si = state[22]; \ - } \ - else { \ - X##me = state[16]^input[16]; \ - X##mi = state[17]^input[17]; \ - X##mo = state[18]^input[18]; \ - X##mu = state[19]^input[19]; \ - if (laneCount < 22) { \ - if (laneCount < 21) { \ - X##sa = state[20]; \ - } \ - else { \ - X##sa = state[20]^input[20]; \ - } \ - X##se = state[21]; \ - X##si = state[22]; \ - } \ - else { \ - X##sa = state[20]^input[20]; \ - X##se = state[21]^input[21]; \ - if (laneCount < 23) { \ - X##si = state[22]; \ - } \ - else { \ - X##si = state[22]^input[22]; \ - } \ - } \ - } \ - X##so = state[23]; \ - X##su = state[24]; \ - } \ - else { \ - X##me = state[16]^input[16]; \ - X##mi = state[17]^input[17]; \ - X##mo = state[18]^input[18]; \ - X##mu = state[19]^input[19]; \ - X##sa = state[20]^input[20]; \ - X##se = state[21]^input[21]; \ - X##si = state[22]^input[22]; \ - X##so = state[23]^input[23]; \ - if (laneCount < 25) { \ - X##su = state[24]; \ - } \ - else { \ - X##su = state[24]^input[24]; \ - } \ - } \ - } - -#define addInput(X, input, laneCount) \ - if (laneCount == 21) { \ - X##ba ^= input[ 0]; \ - X##be ^= input[ 1]; \ - X##bi ^= input[ 2]; \ - X##bo ^= input[ 3]; \ - X##bu ^= input[ 4]; \ - X##ga ^= input[ 5]; \ - X##ge ^= input[ 6]; \ - X##gi ^= input[ 7]; \ - X##go ^= input[ 8]; \ - X##gu ^= input[ 9]; \ - X##ka ^= input[10]; \ - X##ke ^= input[11]; \ - X##ki ^= input[12]; \ - X##ko ^= input[13]; \ - X##ku ^= input[14]; \ - X##ma ^= input[15]; \ - X##me ^= input[16]; \ - X##mi ^= input[17]; \ - X##mo ^= input[18]; \ - X##mu ^= input[19]; \ - X##sa ^= input[20]; \ - } \ - else if (laneCount < 16) { \ - if (laneCount < 8) { \ - if (laneCount < 4) { \ - if (laneCount < 2) { \ - if (laneCount < 1) { \ - } \ - else { \ - X##ba ^= input[ 0]; \ - } \ - } \ - else { \ - X##ba ^= input[ 0]; \ - X##be ^= input[ 1]; \ - if (laneCount < 3) { \ - } \ - else { \ - X##bi ^= input[ 2]; \ - } \ - } \ - } \ - else { \ - X##ba ^= input[ 0]; \ - X##be ^= input[ 1]; \ - X##bi ^= input[ 2]; \ - X##bo ^= input[ 3]; \ - if (laneCount < 6) { \ - if (laneCount < 5) { \ - } \ - else { \ - X##bu ^= input[ 4]; \ - } \ - } \ - else { \ - X##bu ^= input[ 4]; \ - X##ga ^= input[ 5]; \ - if (laneCount < 7) { \ - } \ - else { \ - X##ge ^= input[ 6]; \ - } \ - } \ - } \ - } \ - else { \ - X##ba ^= input[ 0]; \ - X##be ^= input[ 1]; \ - X##bi ^= input[ 2]; \ - X##bo ^= input[ 3]; \ - X##bu ^= input[ 4]; \ - X##ga ^= input[ 5]; \ - X##ge ^= input[ 6]; \ - X##gi ^= input[ 7]; \ - if (laneCount < 12) { \ - if (laneCount < 10) { \ - if (laneCount < 9) { \ - } \ - else { \ - X##go ^= input[ 8]; \ - } \ - } \ - else { \ - X##go ^= input[ 8]; \ - X##gu ^= input[ 9]; \ - if (laneCount < 11) { \ - } \ - else { \ - X##ka ^= input[10]; \ - } \ - } \ - } \ - else { \ - X##go ^= input[ 8]; \ - X##gu ^= input[ 9]; \ - X##ka ^= input[10]; \ - X##ke ^= input[11]; \ - if (laneCount < 14) { \ - if (laneCount < 13) { \ - } \ - else { \ - X##ki ^= input[12]; \ - } \ - } \ - else { \ - X##ki ^= input[12]; \ - X##ko ^= input[13]; \ - if (laneCount < 15) { \ - } \ - else { \ - X##ku ^= input[14]; \ - } \ - } \ - } \ - } \ - } \ - else { \ - X##ba ^= input[ 0]; \ - X##be ^= input[ 1]; \ - X##bi ^= input[ 2]; \ - X##bo ^= input[ 3]; \ - X##bu ^= input[ 4]; \ - X##ga ^= input[ 5]; \ - X##ge ^= input[ 6]; \ - X##gi ^= input[ 7]; \ - X##go ^= input[ 8]; \ - X##gu ^= input[ 9]; \ - X##ka ^= input[10]; \ - X##ke ^= input[11]; \ - X##ki ^= input[12]; \ - X##ko ^= input[13]; \ - X##ku ^= input[14]; \ - X##ma ^= input[15]; \ - if (laneCount < 24) { \ - if (laneCount < 20) { \ - if (laneCount < 18) { \ - if (laneCount < 17) { \ - } \ - else { \ - X##me ^= input[16]; \ - } \ - } \ - else { \ - X##me ^= input[16]; \ - X##mi ^= input[17]; \ - if (laneCount < 19) { \ - } \ - else { \ - X##mo ^= input[18]; \ - } \ - } \ - } \ - else { \ - X##me ^= input[16]; \ - X##mi ^= input[17]; \ - X##mo ^= input[18]; \ - X##mu ^= input[19]; \ - if (laneCount < 22) { \ - if (laneCount < 21) { \ - } \ - else { \ - X##sa ^= input[20]; \ - } \ - } \ - else { \ - X##sa ^= input[20]; \ - X##se ^= input[21]; \ - if (laneCount < 23) { \ - } \ - else { \ - X##si ^= input[22]; \ - } \ - } \ - } \ - } \ - else { \ - X##me ^= input[16]; \ - X##mi ^= input[17]; \ - X##mo ^= input[18]; \ - X##mu ^= input[19]; \ - X##sa ^= input[20]; \ - X##se ^= input[21]; \ - X##si ^= input[22]; \ - X##so ^= input[23]; \ - if (laneCount < 25) { \ - } \ - else { \ - X##su ^= input[24]; \ - } \ - } \ - } - -#ifdef UseBebigokimisa - -#define copyToStateAndOutput(X, state, output, laneCount) \ - if (laneCount < 16) { \ - if (laneCount < 8) { \ - if (laneCount < 4) { \ - if (laneCount < 2) { \ - state[ 0] = X##ba; \ - if (laneCount >= 1) { \ - output[ 0] = X##ba; \ - } \ - state[ 1] = X##be; \ - state[ 2] = X##bi; \ - } \ - else { \ - state[ 0] = X##ba; \ - output[ 0] = X##ba; \ - state[ 1] = X##be; \ - output[ 1] = ~X##be; \ - state[ 2] = X##bi; \ - if (laneCount >= 3) { \ - output[ 2] = ~X##bi; \ - } \ - } \ - state[ 3] = X##bo; \ - state[ 4] = X##bu; \ - state[ 5] = X##ga; \ - state[ 6] = X##ge; \ - } \ - else { \ - state[ 0] = X##ba; \ - output[ 0] = X##ba; \ - state[ 1] = X##be; \ - output[ 1] = ~X##be; \ - state[ 2] = X##bi; \ - output[ 2] = ~X##bi; \ - state[ 3] = X##bo; \ - output[ 3] = X##bo; \ - if (laneCount < 6) { \ - state[ 4] = X##bu; \ - if (laneCount >= 5) { \ - output[ 4] = X##bu; \ - } \ - state[ 5] = X##ga; \ - state[ 6] = X##ge; \ - } \ - else { \ - state[ 4] = X##bu; \ - output[ 4] = X##bu; \ - state[ 5] = X##ga; \ - output[ 5] = X##ga; \ - state[ 6] = X##ge; \ - if (laneCount >= 7) { \ - output[ 6] = X##ge; \ - } \ - } \ - } \ - state[ 7] = X##gi; \ - state[ 8] = X##go; \ - state[ 9] = X##gu; \ - state[10] = X##ka; \ - state[11] = X##ke; \ - state[12] = X##ki; \ - state[13] = X##ko; \ - state[14] = X##ku; \ - } \ - else { \ - state[ 0] = X##ba; \ - output[ 0] = X##ba; \ - state[ 1] = X##be; \ - output[ 1] = ~X##be; \ - state[ 2] = X##bi; \ - output[ 2] = ~X##bi; \ - state[ 3] = X##bo; \ - output[ 3] = X##bo; \ - state[ 4] = X##bu; \ - output[ 4] = X##bu; \ - state[ 5] = X##ga; \ - output[ 5] = X##ga; \ - state[ 6] = X##ge; \ - output[ 6] = X##ge; \ - state[ 7] = X##gi; \ - output[ 7] = X##gi; \ - if (laneCount < 12) { \ - if (laneCount < 10) { \ - state[ 8] = X##go; \ - if (laneCount >= 9) { \ - output[ 8] = ~X##go; \ - } \ - state[ 9] = X##gu; \ - state[10] = X##ka; \ - } \ - else { \ - state[ 8] = X##go; \ - output[ 8] = ~X##go; \ - state[ 9] = X##gu; \ - output[ 9] = X##gu; \ - state[10] = X##ka; \ - if (laneCount >= 11) { \ - output[10] = X##ka; \ - } \ - } \ - state[11] = X##ke; \ - state[12] = X##ki; \ - state[13] = X##ko; \ - state[14] = X##ku; \ - } \ - else { \ - state[ 8] = X##go; \ - output[ 8] = ~X##go; \ - state[ 9] = X##gu; \ - output[ 9] = X##gu; \ - state[10] = X##ka; \ - output[10] = X##ka; \ - state[11] = X##ke; \ - output[11] = X##ke; \ - if (laneCount < 14) { \ - state[12] = X##ki; \ - if (laneCount >= 13) { \ - output[12] = ~X##ki; \ - } \ - state[13] = X##ko; \ - state[14] = X##ku; \ - } \ - else { \ - state[12] = X##ki; \ - output[12] = ~X##ki; \ - state[13] = X##ko; \ - output[13] = X##ko; \ - state[14] = X##ku; \ - if (laneCount >= 15) { \ - output[14] = X##ku; \ - } \ - } \ - } \ - } \ - state[15] = X##ma; \ - state[16] = X##me; \ - state[17] = X##mi; \ - state[18] = X##mo; \ - state[19] = X##mu; \ - state[20] = X##sa; \ - state[21] = X##se; \ - state[22] = X##si; \ - state[23] = X##so; \ - state[24] = X##su; \ - } \ - else { \ - state[ 0] = X##ba; \ - output[ 0] = X##ba; \ - state[ 1] = X##be; \ - output[ 1] = ~X##be; \ - state[ 2] = X##bi; \ - output[ 2] = ~X##bi; \ - state[ 3] = X##bo; \ - output[ 3] = X##bo; \ - state[ 4] = X##bu; \ - output[ 4] = X##bu; \ - state[ 5] = X##ga; \ - output[ 5] = X##ga; \ - state[ 6] = X##ge; \ - output[ 6] = X##ge; \ - state[ 7] = X##gi; \ - output[ 7] = X##gi; \ - state[ 8] = X##go; \ - output[ 8] = ~X##go; \ - state[ 9] = X##gu; \ - output[ 9] = X##gu; \ - state[10] = X##ka; \ - output[10] = X##ka; \ - state[11] = X##ke; \ - output[11] = X##ke; \ - state[12] = X##ki; \ - output[12] = ~X##ki; \ - state[13] = X##ko; \ - output[13] = X##ko; \ - state[14] = X##ku; \ - output[14] = X##ku; \ - state[15] = X##ma; \ - output[15] = X##ma; \ - if (laneCount < 24) { \ - if (laneCount < 20) { \ - if (laneCount < 18) { \ - state[16] = X##me; \ - if (laneCount >= 17) { \ - output[16] = X##me; \ - } \ - state[17] = X##mi; \ - state[18] = X##mo; \ - } \ - else { \ - state[16] = X##me; \ - output[16] = X##me; \ - state[17] = X##mi; \ - output[17] = ~X##mi; \ - state[18] = X##mo; \ - if (laneCount >= 19) { \ - output[18] = X##mo; \ - } \ - } \ - state[19] = X##mu; \ - state[20] = X##sa; \ - state[21] = X##se; \ - state[22] = X##si; \ - } \ - else { \ - state[16] = X##me; \ - output[16] = X##me; \ - state[17] = X##mi; \ - output[17] = ~X##mi; \ - state[18] = X##mo; \ - output[18] = X##mo; \ - state[19] = X##mu; \ - output[19] = X##mu; \ - if (laneCount < 22) { \ - state[20] = X##sa; \ - if (laneCount >= 21) { \ - output[20] = ~X##sa; \ - } \ - state[21] = X##se; \ - state[22] = X##si; \ - } \ - else { \ - state[20] = X##sa; \ - output[20] = ~X##sa; \ - state[21] = X##se; \ - output[21] = X##se; \ - state[22] = X##si; \ - if (laneCount >= 23) { \ - output[22] = X##si; \ - } \ - } \ - } \ - state[23] = X##so; \ - state[24] = X##su; \ - } \ - else { \ - state[16] = X##me; \ - output[16] = X##me; \ - state[17] = X##mi; \ - output[17] = ~X##mi; \ - state[18] = X##mo; \ - output[18] = X##mo; \ - state[19] = X##mu; \ - output[19] = X##mu; \ - state[20] = X##sa; \ - output[20] = ~X##sa; \ - state[21] = X##se; \ - output[21] = X##se; \ - state[22] = X##si; \ - output[22] = X##si; \ - state[23] = X##so; \ - output[23] = X##so; \ - state[24] = X##su; \ - if (laneCount >= 25) { \ - output[24] = X##su; \ - } \ - } \ - } - -#define output(X, output, laneCount) \ - if (laneCount < 16) { \ - if (laneCount < 8) { \ - if (laneCount < 4) { \ - if (laneCount < 2) { \ - if (laneCount >= 1) { \ - output[ 0] = X##ba; \ - } \ - } \ - else { \ - output[ 0] = X##ba; \ - output[ 1] = ~X##be; \ - if (laneCount >= 3) { \ - output[ 2] = ~X##bi; \ - } \ - } \ - } \ - else { \ - output[ 0] = X##ba; \ - output[ 1] = ~X##be; \ - output[ 2] = ~X##bi; \ - output[ 3] = X##bo; \ - if (laneCount < 6) { \ - if (laneCount >= 5) { \ - output[ 4] = X##bu; \ - } \ - } \ - else { \ - output[ 4] = X##bu; \ - output[ 5] = X##ga; \ - if (laneCount >= 7) { \ - output[ 6] = X##ge; \ - } \ - } \ - } \ - } \ - else { \ - output[ 0] = X##ba; \ - output[ 1] = ~X##be; \ - output[ 2] = ~X##bi; \ - output[ 3] = X##bo; \ - output[ 4] = X##bu; \ - output[ 5] = X##ga; \ - output[ 6] = X##ge; \ - output[ 7] = X##gi; \ - if (laneCount < 12) { \ - if (laneCount < 10) { \ - if (laneCount >= 9) { \ - output[ 8] = ~X##go; \ - } \ - } \ - else { \ - output[ 8] = ~X##go; \ - output[ 9] = X##gu; \ - if (laneCount >= 11) { \ - output[10] = X##ka; \ - } \ - } \ - } \ - else { \ - output[ 8] = ~X##go; \ - output[ 9] = X##gu; \ - output[10] = X##ka; \ - output[11] = X##ke; \ - if (laneCount < 14) { \ - if (laneCount >= 13) { \ - output[12] = ~X##ki; \ - } \ - } \ - else { \ - output[12] = ~X##ki; \ - output[13] = X##ko; \ - if (laneCount >= 15) { \ - output[14] = X##ku; \ - } \ - } \ - } \ - } \ - } \ - else { \ - output[ 0] = X##ba; \ - output[ 1] = ~X##be; \ - output[ 2] = ~X##bi; \ - output[ 3] = X##bo; \ - output[ 4] = X##bu; \ - output[ 5] = X##ga; \ - output[ 6] = X##ge; \ - output[ 7] = X##gi; \ - output[ 8] = ~X##go; \ - output[ 9] = X##gu; \ - output[10] = X##ka; \ - output[11] = X##ke; \ - output[12] = ~X##ki; \ - output[13] = X##ko; \ - output[14] = X##ku; \ - output[15] = X##ma; \ - if (laneCount < 24) { \ - if (laneCount < 20) { \ - if (laneCount < 18) { \ - if (laneCount >= 17) { \ - output[16] = X##me; \ - } \ - } \ - else { \ - output[16] = X##me; \ - output[17] = ~X##mi; \ - if (laneCount >= 19) { \ - output[18] = X##mo; \ - } \ - } \ - } \ - else { \ - output[16] = X##me; \ - output[17] = ~X##mi; \ - output[18] = X##mo; \ - output[19] = X##mu; \ - if (laneCount < 22) { \ - if (laneCount >= 21) { \ - output[20] = ~X##sa; \ - } \ - } \ - else { \ - output[20] = ~X##sa; \ - output[21] = X##se; \ - if (laneCount >= 23) { \ - output[22] = X##si; \ - } \ - } \ - } \ - } \ - else { \ - output[16] = X##me; \ - output[17] = ~X##mi; \ - output[18] = X##mo; \ - output[19] = X##mu; \ - output[20] = ~X##sa; \ - output[21] = X##se; \ - output[22] = X##si; \ - output[23] = X##so; \ - if (laneCount >= 25) { \ - output[24] = X##su; \ - } \ - } \ - } - -#define wrapOne(X, input, output, index, name) \ - X##name ^= input[index]; \ - output[index] = X##name; - -#define wrapOneInvert(X, input, output, index, name) \ - X##name ^= input[index]; \ - output[index] = ~X##name; - -#define unwrapOne(X, input, output, index, name) \ - output[index] = input[index] ^ X##name; \ - X##name ^= output[index]; - -#define unwrapOneInvert(X, input, output, index, name) \ - output[index] = ~(input[index] ^ X##name); \ - X##name ^= output[index]; \ - -#else /* UseBebigokimisa */ - - -#define copyToStateAndOutput(X, state, output, laneCount) \ - if (laneCount < 16) { \ - if (laneCount < 8) { \ - if (laneCount < 4) { \ - if (laneCount < 2) { \ - state[ 0] = X##ba; \ - if (laneCount >= 1) { \ - output[ 0] = X##ba; \ - } \ - state[ 1] = X##be; \ - state[ 2] = X##bi; \ - } \ - else { \ - state[ 0] = X##ba; \ - output[ 0] = X##ba; \ - state[ 1] = X##be; \ - output[ 1] = X##be; \ - state[ 2] = X##bi; \ - if (laneCount >= 3) { \ - output[ 2] = X##bi; \ - } \ - } \ - state[ 3] = X##bo; \ - state[ 4] = X##bu; \ - state[ 5] = X##ga; \ - state[ 6] = X##ge; \ - } \ - else { \ - state[ 0] = X##ba; \ - output[ 0] = X##ba; \ - state[ 1] = X##be; \ - output[ 1] = X##be; \ - state[ 2] = X##bi; \ - output[ 2] = X##bi; \ - state[ 3] = X##bo; \ - output[ 3] = X##bo; \ - if (laneCount < 6) { \ - state[ 4] = X##bu; \ - if (laneCount >= 5) { \ - output[ 4] = X##bu; \ - } \ - state[ 5] = X##ga; \ - state[ 6] = X##ge; \ - } \ - else { \ - state[ 4] = X##bu; \ - output[ 4] = X##bu; \ - state[ 5] = X##ga; \ - output[ 5] = X##ga; \ - state[ 6] = X##ge; \ - if (laneCount >= 7) { \ - output[ 6] = X##ge; \ - } \ - } \ - } \ - state[ 7] = X##gi; \ - state[ 8] = X##go; \ - state[ 9] = X##gu; \ - state[10] = X##ka; \ - state[11] = X##ke; \ - state[12] = X##ki; \ - state[13] = X##ko; \ - state[14] = X##ku; \ - } \ - else { \ - state[ 0] = X##ba; \ - output[ 0] = X##ba; \ - state[ 1] = X##be; \ - output[ 1] = X##be; \ - state[ 2] = X##bi; \ - output[ 2] = X##bi; \ - state[ 3] = X##bo; \ - output[ 3] = X##bo; \ - state[ 4] = X##bu; \ - output[ 4] = X##bu; \ - state[ 5] = X##ga; \ - output[ 5] = X##ga; \ - state[ 6] = X##ge; \ - output[ 6] = X##ge; \ - state[ 7] = X##gi; \ - output[ 7] = X##gi; \ - if (laneCount < 12) { \ - if (laneCount < 10) { \ - state[ 8] = X##go; \ - if (laneCount >= 9) { \ - output[ 8] = X##go; \ - } \ - state[ 9] = X##gu; \ - state[10] = X##ka; \ - } \ - else { \ - state[ 8] = X##go; \ - output[ 8] = X##go; \ - state[ 9] = X##gu; \ - output[ 9] = X##gu; \ - state[10] = X##ka; \ - if (laneCount >= 11) { \ - output[10] = X##ka; \ - } \ - } \ - state[11] = X##ke; \ - state[12] = X##ki; \ - state[13] = X##ko; \ - state[14] = X##ku; \ - } \ - else { \ - state[ 8] = X##go; \ - output[ 8] = X##go; \ - state[ 9] = X##gu; \ - output[ 9] = X##gu; \ - state[10] = X##ka; \ - output[10] = X##ka; \ - state[11] = X##ke; \ - output[11] = X##ke; \ - if (laneCount < 14) { \ - state[12] = X##ki; \ - if (laneCount >= 13) { \ - output[12]= X##ki; \ - } \ - state[13] = X##ko; \ - state[14] = X##ku; \ - } \ - else { \ - state[12] = X##ki; \ - output[12]= X##ki; \ - state[13] = X##ko; \ - output[13] = X##ko; \ - state[14] = X##ku; \ - if (laneCount >= 15) { \ - output[14] = X##ku; \ - } \ - } \ - } \ - } \ - state[15] = X##ma; \ - state[16] = X##me; \ - state[17] = X##mi; \ - state[18] = X##mo; \ - state[19] = X##mu; \ - state[20] = X##sa; \ - state[21] = X##se; \ - state[22] = X##si; \ - state[23] = X##so; \ - state[24] = X##su; \ - } \ - else { \ - state[ 0] = X##ba; \ - output[ 0] = X##ba; \ - state[ 1] = X##be; \ - output[ 1] = X##be; \ - state[ 2] = X##bi; \ - output[ 2] = X##bi; \ - state[ 3] = X##bo; \ - output[ 3] = X##bo; \ - state[ 4] = X##bu; \ - output[ 4] = X##bu; \ - state[ 5] = X##ga; \ - output[ 5] = X##ga; \ - state[ 6] = X##ge; \ - output[ 6] = X##ge; \ - state[ 7] = X##gi; \ - output[ 7] = X##gi; \ - state[ 8] = X##go; \ - output[ 8] = X##go; \ - state[ 9] = X##gu; \ - output[ 9] = X##gu; \ - state[10] = X##ka; \ - output[10] = X##ka; \ - state[11] = X##ke; \ - output[11] = X##ke; \ - state[12] = X##ki; \ - output[12]= X##ki; \ - state[13] = X##ko; \ - output[13] = X##ko; \ - state[14] = X##ku; \ - output[14] = X##ku; \ - state[15] = X##ma; \ - output[15] = X##ma; \ - if (laneCount < 24) { \ - if (laneCount < 20) { \ - if (laneCount < 18) { \ - state[16] = X##me; \ - if (laneCount >= 17) { \ - output[16] = X##me; \ - } \ - state[17] = X##mi; \ - state[18] = X##mo; \ - } \ - else { \ - state[16] = X##me; \ - output[16] = X##me; \ - state[17] = X##mi; \ - output[17] = X##mi; \ - state[18] = X##mo; \ - if (laneCount >= 19) { \ - output[18] = X##mo; \ - } \ - } \ - state[19] = X##mu; \ - state[20] = X##sa; \ - state[21] = X##se; \ - state[22] = X##si; \ - } \ - else { \ - state[16] = X##me; \ - output[16] = X##me; \ - state[17] = X##mi; \ - output[17] = X##mi; \ - state[18] = X##mo; \ - output[18] = X##mo; \ - state[19] = X##mu; \ - output[19] = X##mu; \ - if (laneCount < 22) { \ - state[20] = X##sa; \ - if (laneCount >= 21) { \ - output[20] = X##sa; \ - } \ - state[21] = X##se; \ - state[22] = X##si; \ - } \ - else { \ - state[20] = X##sa; \ - output[20] = X##sa; \ - state[21] = X##se; \ - output[21] = X##se; \ - state[22] = X##si; \ - if (laneCount >= 23) { \ - output[22] = X##si; \ - } \ - } \ - } \ - state[23] = X##so; \ - state[24] = X##su; \ - } \ - else { \ - state[16] = X##me; \ - output[16] = X##me; \ - state[17] = X##mi; \ - output[17] = X##mi; \ - state[18] = X##mo; \ - output[18] = X##mo; \ - state[19] = X##mu; \ - output[19] = X##mu; \ - state[20] = X##sa; \ - output[20] = X##sa; \ - state[21] = X##se; \ - output[21] = X##se; \ - state[22] = X##si; \ - output[22] = X##si; \ - state[23] = X##so; \ - output[23] = X##so; \ - state[24] = X##su; \ - if (laneCount >= 25) { \ - output[24] = X##su; \ - } \ - } \ - } - -#define output(X, output, laneCount) \ - if (laneCount < 16) { \ - if (laneCount < 8) { \ - if (laneCount < 4) { \ - if (laneCount < 2) { \ - if (laneCount >= 1) { \ - output[ 0] = X##ba; \ - } \ - } \ - else { \ - output[ 0] = X##ba; \ - output[ 1] = X##be; \ - if (laneCount >= 3) { \ - output[ 2] = X##bi; \ - } \ - } \ - } \ - else { \ - output[ 0] = X##ba; \ - output[ 1] = X##be; \ - output[ 2] = X##bi; \ - output[ 3] = X##bo; \ - if (laneCount < 6) { \ - if (laneCount >= 5) { \ - output[ 4] = X##bu; \ - } \ - } \ - else { \ - output[ 4] = X##bu; \ - output[ 5] = X##ga; \ - if (laneCount >= 7) { \ - output[ 6] = X##ge; \ - } \ - } \ - } \ - } \ - else { \ - output[ 0] = X##ba; \ - output[ 1] = X##be; \ - output[ 2] = X##bi; \ - output[ 3] = X##bo; \ - output[ 4] = X##bu; \ - output[ 5] = X##ga; \ - output[ 6] = X##ge; \ - output[ 7] = X##gi; \ - if (laneCount < 12) { \ - if (laneCount < 10) { \ - if (laneCount >= 9) { \ - output[ 8] = X##go; \ - } \ - } \ - else { \ - output[ 8] = X##go; \ - output[ 9] = X##gu; \ - if (laneCount >= 11) { \ - output[10] = X##ka; \ - } \ - } \ - } \ - else { \ - output[ 8] = X##go; \ - output[ 9] = X##gu; \ - output[10] = X##ka; \ - output[11] = X##ke; \ - if (laneCount < 14) { \ - if (laneCount >= 13) { \ - output[12] = X##ki; \ - } \ - } \ - else { \ - output[12] = X##ki; \ - output[13] = X##ko; \ - if (laneCount >= 15) { \ - output[14] = X##ku; \ - } \ - } \ - } \ - } \ - } \ - else { \ - output[ 0] = X##ba; \ - output[ 1] = X##be; \ - output[ 2] = X##bi; \ - output[ 3] = X##bo; \ - output[ 4] = X##bu; \ - output[ 5] = X##ga; \ - output[ 6] = X##ge; \ - output[ 7] = X##gi; \ - output[ 8] = X##go; \ - output[ 9] = X##gu; \ - output[10] = X##ka; \ - output[11] = X##ke; \ - output[12] = X##ki; \ - output[13] = X##ko; \ - output[14] = X##ku; \ - output[15] = X##ma; \ - if (laneCount < 24) { \ - if (laneCount < 20) { \ - if (laneCount < 18) { \ - if (laneCount >= 17) { \ - output[16] = X##me; \ - } \ - } \ - else { \ - output[16] = X##me; \ - output[17] = X##mi; \ - if (laneCount >= 19) { \ - output[18] = X##mo; \ - } \ - } \ - } \ - else { \ - output[16] = X##me; \ - output[17] = X##mi; \ - output[18] = X##mo; \ - output[19] = X##mu; \ - if (laneCount < 22) { \ - if (laneCount >= 21) { \ - output[20] = X##sa; \ - } \ - } \ - else { \ - output[20] = X##sa; \ - output[21] = X##se; \ - if (laneCount >= 23) { \ - output[22] = X##si; \ - } \ - } \ - } \ - } \ - else { \ - output[16] = X##me; \ - output[17] = X##mi; \ - output[18] = X##mo; \ - output[19] = X##mu; \ - output[20] = X##sa; \ - output[21] = X##se; \ - output[22] = X##si; \ - output[23] = X##so; \ - if (laneCount >= 25) { \ - output[24] = X##su; \ - } \ - } \ - } - -#define wrapOne(X, input, output, index, name) \ - X##name ^= input[index]; \ - output[index] = X##name; - -#define wrapOneInvert(X, input, output, index, name) \ - X##name ^= input[index]; \ - output[index] = X##name; - -#define unwrapOne(X, input, output, index, name) \ - output[index] = input[index] ^ X##name; \ - X##name ^= output[index]; - -#define unwrapOneInvert(X, input, output, index, name) \ - output[index] = input[index] ^ X##name; \ - X##name ^= output[index]; - -#endif - -#define wrap(X, input, output, laneCount, trailingBits) \ - if (laneCount < 16) { \ - if (laneCount < 8) { \ - if (laneCount < 4) { \ - if (laneCount < 2) { \ - if (laneCount < 1) { \ - X##ba ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 0, ba) \ - X##be ^= trailingBits; \ - } \ - } \ - else { \ - wrapOne(X, input, output, 0, ba) \ - wrapOneInvert(X, input, output, 1, be) \ - if (laneCount < 3) { \ - X##bi ^= trailingBits; \ - } \ - else { \ - wrapOneInvert(X, input, output, 2, bi) \ - X##bo ^= trailingBits; \ - } \ - } \ - } \ - else { \ - wrapOne(X, input, output, 0, ba) \ - wrapOneInvert(X, input, output, 1, be) \ - wrapOneInvert(X, input, output, 2, bi) \ - wrapOne(X, input, output, 3, bo) \ - if (laneCount < 6) { \ - if (laneCount < 5) { \ - X##bu ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 4, bu) \ - X##ga ^= trailingBits; \ - } \ - } \ - else { \ - wrapOne(X, input, output, 4, bu) \ - wrapOne(X, input, output, 5, ga) \ - if (laneCount < 7) { \ - X##ge ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 6, ge) \ - X##gi ^= trailingBits; \ - } \ - } \ - } \ - } \ - else { \ - wrapOne(X, input, output, 0, ba) \ - wrapOneInvert(X, input, output, 1, be) \ - wrapOneInvert(X, input, output, 2, bi) \ - wrapOne(X, input, output, 3, bo) \ - wrapOne(X, input, output, 4, bu) \ - wrapOne(X, input, output, 5, ga) \ - wrapOne(X, input, output, 6, ge) \ - wrapOne(X, input, output, 7, gi) \ - if (laneCount < 12) { \ - if (laneCount < 10) { \ - if (laneCount < 9) { \ - X##go ^= trailingBits; \ - } \ - else { \ - wrapOneInvert(X, input, output, 8, go) \ - X##gu ^= trailingBits; \ - } \ - } \ - else { \ - wrapOneInvert(X, input, output, 8, go) \ - wrapOne(X, input, output, 9, gu) \ - if (laneCount < 11) { \ - X##ka ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 10, ka) \ - X##ke ^= trailingBits; \ - } \ - } \ - } \ - else { \ - wrapOneInvert(X, input, output, 8, go) \ - wrapOne(X, input, output, 9, gu) \ - wrapOne(X, input, output, 10, ka) \ - wrapOne(X, input, output, 11, ke) \ - if (laneCount < 14) { \ - if (laneCount < 13) { \ - X##ki ^= trailingBits; \ - } \ - else { \ - wrapOneInvert(X, input, output, 12, ki) \ - X##ko ^= trailingBits; \ - } \ - } \ - else { \ - wrapOneInvert(X, input, output, 12, ki) \ - wrapOne(X, input, output, 13, ko) \ - if (laneCount < 15) { \ - X##ku ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 14, ku) \ - X##ma ^= trailingBits; \ - } \ - } \ - } \ - } \ - } \ - else { \ - wrapOne(X, input, output, 0, ba) \ - wrapOneInvert(X, input, output, 1, be) \ - wrapOneInvert(X, input, output, 2, bi) \ - wrapOne(X, input, output, 3, bo) \ - wrapOne(X, input, output, 4, bu) \ - wrapOne(X, input, output, 5, ga) \ - wrapOne(X, input, output, 6, ge) \ - wrapOne(X, input, output, 7, gi) \ - wrapOneInvert(X, input, output, 8, go) \ - wrapOne(X, input, output, 9, gu) \ - wrapOne(X, input, output, 10, ka) \ - wrapOne(X, input, output, 11, ke) \ - wrapOneInvert(X, input, output, 12, ki) \ - wrapOne(X, input, output, 13, ko) \ - wrapOne(X, input, output, 14, ku) \ - wrapOne(X, input, output, 15, ma) \ - if (laneCount < 24) { \ - if (laneCount < 20) { \ - if (laneCount < 18) { \ - if (laneCount < 17) { \ - X##me ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 16, me) \ - X##mi ^= trailingBits; \ - } \ - } \ - else { \ - wrapOne(X, input, output, 16, me) \ - wrapOneInvert(X, input, output, 17, mi) \ - if (laneCount < 19) { \ - X##mo ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 18, mo) \ - X##mu ^= trailingBits; \ - } \ - } \ - } \ - else { \ - wrapOne(X, input, output, 16, me) \ - wrapOneInvert(X, input, output, 17, mi) \ - wrapOne(X, input, output, 18, mo) \ - wrapOne(X, input, output, 19, mu) \ - if (laneCount < 22) { \ - if (laneCount < 21) { \ - X##sa ^= trailingBits; \ - } \ - else { \ - wrapOneInvert(X, input, output, 20, sa) \ - X##se ^= trailingBits; \ - } \ - } \ - else { \ - wrapOneInvert(X, input, output, 20, sa) \ - wrapOne(X, input, output, 21, se) \ - if (laneCount < 23) { \ - X##si ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 22, si) \ - X##so ^= trailingBits; \ - } \ - } \ - } \ - } \ - else { \ - wrapOne(X, input, output, 16, me) \ - wrapOneInvert(X, input, output, 17, mi) \ - wrapOne(X, input, output, 18, mo) \ - wrapOne(X, input, output, 19, mu) \ - wrapOneInvert(X, input, output, 20, sa) \ - wrapOne(X, input, output, 21, se) \ - wrapOne(X, input, output, 22, si) \ - wrapOne(X, input, output, 23, so) \ - if (laneCount < 25) { \ - X##su ^= trailingBits; \ - } \ - else { \ - wrapOne(X, input, output, 24, su) \ - } \ - } \ - } - -#define unwrap(X, input, output, laneCount, trailingBits) \ - if (laneCount < 16) { \ - if (laneCount < 8) { \ - if (laneCount < 4) { \ - if (laneCount < 2) { \ - if (laneCount < 1) { \ - X##ba ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 0, ba) \ - X##be ^= trailingBits; \ - } \ - } \ - else { \ - unwrapOne(X, input, output, 0, ba) \ - unwrapOneInvert(X, input, output, 1, be) \ - if (laneCount < 3) { \ - X##bi ^= trailingBits; \ - } \ - else { \ - unwrapOneInvert(X, input, output, 2, bi) \ - X##bo ^= trailingBits; \ - } \ - } \ - } \ - else { \ - unwrapOne(X, input, output, 0, ba) \ - unwrapOneInvert(X, input, output, 1, be) \ - unwrapOneInvert(X, input, output, 2, bi) \ - unwrapOne(X, input, output, 3, bo) \ - if (laneCount < 6) { \ - if (laneCount < 5) { \ - X##bu ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 4, bu) \ - X##ga ^= trailingBits; \ - } \ - } \ - else { \ - unwrapOne(X, input, output, 4, bu) \ - unwrapOne(X, input, output, 5, ga) \ - if (laneCount < 7) { \ - X##ge ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 6, ge) \ - X##gi ^= trailingBits; \ - } \ - } \ - } \ - } \ - else { \ - unwrapOne(X, input, output, 0, ba) \ - unwrapOneInvert(X, input, output, 1, be) \ - unwrapOneInvert(X, input, output, 2, bi) \ - unwrapOne(X, input, output, 3, bo) \ - unwrapOne(X, input, output, 4, bu) \ - unwrapOne(X, input, output, 5, ga) \ - unwrapOne(X, input, output, 6, ge) \ - unwrapOne(X, input, output, 7, gi) \ - if (laneCount < 12) { \ - if (laneCount < 10) { \ - if (laneCount < 9) { \ - X##go ^= trailingBits; \ - } \ - else { \ - unwrapOneInvert(X, input, output, 8, go) \ - X##gu ^= trailingBits; \ - } \ - } \ - else { \ - unwrapOneInvert(X, input, output, 8, go) \ - unwrapOne(X, input, output, 9, gu) \ - if (laneCount < 11) { \ - X##ka ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 10, ka) \ - X##ke ^= trailingBits; \ - } \ - } \ - } \ - else { \ - unwrapOneInvert(X, input, output, 8, go) \ - unwrapOne(X, input, output, 9, gu) \ - unwrapOne(X, input, output, 10, ka) \ - unwrapOne(X, input, output, 11, ke) \ - if (laneCount < 14) { \ - if (laneCount < 13) { \ - X##ki ^= trailingBits; \ - } \ - else { \ - unwrapOneInvert(X, input, output, 12, ki) \ - X##ko ^= trailingBits; \ - } \ - } \ - else { \ - unwrapOneInvert(X, input, output, 12, ki) \ - unwrapOne(X, input, output, 13, ko) \ - if (laneCount < 15) { \ - X##ku ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 14, ku) \ - X##ma ^= trailingBits; \ - } \ - } \ - } \ - } \ - } \ - else { \ - unwrapOne(X, input, output, 0, ba) \ - unwrapOneInvert(X, input, output, 1, be) \ - unwrapOneInvert(X, input, output, 2, bi) \ - unwrapOne(X, input, output, 3, bo) \ - unwrapOne(X, input, output, 4, bu) \ - unwrapOne(X, input, output, 5, ga) \ - unwrapOne(X, input, output, 6, ge) \ - unwrapOne(X, input, output, 7, gi) \ - unwrapOneInvert(X, input, output, 8, go) \ - unwrapOne(X, input, output, 9, gu) \ - unwrapOne(X, input, output, 10, ka) \ - unwrapOne(X, input, output, 11, ke) \ - unwrapOneInvert(X, input, output, 12, ki) \ - unwrapOne(X, input, output, 13, ko) \ - unwrapOne(X, input, output, 14, ku) \ - unwrapOne(X, input, output, 15, ma) \ - if (laneCount < 24) { \ - if (laneCount < 20) { \ - if (laneCount < 18) { \ - if (laneCount < 17) { \ - X##me ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 16, me) \ - X##mi ^= trailingBits; \ - } \ - } \ - else { \ - unwrapOne(X, input, output, 16, me) \ - unwrapOneInvert(X, input, output, 17, mi) \ - if (laneCount < 19) { \ - X##mo ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 18, mo) \ - X##mu ^= trailingBits; \ - } \ - } \ - } \ - else { \ - unwrapOne(X, input, output, 16, me) \ - unwrapOneInvert(X, input, output, 17, mi) \ - unwrapOne(X, input, output, 18, mo) \ - unwrapOne(X, input, output, 19, mu) \ - if (laneCount < 22) { \ - if (laneCount < 21) { \ - X##sa ^= trailingBits; \ - } \ - else { \ - unwrapOneInvert(X, input, output, 20, sa) \ - X##se ^= trailingBits; \ - } \ - } \ - else { \ - unwrapOneInvert(X, input, output, 20, sa) \ - unwrapOne(X, input, output, 21, se) \ - if (laneCount < 23) { \ - X##si ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 22, si) \ - X##so ^= trailingBits; \ - } \ - } \ - } \ - } \ - else { \ - unwrapOne(X, input, output, 16, me) \ - unwrapOneInvert(X, input, output, 17, mi) \ - unwrapOne(X, input, output, 18, mo) \ - unwrapOne(X, input, output, 19, mu) \ - unwrapOneInvert(X, input, output, 20, sa) \ - unwrapOne(X, input, output, 21, se) \ - unwrapOne(X, input, output, 22, si) \ - unwrapOne(X, input, output, 23, so) \ - if (laneCount < 25) { \ - X##su ^= trailingBits; \ - } \ - else { \ - unwrapOne(X, input, output, 24, su) \ - } \ - } \ - } diff --git a/Modules/_sha3/kcp/KeccakP-1600-SnP-opt32.h b/Modules/_sha3/kcp/KeccakP-1600-SnP-opt32.h deleted file mode 100644 index 6cf765e6ce11e..0000000000000 --- a/Modules/_sha3/kcp/KeccakP-1600-SnP-opt32.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Micha?l Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#ifndef _KeccakP_1600_SnP_h_ -#define _KeccakP_1600_SnP_h_ - -/** For the documentation, see SnP-documentation.h. - */ - -#define KeccakP1600_implementation "in-place 32-bit optimized implementation" -#define KeccakP1600_stateSizeInBytes 200 -#define KeccakP1600_stateAlignment 8 - -#define KeccakP1600_StaticInitialize() -void KeccakP1600_Initialize(void *state); -void KeccakP1600_AddByte(void *state, unsigned char data, unsigned int offset); -void KeccakP1600_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); -void KeccakP1600_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); -void KeccakP1600_OverwriteWithZeroes(void *state, unsigned int byteCount); -void KeccakP1600_Permute_12rounds(void *state); -void KeccakP1600_Permute_24rounds(void *state); -void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length); -void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length); - -#endif diff --git a/Modules/_sha3/kcp/KeccakP-1600-SnP-opt64.h b/Modules/_sha3/kcp/KeccakP-1600-SnP-opt64.h deleted file mode 100644 index 889a31a79444c..0000000000000 --- a/Modules/_sha3/kcp/KeccakP-1600-SnP-opt64.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Micha?l Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#ifndef _KeccakP_1600_SnP_h_ -#define _KeccakP_1600_SnP_h_ - -/** For the documentation, see SnP-documentation.h. - */ - -/* #include "brg_endian.h" */ -#include "KeccakP-1600-opt64-config.h" - -#define KeccakP1600_implementation "generic 64-bit optimized implementation (" KeccakP1600_implementation_config ")" -#define KeccakP1600_stateSizeInBytes 200 -#define KeccakP1600_stateAlignment 8 -#define KeccakF1600_FastLoop_supported - -#include - -#define KeccakP1600_StaticInitialize() -void KeccakP1600_Initialize(void *state); -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) -#define KeccakP1600_AddByte(state, byte, offset) \ - ((unsigned char*)(state))[(offset)] ^= (byte) -#else -void KeccakP1600_AddByte(void *state, unsigned char data, unsigned int offset); -#endif -void KeccakP1600_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); -void KeccakP1600_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); -void KeccakP1600_OverwriteWithZeroes(void *state, unsigned int byteCount); -void KeccakP1600_Permute_12rounds(void *state); -void KeccakP1600_Permute_24rounds(void *state); -void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length); -void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length); -size_t KeccakF1600_FastLoop_Absorb(void *state, unsigned int laneCount, const unsigned char *data, size_t dataByteLen); - -#endif diff --git a/Modules/_sha3/kcp/KeccakP-1600-SnP.h b/Modules/_sha3/kcp/KeccakP-1600-SnP.h deleted file mode 100644 index 0b23f09a6a442..0000000000000 --- a/Modules/_sha3/kcp/KeccakP-1600-SnP.h +++ /dev/null @@ -1,7 +0,0 @@ -#if KeccakOpt == 64 - #include "KeccakP-1600-SnP-opt64.h" -#elif KeccakOpt == 32 - #include "KeccakP-1600-SnP-opt32.h" -#else - #error "No KeccakOpt" -#endif diff --git a/Modules/_sha3/kcp/KeccakP-1600-inplace32BI.c b/Modules/_sha3/kcp/KeccakP-1600-inplace32BI.c deleted file mode 100644 index a2f9ffea93259..0000000000000 --- a/Modules/_sha3/kcp/KeccakP-1600-inplace32BI.c +++ /dev/null @@ -1,1162 +0,0 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Micha?l Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#include -/* #include "brg_endian.h" */ -#include "KeccakP-1600-SnP.h" -#include "SnP-Relaned.h" - -typedef unsigned char UINT8; -typedef unsigned int UINT32; -/* WARNING: on 8-bit and 16-bit platforms, this should be replaced by: */ - -/*typedef unsigned long UINT32; */ - - -#define ROL32(a, offset) ((((UINT32)a) << (offset)) ^ (((UINT32)a) >> (32-(offset)))) - -/* Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */ - -#define prepareToBitInterleaving(low, high, temp, temp0, temp1) \ - temp0 = (low); \ - temp = (temp0 ^ (temp0 >> 1)) & 0x22222222UL; temp0 = temp0 ^ temp ^ (temp << 1); \ - temp = (temp0 ^ (temp0 >> 2)) & 0x0C0C0C0CUL; temp0 = temp0 ^ temp ^ (temp << 2); \ - temp = (temp0 ^ (temp0 >> 4)) & 0x00F000F0UL; temp0 = temp0 ^ temp ^ (temp << 4); \ - temp = (temp0 ^ (temp0 >> 8)) & 0x0000FF00UL; temp0 = temp0 ^ temp ^ (temp << 8); \ - temp1 = (high); \ - temp = (temp1 ^ (temp1 >> 1)) & 0x22222222UL; temp1 = temp1 ^ temp ^ (temp << 1); \ - temp = (temp1 ^ (temp1 >> 2)) & 0x0C0C0C0CUL; temp1 = temp1 ^ temp ^ (temp << 2); \ - temp = (temp1 ^ (temp1 >> 4)) & 0x00F000F0UL; temp1 = temp1 ^ temp ^ (temp << 4); \ - temp = (temp1 ^ (temp1 >> 8)) & 0x0000FF00UL; temp1 = temp1 ^ temp ^ (temp << 8); - -#define toBitInterleavingAndXOR(low, high, even, odd, temp, temp0, temp1) \ - prepareToBitInterleaving(low, high, temp, temp0, temp1) \ - even ^= (temp0 & 0x0000FFFF) | (temp1 << 16); \ - odd ^= (temp0 >> 16) | (temp1 & 0xFFFF0000); - -#define toBitInterleavingAndAND(low, high, even, odd, temp, temp0, temp1) \ - prepareToBitInterleaving(low, high, temp, temp0, temp1) \ - even &= (temp0 & 0x0000FFFF) | (temp1 << 16); \ - odd &= (temp0 >> 16) | (temp1 & 0xFFFF0000); - -#define toBitInterleavingAndSet(low, high, even, odd, temp, temp0, temp1) \ - prepareToBitInterleaving(low, high, temp, temp0, temp1) \ - even = (temp0 & 0x0000FFFF) | (temp1 << 16); \ - odd = (temp0 >> 16) | (temp1 & 0xFFFF0000); - -/* Credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */ - -#define prepareFromBitInterleaving(even, odd, temp, temp0, temp1) \ - temp0 = (even); \ - temp1 = (odd); \ - temp = (temp0 & 0x0000FFFF) | (temp1 << 16); \ - temp1 = (temp0 >> 16) | (temp1 & 0xFFFF0000); \ - temp0 = temp; \ - temp = (temp0 ^ (temp0 >> 8)) & 0x0000FF00UL; temp0 = temp0 ^ temp ^ (temp << 8); \ - temp = (temp0 ^ (temp0 >> 4)) & 0x00F000F0UL; temp0 = temp0 ^ temp ^ (temp << 4); \ - temp = (temp0 ^ (temp0 >> 2)) & 0x0C0C0C0CUL; temp0 = temp0 ^ temp ^ (temp << 2); \ - temp = (temp0 ^ (temp0 >> 1)) & 0x22222222UL; temp0 = temp0 ^ temp ^ (temp << 1); \ - temp = (temp1 ^ (temp1 >> 8)) & 0x0000FF00UL; temp1 = temp1 ^ temp ^ (temp << 8); \ - temp = (temp1 ^ (temp1 >> 4)) & 0x00F000F0UL; temp1 = temp1 ^ temp ^ (temp << 4); \ - temp = (temp1 ^ (temp1 >> 2)) & 0x0C0C0C0CUL; temp1 = temp1 ^ temp ^ (temp << 2); \ - temp = (temp1 ^ (temp1 >> 1)) & 0x22222222UL; temp1 = temp1 ^ temp ^ (temp << 1); - -#define fromBitInterleaving(even, odd, low, high, temp, temp0, temp1) \ - prepareFromBitInterleaving(even, odd, temp, temp0, temp1) \ - low = temp0; \ - high = temp1; - -#define fromBitInterleavingAndXOR(even, odd, lowIn, highIn, lowOut, highOut, temp, temp0, temp1) \ - prepareFromBitInterleaving(even, odd, temp, temp0, temp1) \ - lowOut = lowIn ^ temp0; \ - highOut = highIn ^ temp1; - -void KeccakP1600_SetBytesInLaneToZero(void *state, unsigned int lanePosition, unsigned int offset, unsigned int length) -{ - UINT8 laneAsBytes[8]; - UINT32 low, high; - UINT32 temp, temp0, temp1; - UINT32 *stateAsHalfLanes = (UINT32*)state; - - memset(laneAsBytes, 0xFF, offset); - memset(laneAsBytes+offset, 0x00, length); - memset(laneAsBytes+offset+length, 0xFF, 8-offset-length); -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - low = *((UINT32*)(laneAsBytes+0)); - high = *((UINT32*)(laneAsBytes+4)); -#else - low = laneAsBytes[0] - | ((UINT32)(laneAsBytes[1]) << 8) - | ((UINT32)(laneAsBytes[2]) << 16) - | ((UINT32)(laneAsBytes[3]) << 24); - high = laneAsBytes[4] - | ((UINT32)(laneAsBytes[5]) << 8) - | ((UINT32)(laneAsBytes[6]) << 16) - | ((UINT32)(laneAsBytes[7]) << 24); -#endif - toBitInterleavingAndAND(low, high, stateAsHalfLanes[lanePosition*2+0], stateAsHalfLanes[lanePosition*2+1], temp, temp0, temp1); -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_Initialize(void *state) -{ - memset(state, 0, 200); -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_AddByte(void *state, unsigned char byte, unsigned int offset) -{ - unsigned int lanePosition = offset/8; - unsigned int offsetInLane = offset%8; - UINT32 low, high; - UINT32 temp, temp0, temp1; - UINT32 *stateAsHalfLanes = (UINT32*)state; - - if (offsetInLane < 4) { - low = (UINT32)byte << (offsetInLane*8); - high = 0; - } - else { - low = 0; - high = (UINT32)byte << ((offsetInLane-4)*8); - } - toBitInterleavingAndXOR(low, high, stateAsHalfLanes[lanePosition*2+0], stateAsHalfLanes[lanePosition*2+1], temp, temp0, temp1); -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_AddBytesInLane(void *state, unsigned int lanePosition, const unsigned char *data, unsigned int offset, unsigned int length) -{ - UINT8 laneAsBytes[8]; - UINT32 low, high; - UINT32 temp, temp0, temp1; - UINT32 *stateAsHalfLanes = (UINT32*)state; - - memset(laneAsBytes, 0, 8); - memcpy(laneAsBytes+offset, data, length); -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - low = *((UINT32*)(laneAsBytes+0)); - high = *((UINT32*)(laneAsBytes+4)); -#else - low = laneAsBytes[0] - | ((UINT32)(laneAsBytes[1]) << 8) - | ((UINT32)(laneAsBytes[2]) << 16) - | ((UINT32)(laneAsBytes[3]) << 24); - high = laneAsBytes[4] - | ((UINT32)(laneAsBytes[5]) << 8) - | ((UINT32)(laneAsBytes[6]) << 16) - | ((UINT32)(laneAsBytes[7]) << 24); -#endif - toBitInterleavingAndXOR(low, high, stateAsHalfLanes[lanePosition*2+0], stateAsHalfLanes[lanePosition*2+1], temp, temp0, temp1); -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_AddLanes(void *state, const unsigned char *data, unsigned int laneCount) -{ -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - const UINT32 * pI = (const UINT32 *)data; - UINT32 * pS = (UINT32*)state; - UINT32 t, x0, x1; - int i; - for (i = laneCount-1; i >= 0; --i) { -#ifdef NO_MISALIGNED_ACCESSES - UINT32 low; - UINT32 high; - memcpy(&low, pI++, 4); - memcpy(&high, pI++, 4); - toBitInterleavingAndXOR(low, high, *(pS++), *(pS++), t, x0, x1); -#else - toBitInterleavingAndXOR(*(pI++), *(pI++), *(pS++), *(pS++), t, x0, x1) -#endif - } -#else - unsigned int lanePosition; - for(lanePosition=0; lanePosition= 0; --i) { -#ifdef NO_MISALIGNED_ACCESSES - UINT32 low; - UINT32 high; - memcpy(&low, pI++, 4); - memcpy(&high, pI++, 4); - toBitInterleavingAndSet(low, high, *(pS++), *(pS++), t, x0, x1); -#else - toBitInterleavingAndSet(*(pI++), *(pI++), *(pS++), *(pS++), t, x0, x1) -#endif - } -#else - unsigned int lanePosition; - for(lanePosition=0; lanePosition> 8) & 0xFF; - laneAsBytes[2] = (low >> 16) & 0xFF; - laneAsBytes[3] = (low >> 24) & 0xFF; - laneAsBytes[4] = high & 0xFF; - laneAsBytes[5] = (high >> 8) & 0xFF; - laneAsBytes[6] = (high >> 16) & 0xFF; - laneAsBytes[7] = (high >> 24) & 0xFF; -#endif - memcpy(data, laneAsBytes+offset, length); -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_ExtractLanes(const void *state, unsigned char *data, unsigned int laneCount) -{ -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - UINT32 * pI = (UINT32 *)data; - const UINT32 * pS = ( const UINT32 *)state; - UINT32 t, x0, x1; - int i; - for (i = laneCount-1; i >= 0; --i) { -#ifdef NO_MISALIGNED_ACCESSES - UINT32 low; - UINT32 high; - fromBitInterleaving(*(pS++), *(pS++), low, high, t, x0, x1); - memcpy(pI++, &low, 4); - memcpy(pI++, &high, 4); -#else - fromBitInterleaving(*(pS++), *(pS++), *(pI++), *(pI++), t, x0, x1) -#endif - } -#else - unsigned int lanePosition; - for(lanePosition=0; lanePosition> 8) & 0xFF; - laneAsBytes[2] = (low >> 16) & 0xFF; - laneAsBytes[3] = (low >> 24) & 0xFF; - laneAsBytes[4] = high & 0xFF; - laneAsBytes[5] = (high >> 8) & 0xFF; - laneAsBytes[6] = (high >> 16) & 0xFF; - laneAsBytes[7] = (high >> 24) & 0xFF; - memcpy(data+lanePosition*8, laneAsBytes, 8); - } -#endif -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length) -{ - SnP_ExtractBytes(state, data, offset, length, KeccakP1600_ExtractLanes, KeccakP1600_ExtractBytesInLane, 8); -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_ExtractAndAddBytesInLane(const void *state, unsigned int lanePosition, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) -{ - UINT32 *stateAsHalfLanes = (UINT32*)state; - UINT32 low, high, temp, temp0, temp1; - UINT8 laneAsBytes[8]; - unsigned int i; - - fromBitInterleaving(stateAsHalfLanes[lanePosition*2], stateAsHalfLanes[lanePosition*2+1], low, high, temp, temp0, temp1); -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - *((UINT32*)(laneAsBytes+0)) = low; - *((UINT32*)(laneAsBytes+4)) = high; -#else - laneAsBytes[0] = low & 0xFF; - laneAsBytes[1] = (low >> 8) & 0xFF; - laneAsBytes[2] = (low >> 16) & 0xFF; - laneAsBytes[3] = (low >> 24) & 0xFF; - laneAsBytes[4] = high & 0xFF; - laneAsBytes[5] = (high >> 8) & 0xFF; - laneAsBytes[6] = (high >> 16) & 0xFF; - laneAsBytes[7] = (high >> 24) & 0xFF; -#endif - for(i=0; i= 0; --i) { -#ifdef NO_MISALIGNED_ACCESSES - UINT32 low; - UINT32 high; - fromBitInterleaving(*(pS++), *(pS++), low, high, t, x0, x1); - *(pO++) = *(pI++) ^ low; - *(pO++) = *(pI++) ^ high; -#else - fromBitInterleavingAndXOR(*(pS++), *(pS++), *(pI++), *(pI++), *(pO++), *(pO++), t, x0, x1) -#endif - } -#else - unsigned int lanePosition; - for(lanePosition=0; lanePosition> 8) & 0xFF; - laneAsBytes[2] = (low >> 16) & 0xFF; - laneAsBytes[3] = (low >> 24) & 0xFF; - laneAsBytes[4] = high & 0xFF; - laneAsBytes[5] = (high >> 8) & 0xFF; - laneAsBytes[6] = (high >> 16) & 0xFF; - laneAsBytes[7] = (high >> 24) & 0xFF; - ((UINT32*)(output+lanePosition*8))[0] = ((UINT32*)(input+lanePosition*8))[0] ^ (*(const UINT32*)(laneAsBytes+0)); - ((UINT32*)(output+lanePosition*8))[1] = ((UINT32*)(input+lanePosition*8))[0] ^ (*(const UINT32*)(laneAsBytes+4)); - } -#endif -} -/* ---------------------------------------------------------------- */ - -void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) -{ - SnP_ExtractAndAddBytes(state, input, output, offset, length, KeccakP1600_ExtractAndAddLanes, KeccakP1600_ExtractAndAddBytesInLane, 8); -} - -/* ---------------------------------------------------------------- */ - -static const UINT32 KeccakF1600RoundConstants_int2[2*24+1] = -{ - 0x00000001UL, 0x00000000UL, - 0x00000000UL, 0x00000089UL, - 0x00000000UL, 0x8000008bUL, - 0x00000000UL, 0x80008080UL, - 0x00000001UL, 0x0000008bUL, - 0x00000001UL, 0x00008000UL, - 0x00000001UL, 0x80008088UL, - 0x00000001UL, 0x80000082UL, - 0x00000000UL, 0x0000000bUL, - 0x00000000UL, 0x0000000aUL, - 0x00000001UL, 0x00008082UL, - 0x00000000UL, 0x00008003UL, - 0x00000001UL, 0x0000808bUL, - 0x00000001UL, 0x8000000bUL, - 0x00000001UL, 0x8000008aUL, - 0x00000001UL, 0x80000081UL, - 0x00000000UL, 0x80000081UL, - 0x00000000UL, 0x80000008UL, - 0x00000000UL, 0x00000083UL, - 0x00000000UL, 0x80008003UL, - 0x00000001UL, 0x80008088UL, - 0x00000000UL, 0x80000088UL, - 0x00000001UL, 0x00008000UL, - 0x00000000UL, 0x80008082UL, - 0x000000FFUL -}; - -#define KeccakAtoD_round0() \ - Cx = Abu0^Agu0^Aku0^Amu0^Asu0; \ - Du1 = Abe1^Age1^Ake1^Ame1^Ase1; \ - Da0 = Cx^ROL32(Du1, 1); \ - Cz = Abu1^Agu1^Aku1^Amu1^Asu1; \ - Du0 = Abe0^Age0^Ake0^Ame0^Ase0; \ - Da1 = Cz^Du0; \ -\ - Cw = Abi0^Agi0^Aki0^Ami0^Asi0; \ - Do0 = Cw^ROL32(Cz, 1); \ - Cy = Abi1^Agi1^Aki1^Ami1^Asi1; \ - Do1 = Cy^Cx; \ -\ - Cx = Aba0^Aga0^Aka0^Ama0^Asa0; \ - De0 = Cx^ROL32(Cy, 1); \ - Cz = Aba1^Aga1^Aka1^Ama1^Asa1; \ - De1 = Cz^Cw; \ -\ - Cy = Abo1^Ago1^Ako1^Amo1^Aso1; \ - Di0 = Du0^ROL32(Cy, 1); \ - Cw = Abo0^Ago0^Ako0^Amo0^Aso0; \ - Di1 = Du1^Cw; \ -\ - Du0 = Cw^ROL32(Cz, 1); \ - Du1 = Cy^Cx; \ - -#define KeccakAtoD_round1() \ - Cx = Asu0^Agu0^Amu0^Abu1^Aku1; \ - Du1 = Age1^Ame0^Abe0^Ake1^Ase1; \ - Da0 = Cx^ROL32(Du1, 1); \ - Cz = Asu1^Agu1^Amu1^Abu0^Aku0; \ - Du0 = Age0^Ame1^Abe1^Ake0^Ase0; \ - Da1 = Cz^Du0; \ -\ - Cw = Aki1^Asi1^Agi0^Ami1^Abi0; \ - Do0 = Cw^ROL32(Cz, 1); \ - Cy = Aki0^Asi0^Agi1^Ami0^Abi1; \ - Do1 = Cy^Cx; \ -\ - Cx = Aba0^Aka1^Asa0^Aga0^Ama1; \ - De0 = Cx^ROL32(Cy, 1); \ - Cz = Aba1^Aka0^Asa1^Aga1^Ama0; \ - De1 = Cz^Cw; \ -\ - Cy = Amo0^Abo1^Ako0^Aso1^Ago0; \ - Di0 = Du0^ROL32(Cy, 1); \ - Cw = Amo1^Abo0^Ako1^Aso0^Ago1; \ - Di1 = Du1^Cw; \ -\ - Du0 = Cw^ROL32(Cz, 1); \ - Du1 = Cy^Cx; \ - -#define KeccakAtoD_round2() \ - Cx = Aku1^Agu0^Abu1^Asu1^Amu1; \ - Du1 = Ame0^Ake0^Age0^Abe0^Ase1; \ - Da0 = Cx^ROL32(Du1, 1); \ - Cz = Aku0^Agu1^Abu0^Asu0^Amu0; \ - Du0 = Ame1^Ake1^Age1^Abe1^Ase0; \ - Da1 = Cz^Du0; \ -\ - Cw = Agi1^Abi1^Asi1^Ami0^Aki1; \ - Do0 = Cw^ROL32(Cz, 1); \ - Cy = Agi0^Abi0^Asi0^Ami1^Aki0; \ - Do1 = Cy^Cx; \ -\ - Cx = Aba0^Asa1^Ama1^Aka1^Aga1; \ - De0 = Cx^ROL32(Cy, 1); \ - Cz = Aba1^Asa0^Ama0^Aka0^Aga0; \ - De1 = Cz^Cw; \ -\ - Cy = Aso0^Amo0^Ako1^Ago0^Abo0; \ - Di0 = Du0^ROL32(Cy, 1); \ - Cw = Aso1^Amo1^Ako0^Ago1^Abo1; \ - Di1 = Du1^Cw; \ -\ - Du0 = Cw^ROL32(Cz, 1); \ - Du1 = Cy^Cx; \ - -#define KeccakAtoD_round3() \ - Cx = Amu1^Agu0^Asu1^Aku0^Abu0; \ - Du1 = Ake0^Abe1^Ame1^Age0^Ase1; \ - Da0 = Cx^ROL32(Du1, 1); \ - Cz = Amu0^Agu1^Asu0^Aku1^Abu1; \ - Du0 = Ake1^Abe0^Ame0^Age1^Ase0; \ - Da1 = Cz^Du0; \ -\ - Cw = Asi0^Aki0^Abi1^Ami1^Agi1; \ - Do0 = Cw^ROL32(Cz, 1); \ - Cy = Asi1^Aki1^Abi0^Ami0^Agi0; \ - Do1 = Cy^Cx; \ -\ - Cx = Aba0^Ama0^Aga1^Asa1^Aka0; \ - De0 = Cx^ROL32(Cy, 1); \ - Cz = Aba1^Ama1^Aga0^Asa0^Aka1; \ - De1 = Cz^Cw; \ -\ - Cy = Ago1^Aso0^Ako0^Abo0^Amo1; \ - Di0 = Du0^ROL32(Cy, 1); \ - Cw = Ago0^Aso1^Ako1^Abo1^Amo0; \ - Di1 = Du1^Cw; \ -\ - Du0 = Cw^ROL32(Cz, 1); \ - Du1 = Cy^Cx; \ - -void KeccakP1600_Permute_Nrounds(void *state, unsigned int nRounds) -{ - { - UINT32 Da0, De0, Di0, Do0, Du0; - UINT32 Da1, De1, Di1, Do1, Du1; - UINT32 Ca0, Ce0, Ci0, Co0, Cu0; - UINT32 Cx, Cy, Cz, Cw; - #define Ba Ca0 - #define Be Ce0 - #define Bi Ci0 - #define Bo Co0 - #define Bu Cu0 - const UINT32 *pRoundConstants = KeccakF1600RoundConstants_int2+(24-nRounds)*2; - UINT32 *stateAsHalfLanes = (UINT32*)state; - #define Aba0 stateAsHalfLanes[ 0] - #define Aba1 stateAsHalfLanes[ 1] - #define Abe0 stateAsHalfLanes[ 2] - #define Abe1 stateAsHalfLanes[ 3] - #define Abi0 stateAsHalfLanes[ 4] - #define Abi1 stateAsHalfLanes[ 5] - #define Abo0 stateAsHalfLanes[ 6] - #define Abo1 stateAsHalfLanes[ 7] - #define Abu0 stateAsHalfLanes[ 8] - #define Abu1 stateAsHalfLanes[ 9] - #define Aga0 stateAsHalfLanes[10] - #define Aga1 stateAsHalfLanes[11] - #define Age0 stateAsHalfLanes[12] - #define Age1 stateAsHalfLanes[13] - #define Agi0 stateAsHalfLanes[14] - #define Agi1 stateAsHalfLanes[15] - #define Ago0 stateAsHalfLanes[16] - #define Ago1 stateAsHalfLanes[17] - #define Agu0 stateAsHalfLanes[18] - #define Agu1 stateAsHalfLanes[19] - #define Aka0 stateAsHalfLanes[20] - #define Aka1 stateAsHalfLanes[21] - #define Ake0 stateAsHalfLanes[22] - #define Ake1 stateAsHalfLanes[23] - #define Aki0 stateAsHalfLanes[24] - #define Aki1 stateAsHalfLanes[25] - #define Ako0 stateAsHalfLanes[26] - #define Ako1 stateAsHalfLanes[27] - #define Aku0 stateAsHalfLanes[28] - #define Aku1 stateAsHalfLanes[29] - #define Ama0 stateAsHalfLanes[30] - #define Ama1 stateAsHalfLanes[31] - #define Ame0 stateAsHalfLanes[32] - #define Ame1 stateAsHalfLanes[33] - #define Ami0 stateAsHalfLanes[34] - #define Ami1 stateAsHalfLanes[35] - #define Amo0 stateAsHalfLanes[36] - #define Amo1 stateAsHalfLanes[37] - #define Amu0 stateAsHalfLanes[38] - #define Amu1 stateAsHalfLanes[39] - #define Asa0 stateAsHalfLanes[40] - #define Asa1 stateAsHalfLanes[41] - #define Ase0 stateAsHalfLanes[42] - #define Ase1 stateAsHalfLanes[43] - #define Asi0 stateAsHalfLanes[44] - #define Asi1 stateAsHalfLanes[45] - #define Aso0 stateAsHalfLanes[46] - #define Aso1 stateAsHalfLanes[47] - #define Asu0 stateAsHalfLanes[48] - #define Asu1 stateAsHalfLanes[49] - - do - { - /* --- Code for 4 rounds */ - - /* --- using factor 2 interleaving, 64-bit lanes mapped to 32-bit words */ - - KeccakAtoD_round0(); - - Ba = (Aba0^Da0); - Be = ROL32((Age0^De0), 22); - Bi = ROL32((Aki1^Di1), 22); - Bo = ROL32((Amo1^Do1), 11); - Bu = ROL32((Asu0^Du0), 7); - Aba0 = Ba ^((~Be)& Bi ); - Aba0 ^= *(pRoundConstants++); - Age0 = Be ^((~Bi)& Bo ); - Aki1 = Bi ^((~Bo)& Bu ); - Amo1 = Bo ^((~Bu)& Ba ); - Asu0 = Bu ^((~Ba)& Be ); - - Ba = (Aba1^Da1); - Be = ROL32((Age1^De1), 22); - Bi = ROL32((Aki0^Di0), 21); - Bo = ROL32((Amo0^Do0), 10); - Bu = ROL32((Asu1^Du1), 7); - Aba1 = Ba ^((~Be)& Bi ); - Aba1 ^= *(pRoundConstants++); - Age1 = Be ^((~Bi)& Bo ); - Aki0 = Bi ^((~Bo)& Bu ); - Amo0 = Bo ^((~Bu)& Ba ); - Asu1 = Bu ^((~Ba)& Be ); - - Bi = ROL32((Aka1^Da1), 2); - Bo = ROL32((Ame1^De1), 23); - Bu = ROL32((Asi1^Di1), 31); - Ba = ROL32((Abo0^Do0), 14); - Be = ROL32((Agu0^Du0), 10); - Aka1 = Ba ^((~Be)& Bi ); - Ame1 = Be ^((~Bi)& Bo ); - Asi1 = Bi ^((~Bo)& Bu ); - Abo0 = Bo ^((~Bu)& Ba ); - Agu0 = Bu ^((~Ba)& Be ); - - Bi = ROL32((Aka0^Da0), 1); - Bo = ROL32((Ame0^De0), 22); - Bu = ROL32((Asi0^Di0), 30); - Ba = ROL32((Abo1^Do1), 14); - Be = ROL32((Agu1^Du1), 10); - Aka0 = Ba ^((~Be)& Bi ); - Ame0 = Be ^((~Bi)& Bo ); - Asi0 = Bi ^((~Bo)& Bu ); - Abo1 = Bo ^((~Bu)& Ba ); - Agu1 = Bu ^((~Ba)& Be ); - - Bu = ROL32((Asa0^Da0), 9); - Ba = ROL32((Abe1^De1), 1); - Be = ROL32((Agi0^Di0), 3); - Bi = ROL32((Ako1^Do1), 13); - Bo = ROL32((Amu0^Du0), 4); - Asa0 = Ba ^((~Be)& Bi ); - Abe1 = Be ^((~Bi)& Bo ); - Agi0 = Bi ^((~Bo)& Bu ); - Ako1 = Bo ^((~Bu)& Ba ); - Amu0 = Bu ^((~Ba)& Be ); - - Bu = ROL32((Asa1^Da1), 9); - Ba = (Abe0^De0); - Be = ROL32((Agi1^Di1), 3); - Bi = ROL32((Ako0^Do0), 12); - Bo = ROL32((Amu1^Du1), 4); - Asa1 = Ba ^((~Be)& Bi ); - Abe0 = Be ^((~Bi)& Bo ); - Agi1 = Bi ^((~Bo)& Bu ); - Ako0 = Bo ^((~Bu)& Ba ); - Amu1 = Bu ^((~Ba)& Be ); - - Be = ROL32((Aga0^Da0), 18); - Bi = ROL32((Ake0^De0), 5); - Bo = ROL32((Ami1^Di1), 8); - Bu = ROL32((Aso0^Do0), 28); - Ba = ROL32((Abu1^Du1), 14); - Aga0 = Ba ^((~Be)& Bi ); - Ake0 = Be ^((~Bi)& Bo ); - Ami1 = Bi ^((~Bo)& Bu ); - Aso0 = Bo ^((~Bu)& Ba ); - Abu1 = Bu ^((~Ba)& Be ); - - Be = ROL32((Aga1^Da1), 18); - Bi = ROL32((Ake1^De1), 5); - Bo = ROL32((Ami0^Di0), 7); - Bu = ROL32((Aso1^Do1), 28); - Ba = ROL32((Abu0^Du0), 13); - Aga1 = Ba ^((~Be)& Bi ); - Ake1 = Be ^((~Bi)& Bo ); - Ami0 = Bi ^((~Bo)& Bu ); - Aso1 = Bo ^((~Bu)& Ba ); - Abu0 = Bu ^((~Ba)& Be ); - - Bo = ROL32((Ama1^Da1), 21); - Bu = ROL32((Ase0^De0), 1); - Ba = ROL32((Abi0^Di0), 31); - Be = ROL32((Ago1^Do1), 28); - Bi = ROL32((Aku1^Du1), 20); - Ama1 = Ba ^((~Be)& Bi ); - Ase0 = Be ^((~Bi)& Bo ); - Abi0 = Bi ^((~Bo)& Bu ); - Ago1 = Bo ^((~Bu)& Ba ); - Aku1 = Bu ^((~Ba)& Be ); - - Bo = ROL32((Ama0^Da0), 20); - Bu = ROL32((Ase1^De1), 1); - Ba = ROL32((Abi1^Di1), 31); - Be = ROL32((Ago0^Do0), 27); - Bi = ROL32((Aku0^Du0), 19); - Ama0 = Ba ^((~Be)& Bi ); - Ase1 = Be ^((~Bi)& Bo ); - Abi1 = Bi ^((~Bo)& Bu ); - Ago0 = Bo ^((~Bu)& Ba ); - Aku0 = Bu ^((~Ba)& Be ); - - KeccakAtoD_round1(); - - Ba = (Aba0^Da0); - Be = ROL32((Ame1^De0), 22); - Bi = ROL32((Agi1^Di1), 22); - Bo = ROL32((Aso1^Do1), 11); - Bu = ROL32((Aku1^Du0), 7); - Aba0 = Ba ^((~Be)& Bi ); - Aba0 ^= *(pRoundConstants++); - Ame1 = Be ^((~Bi)& Bo ); - Agi1 = Bi ^((~Bo)& Bu ); - Aso1 = Bo ^((~Bu)& Ba ); - Aku1 = Bu ^((~Ba)& Be ); - - Ba = (Aba1^Da1); - Be = ROL32((Ame0^De1), 22); - Bi = ROL32((Agi0^Di0), 21); - Bo = ROL32((Aso0^Do0), 10); - Bu = ROL32((Aku0^Du1), 7); - Aba1 = Ba ^((~Be)& Bi ); - Aba1 ^= *(pRoundConstants++); - Ame0 = Be ^((~Bi)& Bo ); - Agi0 = Bi ^((~Bo)& Bu ); - Aso0 = Bo ^((~Bu)& Ba ); - Aku0 = Bu ^((~Ba)& Be ); - - Bi = ROL32((Asa1^Da1), 2); - Bo = ROL32((Ake1^De1), 23); - Bu = ROL32((Abi1^Di1), 31); - Ba = ROL32((Amo1^Do0), 14); - Be = ROL32((Agu0^Du0), 10); - Asa1 = Ba ^((~Be)& Bi ); - Ake1 = Be ^((~Bi)& Bo ); - Abi1 = Bi ^((~Bo)& Bu ); - Amo1 = Bo ^((~Bu)& Ba ); - Agu0 = Bu ^((~Ba)& Be ); - - Bi = ROL32((Asa0^Da0), 1); - Bo = ROL32((Ake0^De0), 22); - Bu = ROL32((Abi0^Di0), 30); - Ba = ROL32((Amo0^Do1), 14); - Be = ROL32((Agu1^Du1), 10); - Asa0 = Ba ^((~Be)& Bi ); - Ake0 = Be ^((~Bi)& Bo ); - Abi0 = Bi ^((~Bo)& Bu ); - Amo0 = Bo ^((~Bu)& Ba ); - Agu1 = Bu ^((~Ba)& Be ); - - Bu = ROL32((Ama1^Da0), 9); - Ba = ROL32((Age1^De1), 1); - Be = ROL32((Asi1^Di0), 3); - Bi = ROL32((Ako0^Do1), 13); - Bo = ROL32((Abu1^Du0), 4); - Ama1 = Ba ^((~Be)& Bi ); - Age1 = Be ^((~Bi)& Bo ); - Asi1 = Bi ^((~Bo)& Bu ); - Ako0 = Bo ^((~Bu)& Ba ); - Abu1 = Bu ^((~Ba)& Be ); - - Bu = ROL32((Ama0^Da1), 9); - Ba = (Age0^De0); - Be = ROL32((Asi0^Di1), 3); - Bi = ROL32((Ako1^Do0), 12); - Bo = ROL32((Abu0^Du1), 4); - Ama0 = Ba ^((~Be)& Bi ); - Age0 = Be ^((~Bi)& Bo ); - Asi0 = Bi ^((~Bo)& Bu ); - Ako1 = Bo ^((~Bu)& Ba ); - Abu0 = Bu ^((~Ba)& Be ); - - Be = ROL32((Aka1^Da0), 18); - Bi = ROL32((Abe1^De0), 5); - Bo = ROL32((Ami0^Di1), 8); - Bu = ROL32((Ago1^Do0), 28); - Ba = ROL32((Asu1^Du1), 14); - Aka1 = Ba ^((~Be)& Bi ); - Abe1 = Be ^((~Bi)& Bo ); - Ami0 = Bi ^((~Bo)& Bu ); - Ago1 = Bo ^((~Bu)& Ba ); - Asu1 = Bu ^((~Ba)& Be ); - - Be = ROL32((Aka0^Da1), 18); - Bi = ROL32((Abe0^De1), 5); - Bo = ROL32((Ami1^Di0), 7); - Bu = ROL32((Ago0^Do1), 28); - Ba = ROL32((Asu0^Du0), 13); - Aka0 = Ba ^((~Be)& Bi ); - Abe0 = Be ^((~Bi)& Bo ); - Ami1 = Bi ^((~Bo)& Bu ); - Ago0 = Bo ^((~Bu)& Ba ); - Asu0 = Bu ^((~Ba)& Be ); - - Bo = ROL32((Aga1^Da1), 21); - Bu = ROL32((Ase0^De0), 1); - Ba = ROL32((Aki1^Di0), 31); - Be = ROL32((Abo1^Do1), 28); - Bi = ROL32((Amu1^Du1), 20); - Aga1 = Ba ^((~Be)& Bi ); - Ase0 = Be ^((~Bi)& Bo ); - Aki1 = Bi ^((~Bo)& Bu ); - Abo1 = Bo ^((~Bu)& Ba ); - Amu1 = Bu ^((~Ba)& Be ); - - Bo = ROL32((Aga0^Da0), 20); - Bu = ROL32((Ase1^De1), 1); - Ba = ROL32((Aki0^Di1), 31); - Be = ROL32((Abo0^Do0), 27); - Bi = ROL32((Amu0^Du0), 19); - Aga0 = Ba ^((~Be)& Bi ); - Ase1 = Be ^((~Bi)& Bo ); - Aki0 = Bi ^((~Bo)& Bu ); - Abo0 = Bo ^((~Bu)& Ba ); - Amu0 = Bu ^((~Ba)& Be ); - - KeccakAtoD_round2(); - - Ba = (Aba0^Da0); - Be = ROL32((Ake1^De0), 22); - Bi = ROL32((Asi0^Di1), 22); - Bo = ROL32((Ago0^Do1), 11); - Bu = ROL32((Amu1^Du0), 7); - Aba0 = Ba ^((~Be)& Bi ); - Aba0 ^= *(pRoundConstants++); - Ake1 = Be ^((~Bi)& Bo ); - Asi0 = Bi ^((~Bo)& Bu ); - Ago0 = Bo ^((~Bu)& Ba ); - Amu1 = Bu ^((~Ba)& Be ); - - Ba = (Aba1^Da1); - Be = ROL32((Ake0^De1), 22); - Bi = ROL32((Asi1^Di0), 21); - Bo = ROL32((Ago1^Do0), 10); - Bu = ROL32((Amu0^Du1), 7); - Aba1 = Ba ^((~Be)& Bi ); - Aba1 ^= *(pRoundConstants++); - Ake0 = Be ^((~Bi)& Bo ); - Asi1 = Bi ^((~Bo)& Bu ); - Ago1 = Bo ^((~Bu)& Ba ); - Amu0 = Bu ^((~Ba)& Be ); - - Bi = ROL32((Ama0^Da1), 2); - Bo = ROL32((Abe0^De1), 23); - Bu = ROL32((Aki0^Di1), 31); - Ba = ROL32((Aso1^Do0), 14); - Be = ROL32((Agu0^Du0), 10); - Ama0 = Ba ^((~Be)& Bi ); - Abe0 = Be ^((~Bi)& Bo ); - Aki0 = Bi ^((~Bo)& Bu ); - Aso1 = Bo ^((~Bu)& Ba ); - Agu0 = Bu ^((~Ba)& Be ); - - Bi = ROL32((Ama1^Da0), 1); - Bo = ROL32((Abe1^De0), 22); - Bu = ROL32((Aki1^Di0), 30); - Ba = ROL32((Aso0^Do1), 14); - Be = ROL32((Agu1^Du1), 10); - Ama1 = Ba ^((~Be)& Bi ); - Abe1 = Be ^((~Bi)& Bo ); - Aki1 = Bi ^((~Bo)& Bu ); - Aso0 = Bo ^((~Bu)& Ba ); - Agu1 = Bu ^((~Ba)& Be ); - - Bu = ROL32((Aga1^Da0), 9); - Ba = ROL32((Ame0^De1), 1); - Be = ROL32((Abi1^Di0), 3); - Bi = ROL32((Ako1^Do1), 13); - Bo = ROL32((Asu1^Du0), 4); - Aga1 = Ba ^((~Be)& Bi ); - Ame0 = Be ^((~Bi)& Bo ); - Abi1 = Bi ^((~Bo)& Bu ); - Ako1 = Bo ^((~Bu)& Ba ); - Asu1 = Bu ^((~Ba)& Be ); - - Bu = ROL32((Aga0^Da1), 9); - Ba = (Ame1^De0); - Be = ROL32((Abi0^Di1), 3); - Bi = ROL32((Ako0^Do0), 12); - Bo = ROL32((Asu0^Du1), 4); - Aga0 = Ba ^((~Be)& Bi ); - Ame1 = Be ^((~Bi)& Bo ); - Abi0 = Bi ^((~Bo)& Bu ); - Ako0 = Bo ^((~Bu)& Ba ); - Asu0 = Bu ^((~Ba)& Be ); - - Be = ROL32((Asa1^Da0), 18); - Bi = ROL32((Age1^De0), 5); - Bo = ROL32((Ami1^Di1), 8); - Bu = ROL32((Abo1^Do0), 28); - Ba = ROL32((Aku0^Du1), 14); - Asa1 = Ba ^((~Be)& Bi ); - Age1 = Be ^((~Bi)& Bo ); - Ami1 = Bi ^((~Bo)& Bu ); - Abo1 = Bo ^((~Bu)& Ba ); - Aku0 = Bu ^((~Ba)& Be ); - - Be = ROL32((Asa0^Da1), 18); - Bi = ROL32((Age0^De1), 5); - Bo = ROL32((Ami0^Di0), 7); - Bu = ROL32((Abo0^Do1), 28); - Ba = ROL32((Aku1^Du0), 13); - Asa0 = Ba ^((~Be)& Bi ); - Age0 = Be ^((~Bi)& Bo ); - Ami0 = Bi ^((~Bo)& Bu ); - Abo0 = Bo ^((~Bu)& Ba ); - Aku1 = Bu ^((~Ba)& Be ); - - Bo = ROL32((Aka0^Da1), 21); - Bu = ROL32((Ase0^De0), 1); - Ba = ROL32((Agi1^Di0), 31); - Be = ROL32((Amo0^Do1), 28); - Bi = ROL32((Abu0^Du1), 20); - Aka0 = Ba ^((~Be)& Bi ); - Ase0 = Be ^((~Bi)& Bo ); - Agi1 = Bi ^((~Bo)& Bu ); - Amo0 = Bo ^((~Bu)& Ba ); - Abu0 = Bu ^((~Ba)& Be ); - - Bo = ROL32((Aka1^Da0), 20); - Bu = ROL32((Ase1^De1), 1); - Ba = ROL32((Agi0^Di1), 31); - Be = ROL32((Amo1^Do0), 27); - Bi = ROL32((Abu1^Du0), 19); - Aka1 = Ba ^((~Be)& Bi ); - Ase1 = Be ^((~Bi)& Bo ); - Agi0 = Bi ^((~Bo)& Bu ); - Amo1 = Bo ^((~Bu)& Ba ); - Abu1 = Bu ^((~Ba)& Be ); - - KeccakAtoD_round3(); - - Ba = (Aba0^Da0); - Be = ROL32((Abe0^De0), 22); - Bi = ROL32((Abi0^Di1), 22); - Bo = ROL32((Abo0^Do1), 11); - Bu = ROL32((Abu0^Du0), 7); - Aba0 = Ba ^((~Be)& Bi ); - Aba0 ^= *(pRoundConstants++); - Abe0 = Be ^((~Bi)& Bo ); - Abi0 = Bi ^((~Bo)& Bu ); - Abo0 = Bo ^((~Bu)& Ba ); - Abu0 = Bu ^((~Ba)& Be ); - - Ba = (Aba1^Da1); - Be = ROL32((Abe1^De1), 22); - Bi = ROL32((Abi1^Di0), 21); - Bo = ROL32((Abo1^Do0), 10); - Bu = ROL32((Abu1^Du1), 7); - Aba1 = Ba ^((~Be)& Bi ); - Aba1 ^= *(pRoundConstants++); - Abe1 = Be ^((~Bi)& Bo ); - Abi1 = Bi ^((~Bo)& Bu ); - Abo1 = Bo ^((~Bu)& Ba ); - Abu1 = Bu ^((~Ba)& Be ); - - Bi = ROL32((Aga0^Da1), 2); - Bo = ROL32((Age0^De1), 23); - Bu = ROL32((Agi0^Di1), 31); - Ba = ROL32((Ago0^Do0), 14); - Be = ROL32((Agu0^Du0), 10); - Aga0 = Ba ^((~Be)& Bi ); - Age0 = Be ^((~Bi)& Bo ); - Agi0 = Bi ^((~Bo)& Bu ); - Ago0 = Bo ^((~Bu)& Ba ); - Agu0 = Bu ^((~Ba)& Be ); - - Bi = ROL32((Aga1^Da0), 1); - Bo = ROL32((Age1^De0), 22); - Bu = ROL32((Agi1^Di0), 30); - Ba = ROL32((Ago1^Do1), 14); - Be = ROL32((Agu1^Du1), 10); - Aga1 = Ba ^((~Be)& Bi ); - Age1 = Be ^((~Bi)& Bo ); - Agi1 = Bi ^((~Bo)& Bu ); - Ago1 = Bo ^((~Bu)& Ba ); - Agu1 = Bu ^((~Ba)& Be ); - - Bu = ROL32((Aka0^Da0), 9); - Ba = ROL32((Ake0^De1), 1); - Be = ROL32((Aki0^Di0), 3); - Bi = ROL32((Ako0^Do1), 13); - Bo = ROL32((Aku0^Du0), 4); - Aka0 = Ba ^((~Be)& Bi ); - Ake0 = Be ^((~Bi)& Bo ); - Aki0 = Bi ^((~Bo)& Bu ); - Ako0 = Bo ^((~Bu)& Ba ); - Aku0 = Bu ^((~Ba)& Be ); - - Bu = ROL32((Aka1^Da1), 9); - Ba = (Ake1^De0); - Be = ROL32((Aki1^Di1), 3); - Bi = ROL32((Ako1^Do0), 12); - Bo = ROL32((Aku1^Du1), 4); - Aka1 = Ba ^((~Be)& Bi ); - Ake1 = Be ^((~Bi)& Bo ); - Aki1 = Bi ^((~Bo)& Bu ); - Ako1 = Bo ^((~Bu)& Ba ); - Aku1 = Bu ^((~Ba)& Be ); - - Be = ROL32((Ama0^Da0), 18); - Bi = ROL32((Ame0^De0), 5); - Bo = ROL32((Ami0^Di1), 8); - Bu = ROL32((Amo0^Do0), 28); - Ba = ROL32((Amu0^Du1), 14); - Ama0 = Ba ^((~Be)& Bi ); - Ame0 = Be ^((~Bi)& Bo ); - Ami0 = Bi ^((~Bo)& Bu ); - Amo0 = Bo ^((~Bu)& Ba ); - Amu0 = Bu ^((~Ba)& Be ); - - Be = ROL32((Ama1^Da1), 18); - Bi = ROL32((Ame1^De1), 5); - Bo = ROL32((Ami1^Di0), 7); - Bu = ROL32((Amo1^Do1), 28); - Ba = ROL32((Amu1^Du0), 13); - Ama1 = Ba ^((~Be)& Bi ); - Ame1 = Be ^((~Bi)& Bo ); - Ami1 = Bi ^((~Bo)& Bu ); - Amo1 = Bo ^((~Bu)& Ba ); - Amu1 = Bu ^((~Ba)& Be ); - - Bo = ROL32((Asa0^Da1), 21); - Bu = ROL32((Ase0^De0), 1); - Ba = ROL32((Asi0^Di0), 31); - Be = ROL32((Aso0^Do1), 28); - Bi = ROL32((Asu0^Du1), 20); - Asa0 = Ba ^((~Be)& Bi ); - Ase0 = Be ^((~Bi)& Bo ); - Asi0 = Bi ^((~Bo)& Bu ); - Aso0 = Bo ^((~Bu)& Ba ); - Asu0 = Bu ^((~Ba)& Be ); - - Bo = ROL32((Asa1^Da0), 20); - Bu = ROL32((Ase1^De1), 1); - Ba = ROL32((Asi1^Di1), 31); - Be = ROL32((Aso1^Do0), 27); - Bi = ROL32((Asu1^Du0), 19); - Asa1 = Ba ^((~Be)& Bi ); - Ase1 = Be ^((~Bi)& Bo ); - Asi1 = Bi ^((~Bo)& Bu ); - Aso1 = Bo ^((~Bu)& Ba ); - Asu1 = Bu ^((~Ba)& Be ); - } - while ( *pRoundConstants != 0xFF ); - - #undef Aba0 - #undef Aba1 - #undef Abe0 - #undef Abe1 - #undef Abi0 - #undef Abi1 - #undef Abo0 - #undef Abo1 - #undef Abu0 - #undef Abu1 - #undef Aga0 - #undef Aga1 - #undef Age0 - #undef Age1 - #undef Agi0 - #undef Agi1 - #undef Ago0 - #undef Ago1 - #undef Agu0 - #undef Agu1 - #undef Aka0 - #undef Aka1 - #undef Ake0 - #undef Ake1 - #undef Aki0 - #undef Aki1 - #undef Ako0 - #undef Ako1 - #undef Aku0 - #undef Aku1 - #undef Ama0 - #undef Ama1 - #undef Ame0 - #undef Ame1 - #undef Ami0 - #undef Ami1 - #undef Amo0 - #undef Amo1 - #undef Amu0 - #undef Amu1 - #undef Asa0 - #undef Asa1 - #undef Ase0 - #undef Ase1 - #undef Asi0 - #undef Asi1 - #undef Aso0 - #undef Aso1 - #undef Asu0 - #undef Asu1 - } -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_Permute_12rounds(void *state) -{ - KeccakP1600_Permute_Nrounds(state, 12); -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_Permute_24rounds(void *state) -{ - KeccakP1600_Permute_Nrounds(state, 24); -} diff --git a/Modules/_sha3/kcp/KeccakP-1600-opt64-config.h b/Modules/_sha3/kcp/KeccakP-1600-opt64-config.h deleted file mode 100644 index 9501c64b186aa..0000000000000 --- a/Modules/_sha3/kcp/KeccakP-1600-opt64-config.h +++ /dev/null @@ -1,3 +0,0 @@ -#define KeccakP1600_implementation_config "lane complementing, all rounds unrolled" -#define KeccakP1600_fullUnrolling -#define KeccakP1600_useLaneComplementing diff --git a/Modules/_sha3/kcp/KeccakP-1600-opt64.c b/Modules/_sha3/kcp/KeccakP-1600-opt64.c deleted file mode 100644 index c90010dd9256c..0000000000000 --- a/Modules/_sha3/kcp/KeccakP-1600-opt64.c +++ /dev/null @@ -1,474 +0,0 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Micha?l Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#include -#include -/* #include "brg_endian.h" */ -#include "KeccakP-1600-opt64-config.h" - -#if NOT_PYTHON -typedef unsigned char UINT8; -/* typedef unsigned long long int UINT64; */ -#endif - -#if defined(KeccakP1600_useLaneComplementing) -#define UseBebigokimisa -#endif - -#if defined(_MSC_VER) -#define ROL64(a, offset) _rotl64(a, offset) -#elif defined(KeccakP1600_useSHLD) - #define ROL64(x,N) ({ \ - register UINT64 __out; \ - register UINT64 __in = x; \ - __asm__ ("shld %2,%0,%0" : "=r"(__out) : "0"(__in), "i"(N)); \ - __out; \ - }) -#else -#define ROL64(a, offset) ((((UINT64)a) << offset) ^ (((UINT64)a) >> (64-offset))) -#endif - -#include "KeccakP-1600-64.macros" -#ifdef KeccakP1600_fullUnrolling -#define FullUnrolling -#else -#define Unrolling KeccakP1600_unrolling -#endif -#include "KeccakP-1600-unrolling.macros" -#include "SnP-Relaned.h" - -static const UINT64 KeccakF1600RoundConstants[24] = { - 0x0000000000000001ULL, - 0x0000000000008082ULL, - 0x800000000000808aULL, - 0x8000000080008000ULL, - 0x000000000000808bULL, - 0x0000000080000001ULL, - 0x8000000080008081ULL, - 0x8000000000008009ULL, - 0x000000000000008aULL, - 0x0000000000000088ULL, - 0x0000000080008009ULL, - 0x000000008000000aULL, - 0x000000008000808bULL, - 0x800000000000008bULL, - 0x8000000000008089ULL, - 0x8000000000008003ULL, - 0x8000000000008002ULL, - 0x8000000000000080ULL, - 0x000000000000800aULL, - 0x800000008000000aULL, - 0x8000000080008081ULL, - 0x8000000000008080ULL, - 0x0000000080000001ULL, - 0x8000000080008008ULL }; - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_Initialize(void *state) -{ - memset(state, 0, 200); -#ifdef KeccakP1600_useLaneComplementing - ((UINT64*)state)[ 1] = ~(UINT64)0; - ((UINT64*)state)[ 2] = ~(UINT64)0; - ((UINT64*)state)[ 8] = ~(UINT64)0; - ((UINT64*)state)[12] = ~(UINT64)0; - ((UINT64*)state)[17] = ~(UINT64)0; - ((UINT64*)state)[20] = ~(UINT64)0; -#endif -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_AddBytesInLane(void *state, unsigned int lanePosition, const unsigned char *data, unsigned int offset, unsigned int length) -{ -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - UINT64 lane; - if (length == 0) - return; - if (length == 1) - lane = data[0]; - else { - lane = 0; - memcpy(&lane, data, length); - } - lane <<= offset*8; -#else - UINT64 lane = 0; - unsigned int i; - for(i=0; i>= offset*8; - for(i=0; i>= 8; - } -#endif -} - -/* ---------------------------------------------------------------- */ - -#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN) -void fromWordToBytes(UINT8 *bytes, const UINT64 word) -{ - unsigned int i; - - for(i=0; i<(64/8); i++) - bytes[i] = (word >> (8*i)) & 0xFF; -} -#endif - -void KeccakP1600_ExtractLanes(const void *state, unsigned char *data, unsigned int laneCount) -{ -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - memcpy(data, state, laneCount*8); -#else - unsigned int i; - - for(i=0; i 1) { - ((UINT64*)data)[ 1] = ~((UINT64*)data)[ 1]; - if (laneCount > 2) { - ((UINT64*)data)[ 2] = ~((UINT64*)data)[ 2]; - if (laneCount > 8) { - ((UINT64*)data)[ 8] = ~((UINT64*)data)[ 8]; - if (laneCount > 12) { - ((UINT64*)data)[12] = ~((UINT64*)data)[12]; - if (laneCount > 17) { - ((UINT64*)data)[17] = ~((UINT64*)data)[17]; - if (laneCount > 20) { - ((UINT64*)data)[20] = ~((UINT64*)data)[20]; - } - } - } - } - } - } -#endif -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length) -{ - SnP_ExtractBytes(state, data, offset, length, KeccakP1600_ExtractLanes, KeccakP1600_ExtractBytesInLane, 8); -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_ExtractAndAddBytesInLane(const void *state, unsigned int lanePosition, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) -{ - UINT64 lane = ((UINT64*)state)[lanePosition]; -#ifdef KeccakP1600_useLaneComplementing - if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20)) - lane = ~lane; -#endif -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - { - unsigned int i; - UINT64 lane1[1]; - lane1[0] = lane; - for(i=0; i>= offset*8; - for(i=0; i>= 8; - } -#endif -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_ExtractAndAddLanes(const void *state, const unsigned char *input, unsigned char *output, unsigned int laneCount) -{ - unsigned int i; -#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN) - unsigned char temp[8]; - unsigned int j; -#endif - - for(i=0; i 1) { - ((UINT64*)output)[ 1] = ~((UINT64*)output)[ 1]; - if (laneCount > 2) { - ((UINT64*)output)[ 2] = ~((UINT64*)output)[ 2]; - if (laneCount > 8) { - ((UINT64*)output)[ 8] = ~((UINT64*)output)[ 8]; - if (laneCount > 12) { - ((UINT64*)output)[12] = ~((UINT64*)output)[12]; - if (laneCount > 17) { - ((UINT64*)output)[17] = ~((UINT64*)output)[17]; - if (laneCount > 20) { - ((UINT64*)output)[20] = ~((UINT64*)output)[20]; - } - } - } - } - } - } -#endif -} - -/* ---------------------------------------------------------------- */ - -void KeccakP1600_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) -{ - SnP_ExtractAndAddBytes(state, input, output, offset, length, KeccakP1600_ExtractAndAddLanes, KeccakP1600_ExtractAndAddBytesInLane, 8); -} - -/* ---------------------------------------------------------------- */ - -size_t KeccakF1600_FastLoop_Absorb(void *state, unsigned int laneCount, const unsigned char *data, size_t dataByteLen) -{ - size_t originalDataByteLen = dataByteLen; - declareABCDE - #ifndef KeccakP1600_fullUnrolling - unsigned int i; - #endif - UINT64 *stateAsLanes = (UINT64*)state; - UINT64 *inDataAsLanes = (UINT64*)data; - - copyFromState(A, stateAsLanes) - while(dataByteLen >= laneCount*8) { - addInput(A, inDataAsLanes, laneCount) - rounds24 - inDataAsLanes += laneCount; - dataByteLen -= laneCount*8; - } - copyToState(stateAsLanes, A) - return originalDataByteLen - dataByteLen; -} diff --git a/Modules/_sha3/kcp/KeccakP-1600-unrolling.macros b/Modules/_sha3/kcp/KeccakP-1600-unrolling.macros deleted file mode 100644 index 405ce29724ced..0000000000000 --- a/Modules/_sha3/kcp/KeccakP-1600-unrolling.macros +++ /dev/null @@ -1,185 +0,0 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Micha?l Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#if (defined(FullUnrolling)) -#define rounds24 \ - prepareTheta \ - thetaRhoPiChiIotaPrepareTheta( 0, A, E) \ - thetaRhoPiChiIotaPrepareTheta( 1, E, A) \ - thetaRhoPiChiIotaPrepareTheta( 2, A, E) \ - thetaRhoPiChiIotaPrepareTheta( 3, E, A) \ - thetaRhoPiChiIotaPrepareTheta( 4, A, E) \ - thetaRhoPiChiIotaPrepareTheta( 5, E, A) \ - thetaRhoPiChiIotaPrepareTheta( 6, A, E) \ - thetaRhoPiChiIotaPrepareTheta( 7, E, A) \ - thetaRhoPiChiIotaPrepareTheta( 8, A, E) \ - thetaRhoPiChiIotaPrepareTheta( 9, E, A) \ - thetaRhoPiChiIotaPrepareTheta(10, A, E) \ - thetaRhoPiChiIotaPrepareTheta(11, E, A) \ - thetaRhoPiChiIotaPrepareTheta(12, A, E) \ - thetaRhoPiChiIotaPrepareTheta(13, E, A) \ - thetaRhoPiChiIotaPrepareTheta(14, A, E) \ - thetaRhoPiChiIotaPrepareTheta(15, E, A) \ - thetaRhoPiChiIotaPrepareTheta(16, A, E) \ - thetaRhoPiChiIotaPrepareTheta(17, E, A) \ - thetaRhoPiChiIotaPrepareTheta(18, A, E) \ - thetaRhoPiChiIotaPrepareTheta(19, E, A) \ - thetaRhoPiChiIotaPrepareTheta(20, A, E) \ - thetaRhoPiChiIotaPrepareTheta(21, E, A) \ - thetaRhoPiChiIotaPrepareTheta(22, A, E) \ - thetaRhoPiChiIota(23, E, A) \ - -#define rounds12 \ - prepareTheta \ - thetaRhoPiChiIotaPrepareTheta(12, A, E) \ - thetaRhoPiChiIotaPrepareTheta(13, E, A) \ - thetaRhoPiChiIotaPrepareTheta(14, A, E) \ - thetaRhoPiChiIotaPrepareTheta(15, E, A) \ - thetaRhoPiChiIotaPrepareTheta(16, A, E) \ - thetaRhoPiChiIotaPrepareTheta(17, E, A) \ - thetaRhoPiChiIotaPrepareTheta(18, A, E) \ - thetaRhoPiChiIotaPrepareTheta(19, E, A) \ - thetaRhoPiChiIotaPrepareTheta(20, A, E) \ - thetaRhoPiChiIotaPrepareTheta(21, E, A) \ - thetaRhoPiChiIotaPrepareTheta(22, A, E) \ - thetaRhoPiChiIota(23, E, A) \ - -#elif (Unrolling == 12) -#define rounds24 \ - prepareTheta \ - for(i=0; i<24; i+=12) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+ 1, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+ 2, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+ 3, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+ 4, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+ 5, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+ 6, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+ 7, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+ 8, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+ 9, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+10, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+11, E, A) \ - } \ - -#define rounds12 \ - prepareTheta \ - thetaRhoPiChiIotaPrepareTheta(12, A, E) \ - thetaRhoPiChiIotaPrepareTheta(13, E, A) \ - thetaRhoPiChiIotaPrepareTheta(14, A, E) \ - thetaRhoPiChiIotaPrepareTheta(15, E, A) \ - thetaRhoPiChiIotaPrepareTheta(16, A, E) \ - thetaRhoPiChiIotaPrepareTheta(17, E, A) \ - thetaRhoPiChiIotaPrepareTheta(18, A, E) \ - thetaRhoPiChiIotaPrepareTheta(19, E, A) \ - thetaRhoPiChiIotaPrepareTheta(20, A, E) \ - thetaRhoPiChiIotaPrepareTheta(21, E, A) \ - thetaRhoPiChiIotaPrepareTheta(22, A, E) \ - thetaRhoPiChiIota(23, E, A) \ - -#elif (Unrolling == 6) -#define rounds24 \ - prepareTheta \ - for(i=0; i<24; i+=6) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+4, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+5, E, A) \ - } \ - -#define rounds12 \ - prepareTheta \ - for(i=12; i<24; i+=6) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+4, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+5, E, A) \ - } \ - -#elif (Unrolling == 4) -#define rounds24 \ - prepareTheta \ - for(i=0; i<24; i+=4) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ - } \ - -#define rounds12 \ - prepareTheta \ - for(i=12; i<24; i+=4) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ - } \ - -#elif (Unrolling == 3) -#define rounds24 \ - prepareTheta \ - for(i=0; i<24; i+=3) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ - copyStateVariables(A, E) \ - } \ - -#define rounds12 \ - prepareTheta \ - for(i=12; i<24; i+=3) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ - copyStateVariables(A, E) \ - } \ - -#elif (Unrolling == 2) -#define rounds24 \ - prepareTheta \ - for(i=0; i<24; i+=2) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - } \ - -#define rounds12 \ - prepareTheta \ - for(i=12; i<24; i+=2) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - } \ - -#elif (Unrolling == 1) -#define rounds24 \ - prepareTheta \ - for(i=0; i<24; i++) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - copyStateVariables(A, E) \ - } \ - -#define rounds12 \ - prepareTheta \ - for(i=12; i<24; i++) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - copyStateVariables(A, E) \ - } \ - -#else -#error "Unrolling is not correctly specified!" -#endif diff --git a/Modules/_sha3/kcp/KeccakSponge.c b/Modules/_sha3/kcp/KeccakSponge.c deleted file mode 100644 index afdb73172f347..0000000000000 --- a/Modules/_sha3/kcp/KeccakSponge.c +++ /dev/null @@ -1,92 +0,0 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Micha?l Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#include "KeccakSponge.h" - -#ifdef KeccakReference - #include "displayIntermediateValues.h" -#endif - -#ifndef KeccakP200_excluded - #include "KeccakP-200-SnP.h" - - #define prefix KeccakWidth200 - #define SnP KeccakP200 - #define SnP_width 200 - #define SnP_Permute KeccakP200_Permute_18rounds - #if defined(KeccakF200_FastLoop_supported) - #define SnP_FastLoop_Absorb KeccakF200_FastLoop_Absorb - #endif - #include "KeccakSponge.inc" - #undef prefix - #undef SnP - #undef SnP_width - #undef SnP_Permute - #undef SnP_FastLoop_Absorb -#endif - -#ifndef KeccakP400_excluded - #include "KeccakP-400-SnP.h" - - #define prefix KeccakWidth400 - #define SnP KeccakP400 - #define SnP_width 400 - #define SnP_Permute KeccakP400_Permute_20rounds - #if defined(KeccakF400_FastLoop_supported) - #define SnP_FastLoop_Absorb KeccakF400_FastLoop_Absorb - #endif - #include "KeccakSponge.inc" - #undef prefix - #undef SnP - #undef SnP_width - #undef SnP_Permute - #undef SnP_FastLoop_Absorb -#endif - -#ifndef KeccakP800_excluded - #include "KeccakP-800-SnP.h" - - #define prefix KeccakWidth800 - #define SnP KeccakP800 - #define SnP_width 800 - #define SnP_Permute KeccakP800_Permute_22rounds - #if defined(KeccakF800_FastLoop_supported) - #define SnP_FastLoop_Absorb KeccakF800_FastLoop_Absorb - #endif - #include "KeccakSponge.inc" - #undef prefix - #undef SnP - #undef SnP_width - #undef SnP_Permute - #undef SnP_FastLoop_Absorb -#endif - -#ifndef KeccakP1600_excluded - #include "KeccakP-1600-SnP.h" - - #define prefix KeccakWidth1600 - #define SnP KeccakP1600 - #define SnP_width 1600 - #define SnP_Permute KeccakP1600_Permute_24rounds - #if defined(KeccakF1600_FastLoop_supported) - #define SnP_FastLoop_Absorb KeccakF1600_FastLoop_Absorb - #endif - #include "KeccakSponge.inc" - #undef prefix - #undef SnP - #undef SnP_width - #undef SnP_Permute - #undef SnP_FastLoop_Absorb -#endif diff --git a/Modules/_sha3/kcp/KeccakSponge.h b/Modules/_sha3/kcp/KeccakSponge.h deleted file mode 100644 index 0f4badcac059e..0000000000000 --- a/Modules/_sha3/kcp/KeccakSponge.h +++ /dev/null @@ -1,172 +0,0 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Micha?l Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#ifndef _KeccakSponge_h_ -#define _KeccakSponge_h_ - -/** General information - * - * The following type and functions are not actually implemented. Their - * documentation is generic, with the prefix Prefix replaced by - * - KeccakWidth200 for a sponge function based on Keccak-f[200] - * - KeccakWidth400 for a sponge function based on Keccak-f[400] - * - KeccakWidth800 for a sponge function based on Keccak-f[800] - * - KeccakWidth1600 for a sponge function based on Keccak-f[1600] - * - * In all these functions, the rate and capacity must sum to the width of the - * chosen permutation. For instance, to use the sponge function - * Keccak[r=1344, c=256], one must use KeccakWidth1600_Sponge() or a combination - * of KeccakWidth1600_SpongeInitialize(), KeccakWidth1600_SpongeAbsorb(), - * KeccakWidth1600_SpongeAbsorbLastFewBits() and - * KeccakWidth1600_SpongeSqueeze(). - * - * The Prefix_SpongeInstance contains the sponge instance attributes for use - * with the Prefix_Sponge* functions. - * It gathers the state processed by the permutation as well as the rate, - * the position of input/output bytes in the state and the phase - * (absorbing or squeezing). - */ - -#ifdef DontReallyInclude_DocumentationOnly -/** Function to evaluate the sponge function Keccak[r, c] in a single call. - * @param rate The value of the rate r. - * @param capacity The value of the capacity c. - * @param input Pointer to the input message (before the suffix). - * @param inputByteLen The length of the input message in bytes. - * @param suffix Byte containing from 0 to 7 suffix bits - * that must be absorbed after @a input. - * These n bits must be in the least significant bit positions. - * These bits must be delimited with a bit 1 at position n - * (counting from 0=LSB to 7=MSB) and followed by bits 0 - * from position n+1 to position 7. - * Some examples: - * - If no bits are to be absorbed, then @a suffix must be 0x01. - * - If the 2-bit sequence 0,0 is to be absorbed, @a suffix must be 0x04. - * - If the 5-bit sequence 0,1,0,0,1 is to be absorbed, @a suffix must be 0x32. - * - If the 7-bit sequence 1,1,0,1,0,0,0 is to be absorbed, @a suffix must be 0x8B. - * . - * @param output Pointer to the output buffer. - * @param outputByteLen The desired number of output bytes. - * @pre One must have r+c equal to the supported width of this implementation - * and the rate a multiple of 8 bits (one byte) in this implementation. - * @pre @a suffix ? 0x00 - * @return Zero if successful, 1 otherwise. - */ -int Prefix_Sponge(unsigned int rate, unsigned int capacity, const unsigned char *input, size_t inputByteLen, unsigned char suffix, unsigned char *output, size_t outputByteLen); - -/** - * Function to initialize the state of the Keccak[r, c] sponge function. - * The phase of the sponge function is set to absorbing. - * @param spongeInstance Pointer to the sponge instance to be initialized. - * @param rate The value of the rate r. - * @param capacity The value of the capacity c. - * @pre One must have r+c equal to the supported width of this implementation - * and the rate a multiple of 8 bits (one byte) in this implementation. - * @return Zero if successful, 1 otherwise. - */ -int Prefix_SpongeInitialize(Prefix_SpongeInstance *spongeInstance, unsigned int rate, unsigned int capacity); - -/** - * Function to give input data bytes for the sponge function to absorb. - * @param spongeInstance Pointer to the sponge instance initialized by Prefix_SpongeInitialize(). - * @param data Pointer to the input data. - * @param dataByteLen The number of input bytes provided in the input data. - * @pre The sponge function must be in the absorbing phase, - * i.e., Prefix_SpongeSqueeze() or Prefix_SpongeAbsorbLastFewBits() - * must not have been called before. - * @return Zero if successful, 1 otherwise. - */ -int Prefix_SpongeAbsorb(Prefix_SpongeInstance *spongeInstance, const unsigned char *data, size_t dataByteLen); - -/** - * Function to give input data bits for the sponge function to absorb - * and then to switch to the squeezing phase. - * @param spongeInstance Pointer to the sponge instance initialized by Prefix_SpongeInitialize(). - * @param delimitedData Byte containing from 0 to 7 trailing bits - * that must be absorbed. - * These n bits must be in the least significant bit positions. - * These bits must be delimited with a bit 1 at position n - * (counting from 0=LSB to 7=MSB) and followed by bits 0 - * from position n+1 to position 7. - * Some examples: - * - If no bits are to be absorbed, then @a delimitedData must be 0x01. - * - If the 2-bit sequence 0,0 is to be absorbed, @a delimitedData must be 0x04. - * - If the 5-bit sequence 0,1,0,0,1 is to be absorbed, @a delimitedData must be 0x32. - * - If the 7-bit sequence 1,1,0,1,0,0,0 is to be absorbed, @a delimitedData must be 0x8B. - * . - * @pre The sponge function must be in the absorbing phase, - * i.e., Prefix_SpongeSqueeze() or Prefix_SpongeAbsorbLastFewBits() - * must not have been called before. - * @pre @a delimitedData ? 0x00 - * @return Zero if successful, 1 otherwise. - */ -int Prefix_SpongeAbsorbLastFewBits(Prefix_SpongeInstance *spongeInstance, unsigned char delimitedData); - -/** - * Function to squeeze output data from the sponge function. - * If the sponge function was in the absorbing phase, this function - * switches it to the squeezing phase - * as if Prefix_SpongeAbsorbLastFewBits(spongeInstance, 0x01) was called. - * @param spongeInstance Pointer to the sponge instance initialized by Prefix_SpongeInitialize(). - * @param data Pointer to the buffer where to store the output data. - * @param dataByteLen The number of output bytes desired. - * @return Zero if successful, 1 otherwise. - */ -int Prefix_SpongeSqueeze(Prefix_SpongeInstance *spongeInstance, unsigned char *data, size_t dataByteLen); -#endif - -#include -#include "align.h" - -#define KCP_DeclareSpongeStructure(prefix, size, alignment) \ - ALIGN(alignment) typedef struct prefix##_SpongeInstanceStruct { \ - unsigned char state[size]; \ - unsigned int rate; \ - unsigned int byteIOIndex; \ - int squeezing; \ - } prefix##_SpongeInstance; - -#define KCP_DeclareSpongeFunctions(prefix) \ - int prefix##_Sponge(unsigned int rate, unsigned int capacity, const unsigned char *input, size_t inputByteLen, unsigned char suffix, unsigned char *output, size_t outputByteLen); \ - int prefix##_SpongeInitialize(prefix##_SpongeInstance *spongeInstance, unsigned int rate, unsigned int capacity); \ - int prefix##_SpongeAbsorb(prefix##_SpongeInstance *spongeInstance, const unsigned char *data, size_t dataByteLen); \ - int prefix##_SpongeAbsorbLastFewBits(prefix##_SpongeInstance *spongeInstance, unsigned char delimitedData); \ - int prefix##_SpongeSqueeze(prefix##_SpongeInstance *spongeInstance, unsigned char *data, size_t dataByteLen); - -#ifndef KeccakP200_excluded - #include "KeccakP-200-SnP.h" - KCP_DeclareSpongeStructure(KeccakWidth200, KeccakP200_stateSizeInBytes, KeccakP200_stateAlignment) - KCP_DeclareSpongeFunctions(KeccakWidth200) -#endif - -#ifndef KeccakP400_excluded - #include "KeccakP-400-SnP.h" - KCP_DeclareSpongeStructure(KeccakWidth400, KeccakP400_stateSizeInBytes, KeccakP400_stateAlignment) - KCP_DeclareSpongeFunctions(KeccakWidth400) -#endif - -#ifndef KeccakP800_excluded - #include "KeccakP-800-SnP.h" - KCP_DeclareSpongeStructure(KeccakWidth800, KeccakP800_stateSizeInBytes, KeccakP800_stateAlignment) - KCP_DeclareSpongeFunctions(KeccakWidth800) -#endif - -#ifndef KeccakP1600_excluded - #include "KeccakP-1600-SnP.h" - KCP_DeclareSpongeStructure(KeccakWidth1600, KeccakP1600_stateSizeInBytes, KeccakP1600_stateAlignment) - KCP_DeclareSpongeFunctions(KeccakWidth1600) -#endif - -#endif diff --git a/Modules/_sha3/kcp/KeccakSponge.inc b/Modules/_sha3/kcp/KeccakSponge.inc deleted file mode 100644 index e10739deafa83..0000000000000 --- a/Modules/_sha3/kcp/KeccakSponge.inc +++ /dev/null @@ -1,332 +0,0 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Micha?l Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#define JOIN0(a, b) a ## b -#define JOIN(a, b) JOIN0(a, b) - -#define Sponge JOIN(prefix, _Sponge) -#define SpongeInstance JOIN(prefix, _SpongeInstance) -#define SpongeInitialize JOIN(prefix, _SpongeInitialize) -#define SpongeAbsorb JOIN(prefix, _SpongeAbsorb) -#define SpongeAbsorbLastFewBits JOIN(prefix, _SpongeAbsorbLastFewBits) -#define SpongeSqueeze JOIN(prefix, _SpongeSqueeze) - -#define SnP_stateSizeInBytes JOIN(SnP, _stateSizeInBytes) -#define SnP_stateAlignment JOIN(SnP, _stateAlignment) -#define SnP_StaticInitialize JOIN(SnP, _StaticInitialize) -#define SnP_Initialize JOIN(SnP, _Initialize) -#define SnP_AddByte JOIN(SnP, _AddByte) -#define SnP_AddBytes JOIN(SnP, _AddBytes) -#define SnP_ExtractBytes JOIN(SnP, _ExtractBytes) - -int Sponge(unsigned int rate, unsigned int capacity, const unsigned char *input, size_t inputByteLen, unsigned char suffix, unsigned char *output, size_t outputByteLen) -{ - ALIGN(SnP_stateAlignment) unsigned char state[SnP_stateSizeInBytes]; - unsigned int partialBlock; - const unsigned char *curInput = input; - unsigned char *curOutput = output; - unsigned int rateInBytes = rate/8; - - if (rate+capacity != SnP_width) - return 1; - if ((rate <= 0) || (rate > SnP_width) || ((rate % 8) != 0)) - return 1; - if (suffix == 0) - return 1; - - /* Initialize the state */ - - SnP_StaticInitialize(); - SnP_Initialize(state); - - /* First, absorb whole blocks */ - -#ifdef SnP_FastLoop_Absorb - if (((rateInBytes % (SnP_width/200)) == 0) && (inputByteLen >= rateInBytes)) { - /* fast lane: whole lane rate */ - - size_t j; - j = SnP_FastLoop_Absorb(state, rateInBytes/(SnP_width/200), curInput, inputByteLen); - curInput += j; - inputByteLen -= j; - } -#endif - while(inputByteLen >= (size_t)rateInBytes) { - #ifdef KeccakReference - displayBytes(1, "Block to be absorbed", curInput, rateInBytes); - #endif - SnP_AddBytes(state, curInput, 0, rateInBytes); - SnP_Permute(state); - curInput += rateInBytes; - inputByteLen -= rateInBytes; - } - - /* Then, absorb what remains */ - - partialBlock = (unsigned int)inputByteLen; - #ifdef KeccakReference - displayBytes(1, "Block to be absorbed (part)", curInput, partialBlock); - #endif - SnP_AddBytes(state, curInput, 0, partialBlock); - - /* Finally, absorb the suffix */ - - #ifdef KeccakReference - { - unsigned char delimitedData1[1]; - delimitedData1[0] = suffix; - displayBytes(1, "Block to be absorbed (last few bits + first bit of padding)", delimitedData1, 1); - } - #endif - /* Last few bits, whose delimiter coincides with first bit of padding */ - - SnP_AddByte(state, suffix, partialBlock); - /* If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding */ - - if ((suffix >= 0x80) && (partialBlock == (rateInBytes-1))) - SnP_Permute(state); - /* Second bit of padding */ - - SnP_AddByte(state, 0x80, rateInBytes-1); - #ifdef KeccakReference - { - unsigned char block[SnP_width/8]; - memset(block, 0, SnP_width/8); - block[rateInBytes-1] = 0x80; - displayBytes(1, "Second bit of padding", block, rateInBytes); - } - #endif - SnP_Permute(state); - #ifdef KeccakReference - displayText(1, "--- Switching to squeezing phase ---"); - #endif - - /* First, output whole blocks */ - - while(outputByteLen > (size_t)rateInBytes) { - SnP_ExtractBytes(state, curOutput, 0, rateInBytes); - SnP_Permute(state); - #ifdef KeccakReference - displayBytes(1, "Squeezed block", curOutput, rateInBytes); - #endif - curOutput += rateInBytes; - outputByteLen -= rateInBytes; - } - - /* Finally, output what remains */ - - partialBlock = (unsigned int)outputByteLen; - SnP_ExtractBytes(state, curOutput, 0, partialBlock); - #ifdef KeccakReference - displayBytes(1, "Squeezed block (part)", curOutput, partialBlock); - #endif - - return 0; -} - -/* ---------------------------------------------------------------- */ -/* ---------------------------------------------------------------- */ -/* ---------------------------------------------------------------- */ - -int SpongeInitialize(SpongeInstance *instance, unsigned int rate, unsigned int capacity) -{ - if (rate+capacity != SnP_width) - return 1; - if ((rate <= 0) || (rate > SnP_width) || ((rate % 8) != 0)) - return 1; - SnP_StaticInitialize(); - SnP_Initialize(instance->state); - instance->rate = rate; - instance->byteIOIndex = 0; - instance->squeezing = 0; - - return 0; -} - -/* ---------------------------------------------------------------- */ - -int SpongeAbsorb(SpongeInstance *instance, const unsigned char *data, size_t dataByteLen) -{ - size_t i, j; - unsigned int partialBlock; - const unsigned char *curData; - unsigned int rateInBytes = instance->rate/8; - - if (instance->squeezing) - return 1; /* Too late for additional input */ - - - i = 0; - curData = data; - while(i < dataByteLen) { - if ((instance->byteIOIndex == 0) && (dataByteLen >= (i + rateInBytes))) { -#ifdef SnP_FastLoop_Absorb - /* processing full blocks first */ - - if ((rateInBytes % (SnP_width/200)) == 0) { - /* fast lane: whole lane rate */ - - j = SnP_FastLoop_Absorb(instance->state, rateInBytes/(SnP_width/200), curData, dataByteLen - i); - i += j; - curData += j; - } - else { -#endif - for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) { - #ifdef KeccakReference - displayBytes(1, "Block to be absorbed", curData, rateInBytes); - #endif - SnP_AddBytes(instance->state, curData, 0, rateInBytes); - SnP_Permute(instance->state); - curData+=rateInBytes; - } - i = dataByteLen - j; -#ifdef SnP_FastLoop_Absorb - } -#endif - } - else { - /* normal lane: using the message queue */ - - partialBlock = (unsigned int)(dataByteLen - i); - if (partialBlock+instance->byteIOIndex > rateInBytes) - partialBlock = rateInBytes-instance->byteIOIndex; - #ifdef KeccakReference - displayBytes(1, "Block to be absorbed (part)", curData, partialBlock); - #endif - i += partialBlock; - - SnP_AddBytes(instance->state, curData, instance->byteIOIndex, partialBlock); - curData += partialBlock; - instance->byteIOIndex += partialBlock; - if (instance->byteIOIndex == rateInBytes) { - SnP_Permute(instance->state); - instance->byteIOIndex = 0; - } - } - } - return 0; -} - -/* ---------------------------------------------------------------- */ - -int SpongeAbsorbLastFewBits(SpongeInstance *instance, unsigned char delimitedData) -{ - unsigned int rateInBytes = instance->rate/8; - - if (delimitedData == 0) - return 1; - if (instance->squeezing) - return 1; /* Too late for additional input */ - - - #ifdef KeccakReference - { - unsigned char delimitedData1[1]; - delimitedData1[0] = delimitedData; - displayBytes(1, "Block to be absorbed (last few bits + first bit of padding)", delimitedData1, 1); - } - #endif - /* Last few bits, whose delimiter coincides with first bit of padding */ - - SnP_AddByte(instance->state, delimitedData, instance->byteIOIndex); - /* If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding */ - - if ((delimitedData >= 0x80) && (instance->byteIOIndex == (rateInBytes-1))) - SnP_Permute(instance->state); - /* Second bit of padding */ - - SnP_AddByte(instance->state, 0x80, rateInBytes-1); - #ifdef KeccakReference - { - unsigned char block[SnP_width/8]; - memset(block, 0, SnP_width/8); - block[rateInBytes-1] = 0x80; - displayBytes(1, "Second bit of padding", block, rateInBytes); - } - #endif - SnP_Permute(instance->state); - instance->byteIOIndex = 0; - instance->squeezing = 1; - #ifdef KeccakReference - displayText(1, "--- Switching to squeezing phase ---"); - #endif - return 0; -} - -/* ---------------------------------------------------------------- */ - -int SpongeSqueeze(SpongeInstance *instance, unsigned char *data, size_t dataByteLen) -{ - size_t i, j; - unsigned int partialBlock; - unsigned int rateInBytes = instance->rate/8; - unsigned char *curData; - - if (!instance->squeezing) - SpongeAbsorbLastFewBits(instance, 0x01); - - i = 0; - curData = data; - while(i < dataByteLen) { - if ((instance->byteIOIndex == rateInBytes) && (dataByteLen >= (i + rateInBytes))) { - for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) { - SnP_Permute(instance->state); - SnP_ExtractBytes(instance->state, curData, 0, rateInBytes); - #ifdef KeccakReference - displayBytes(1, "Squeezed block", curData, rateInBytes); - #endif - curData+=rateInBytes; - } - i = dataByteLen - j; - } - else { - /* normal lane: using the message queue */ - - if (instance->byteIOIndex == rateInBytes) { - SnP_Permute(instance->state); - instance->byteIOIndex = 0; - } - partialBlock = (unsigned int)(dataByteLen - i); - if (partialBlock+instance->byteIOIndex > rateInBytes) - partialBlock = rateInBytes-instance->byteIOIndex; - i += partialBlock; - - SnP_ExtractBytes(instance->state, curData, instance->byteIOIndex, partialBlock); - #ifdef KeccakReference - displayBytes(1, "Squeezed block (part)", curData, partialBlock); - #endif - curData += partialBlock; - instance->byteIOIndex += partialBlock; - } - } - return 0; -} - -/* ---------------------------------------------------------------- */ - -#undef Sponge -#undef SpongeInstance -#undef SpongeInitialize -#undef SpongeAbsorb -#undef SpongeAbsorbLastFewBits -#undef SpongeSqueeze -#undef SnP_stateSizeInBytes -#undef SnP_stateAlignment -#undef SnP_StaticInitialize -#undef SnP_Initialize -#undef SnP_AddByte -#undef SnP_AddBytes -#undef SnP_ExtractBytes diff --git a/Modules/_sha3/kcp/PlSnP-Fallback.inc b/Modules/_sha3/kcp/PlSnP-Fallback.inc deleted file mode 100644 index 3a9119ab4b6aa..0000000000000 --- a/Modules/_sha3/kcp/PlSnP-Fallback.inc +++ /dev/null @@ -1,257 +0,0 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Micha?l Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -/* expect PlSnP_baseParallelism, PlSnP_targetParallelism */ - -/* expect SnP_stateSizeInBytes, SnP_stateAlignment */ - -/* expect prefix */ - -/* expect SnP_* */ - - -#define JOIN0(a, b) a ## b -#define JOIN(a, b) JOIN0(a, b) - -#define PlSnP_StaticInitialize JOIN(prefix, _StaticInitialize) -#define PlSnP_InitializeAll JOIN(prefix, _InitializeAll) -#define PlSnP_AddByte JOIN(prefix, _AddByte) -#define PlSnP_AddBytes JOIN(prefix, _AddBytes) -#define PlSnP_AddLanesAll JOIN(prefix, _AddLanesAll) -#define PlSnP_OverwriteBytes JOIN(prefix, _OverwriteBytes) -#define PlSnP_OverwriteLanesAll JOIN(prefix, _OverwriteLanesAll) -#define PlSnP_OverwriteWithZeroes JOIN(prefix, _OverwriteWithZeroes) -#define PlSnP_ExtractBytes JOIN(prefix, _ExtractBytes) -#define PlSnP_ExtractLanesAll JOIN(prefix, _ExtractLanesAll) -#define PlSnP_ExtractAndAddBytes JOIN(prefix, _ExtractAndAddBytes) -#define PlSnP_ExtractAndAddLanesAll JOIN(prefix, _ExtractAndAddLanesAll) - -#if (PlSnP_baseParallelism == 1) - #define SnP_stateSizeInBytes JOIN(SnP, _stateSizeInBytes) - #define SnP_stateAlignment JOIN(SnP, _stateAlignment) -#else - #define SnP_stateSizeInBytes JOIN(SnP, _statesSizeInBytes) - #define SnP_stateAlignment JOIN(SnP, _statesAlignment) -#endif -#define PlSnP_factor ((PlSnP_targetParallelism)/(PlSnP_baseParallelism)) -#define SnP_stateOffset (((SnP_stateSizeInBytes+(SnP_stateAlignment-1))/SnP_stateAlignment)*SnP_stateAlignment) -#define stateWithIndex(i) ((unsigned char *)states+((i)*SnP_stateOffset)) - -#define SnP_StaticInitialize JOIN(SnP, _StaticInitialize) -#define SnP_Initialize JOIN(SnP, _Initialize) -#define SnP_InitializeAll JOIN(SnP, _InitializeAll) -#define SnP_AddByte JOIN(SnP, _AddByte) -#define SnP_AddBytes JOIN(SnP, _AddBytes) -#define SnP_AddLanesAll JOIN(SnP, _AddLanesAll) -#define SnP_OverwriteBytes JOIN(SnP, _OverwriteBytes) -#define SnP_OverwriteLanesAll JOIN(SnP, _OverwriteLanesAll) -#define SnP_OverwriteWithZeroes JOIN(SnP, _OverwriteWithZeroes) -#define SnP_ExtractBytes JOIN(SnP, _ExtractBytes) -#define SnP_ExtractLanesAll JOIN(SnP, _ExtractLanesAll) -#define SnP_ExtractAndAddBytes JOIN(SnP, _ExtractAndAddBytes) -#define SnP_ExtractAndAddLanesAll JOIN(SnP, _ExtractAndAddLanesAll) - -void PlSnP_StaticInitialize( void ) -{ - SnP_StaticInitialize(); -} - -void PlSnP_InitializeAll(void *states) -{ - unsigned int i; - - for(i=0; i 0) { \ - unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ - if (_bytesInLane > _sizeLeft) \ - _bytesInLane = _sizeLeft; \ - SnP_AddBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \ - _sizeLeft -= _bytesInLane; \ - _lanePosition++; \ - _offsetInLane = 0; \ - _curData += _bytesInLane; \ - } \ - } \ - } - -#define SnP_OverwriteBytes(state, data, offset, length, SnP_OverwriteLanes, SnP_OverwriteBytesInLane, SnP_laneLengthInBytes) \ - { \ - if ((offset) == 0) { \ - SnP_OverwriteLanes(state, data, (length)/SnP_laneLengthInBytes); \ - SnP_OverwriteBytesInLane(state, \ - (length)/SnP_laneLengthInBytes, \ - (data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ - 0, \ - (length)%SnP_laneLengthInBytes); \ - } \ - else { \ - unsigned int _sizeLeft = (length); \ - unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \ - unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \ - const unsigned char *_curData = (data); \ - while(_sizeLeft > 0) { \ - unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ - if (_bytesInLane > _sizeLeft) \ - _bytesInLane = _sizeLeft; \ - SnP_OverwriteBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \ - _sizeLeft -= _bytesInLane; \ - _lanePosition++; \ - _offsetInLane = 0; \ - _curData += _bytesInLane; \ - } \ - } \ - } - -#define SnP_ExtractBytes(state, data, offset, length, SnP_ExtractLanes, SnP_ExtractBytesInLane, SnP_laneLengthInBytes) \ - { \ - if ((offset) == 0) { \ - SnP_ExtractLanes(state, data, (length)/SnP_laneLengthInBytes); \ - SnP_ExtractBytesInLane(state, \ - (length)/SnP_laneLengthInBytes, \ - (data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ - 0, \ - (length)%SnP_laneLengthInBytes); \ - } \ - else { \ - unsigned int _sizeLeft = (length); \ - unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \ - unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \ - unsigned char *_curData = (data); \ - while(_sizeLeft > 0) { \ - unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ - if (_bytesInLane > _sizeLeft) \ - _bytesInLane = _sizeLeft; \ - SnP_ExtractBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \ - _sizeLeft -= _bytesInLane; \ - _lanePosition++; \ - _offsetInLane = 0; \ - _curData += _bytesInLane; \ - } \ - } \ - } - -#define SnP_ExtractAndAddBytes(state, input, output, offset, length, SnP_ExtractAndAddLanes, SnP_ExtractAndAddBytesInLane, SnP_laneLengthInBytes) \ - { \ - if ((offset) == 0) { \ - SnP_ExtractAndAddLanes(state, input, output, (length)/SnP_laneLengthInBytes); \ - SnP_ExtractAndAddBytesInLane(state, \ - (length)/SnP_laneLengthInBytes, \ - (input)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ - (output)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ - 0, \ - (length)%SnP_laneLengthInBytes); \ - } \ - else { \ - unsigned int _sizeLeft = (length); \ - unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \ - unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \ - const unsigned char *_curInput = (input); \ - unsigned char *_curOutput = (output); \ - while(_sizeLeft > 0) { \ - unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ - if (_bytesInLane > _sizeLeft) \ - _bytesInLane = _sizeLeft; \ - SnP_ExtractAndAddBytesInLane(state, _lanePosition, _curInput, _curOutput, _offsetInLane, _bytesInLane); \ - _sizeLeft -= _bytesInLane; \ - _lanePosition++; \ - _offsetInLane = 0; \ - _curInput += _bytesInLane; \ - _curOutput += _bytesInLane; \ - } \ - } \ - } - -#endif diff --git a/Modules/_sha3/kcp/align.h b/Modules/_sha3/kcp/align.h deleted file mode 100644 index 6650fe8c3cf0e..0000000000000 --- a/Modules/_sha3/kcp/align.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Micha?l Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#ifndef _align_h_ -#define _align_h_ - -/* on Mac OS-X and possibly others, ALIGN(x) is defined in param.h, and -Werror chokes on the redef. */ - -#ifdef ALIGN -#undef ALIGN -#endif - -#if defined(__GNUC__) -#define ALIGN(x) __attribute__ ((aligned(x))) -#elif defined(_MSC_VER) -#define ALIGN(x) __declspec(align(x)) -#elif defined(__ARMCC_VERSION) -#define ALIGN(x) __align(x) -#else -#define ALIGN(x) -#endif - -#endif diff --git a/Modules/_sha3/sha3.c b/Modules/_sha3/sha3.c new file mode 100644 index 0000000000000..e2d3fd7b8ad85 --- /dev/null +++ b/Modules/_sha3/sha3.c @@ -0,0 +1,193 @@ +// sha3.c +// 19-Nov-11 Markku-Juhani O. Saarinen + +// Revised 07-Aug-15 to match with official release of FIPS PUB 202 "SHA3" +// Revised 03-Sep-15 for portability + OpenSSL - style API + +#include "sha3.h" + +// update the state with given number of rounds + +static void sha3_keccakf(uint64_t st[25]) +{ + // constants + const uint64_t keccakf_rndc[24] = { + 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, + 0x8000000080008000, 0x000000000000808b, 0x0000000080000001, + 0x8000000080008081, 0x8000000000008009, 0x000000000000008a, + 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, + 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, + 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, + 0x000000000000800a, 0x800000008000000a, 0x8000000080008081, + 0x8000000000008080, 0x0000000080000001, 0x8000000080008008 + }; + const int keccakf_rotc[24] = { + 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, + 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 + }; + const int keccakf_piln[24] = { + 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, + 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 + }; + + // variables + int i, j, r; + uint64_t t, bc[5]; + +#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ + uint8_t *v; + + // endianess conversion. this is redundant on little-endian targets + for (i = 0; i < 25; i++) { + v = (uint8_t *) &st[i]; + st[i] = ((uint64_t) v[0]) | (((uint64_t) v[1]) << 8) | + (((uint64_t) v[2]) << 16) | (((uint64_t) v[3]) << 24) | + (((uint64_t) v[4]) << 32) | (((uint64_t) v[5]) << 40) | + (((uint64_t) v[6]) << 48) | (((uint64_t) v[7]) << 56); + } +#endif + + // actual iteration + for (r = 0; r < KECCAKF_ROUNDS; r++) { + + // Theta + for (i = 0; i < 5; i++) + bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20]; + + for (i = 0; i < 5; i++) { + t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1); + for (j = 0; j < 25; j += 5) + st[j + i] ^= t; + } + + // Rho Pi + t = st[1]; + for (i = 0; i < 24; i++) { + j = keccakf_piln[i]; + bc[0] = st[j]; + st[j] = ROTL64(t, keccakf_rotc[i]); + t = bc[0]; + } + + // Chi + for (j = 0; j < 25; j += 5) { + for (i = 0; i < 5; i++) + bc[i] = st[j + i]; + for (i = 0; i < 5; i++) + st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5]; + } + + // Iota + st[0] ^= keccakf_rndc[r]; + } + +#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ + // endianess conversion. this is redundant on little-endian targets + for (i = 0; i < 25; i++) { + v = (uint8_t *) &st[i]; + t = st[i]; + v[0] = t & 0xFF; + v[1] = (t >> 8) & 0xFF; + v[2] = (t >> 16) & 0xFF; + v[3] = (t >> 24) & 0xFF; + v[4] = (t >> 32) & 0xFF; + v[5] = (t >> 40) & 0xFF; + v[6] = (t >> 48) & 0xFF; + v[7] = (t >> 56) & 0xFF; + } +#endif +} + +// Initialize the context for SHA3 + +static int sha3_init(sha3_ctx_t *c, int mdlen) +{ + int i; + + for (i = 0; i < 25; i++) + c->st.q[i] = 0; + c->mdlen = mdlen; + c->rsiz = 200 - 2 * mdlen; + c->pt = 0; + + return 1; +} + +// update state with more data + +static int sha3_update(sha3_ctx_t *c, const void *data, size_t len) +{ + size_t i; + int j; + + j = c->pt; + for (i = 0; i < len; i++) { + c->st.b[j++] ^= ((const uint8_t *) data)[i]; + if (j >= c->rsiz) { + sha3_keccakf(c->st.q); + j = 0; + } + } + c->pt = j; + + return 1; +} + +// finalize and output a hash + +static int sha3_final(void *md, sha3_ctx_t *c) +{ + int i; + + c->st.b[c->pt] ^= 0x06; + c->st.b[c->rsiz - 1] ^= 0x80; + sha3_keccakf(c->st.q); + + for (i = 0; i < c->mdlen; i++) { + ((uint8_t *) md)[i] = c->st.b[i]; + } + + return 1; +} + +#if 0 +// compute a SHA-3 hash (md) of given byte length from "in" + +void *sha3(const void *in, size_t inlen, void *md, int mdlen) +{ + sha3_ctx_t sha3; + + sha3_init(&sha3, mdlen); + sha3_update(&sha3, in, inlen); + sha3_final(md, &sha3); + + return md; +} +#endif + +// SHAKE128 and SHAKE256 extensible-output functionality + +static void shake_xof(sha3_ctx_t *c) +{ + c->st.b[c->pt] ^= 0x1F; + c->st.b[c->rsiz - 1] ^= 0x80; + sha3_keccakf(c->st.q); + c->pt = 0; +} + +static void shake_out(sha3_ctx_t *c, void *out, size_t len) +{ + size_t i; + int j; + + j = c->pt; + for (i = 0; i < len; i++) { + if (j >= c->rsiz) { + sha3_keccakf(c->st.q); + j = 0; + } + ((uint8_t *) out)[i] = c->st.b[j++]; + } + c->pt = j; +} + diff --git a/Modules/_sha3/sha3.h b/Modules/_sha3/sha3.h new file mode 100644 index 0000000000000..f973d6733ec2c --- /dev/null +++ b/Modules/_sha3/sha3.h @@ -0,0 +1,49 @@ +// sha3.h +// 19-Nov-11 Markku-Juhani O. Saarinen + +#ifndef SHA3_H +#define SHA3_H + +#include +#include + +#ifndef KECCAKF_ROUNDS +#define KECCAKF_ROUNDS 24 +#endif + +#ifndef ROTL64 +#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) +#endif + +// state context +typedef struct { + union { // state: + uint8_t b[200]; // 8-bit bytes + uint64_t q[25]; // 64-bit words + } st; + int pt, rsiz, mdlen; // these don't overflow +} sha3_ctx_t; + +// Compression function. +static void sha3_keccakf(uint64_t st[25]); + +// OpenSSL - like interfece +static int sha3_init(sha3_ctx_t *c, int mdlen); // mdlen = hash output in bytes +static int sha3_update(sha3_ctx_t *c, const void *data, size_t len); +static int sha3_final(void *md, sha3_ctx_t *c); // digest goes to md + +// compute a sha3 hash (md) of given byte length from "in" +#if 0 +static void *sha3(const void *in, size_t inlen, void *md, int mdlen); +#endif + +// SHAKE128 and SHAKE256 extensible-output functions +#define shake128_init(c) sha3_init(c, 16) +#define shake256_init(c) sha3_init(c, 32) +#define shake_update sha3_update + +static void shake_xof(sha3_ctx_t *c); +static void shake_out(sha3_ctx_t *c, void *out, size_t len); + +#endif + diff --git a/Modules/_sha3/sha3module.c b/Modules/_sha3/sha3module.c index bffd177c0e753..bd1dd596bdda6 100644 --- a/Modules/_sha3/sha3module.c +++ b/Modules/_sha3/sha3module.c @@ -10,7 +10,7 @@ * Trevor Perrin (trevp at trevp.net) * Gregory P. Smith (greg at krypto.org) * - * Copyright (C) 2012-2016 Christian Heimes (christian at python.org) + * Copyright (C) 2012-2022 Christian Heimes (christian at python.org) * Licensed to PSF under a Contributor Agreement. * */ @@ -23,127 +23,27 @@ #include "pycore_strhex.h" // _Py_strhex() #include "../hashlib.h" -/* ************************************************************************** - * SHA-3 (Keccak) and SHAKE - * - * The code is based on KeccakCodePackage from 2016-04-23 - * commit 647f93079afc4ada3d23737477a6e52511ca41fd - * - * The reference implementation is altered in this points: - * - C++ comments are converted to ANSI C comments. - * - all function names are mangled - * - typedef for UINT64 is commented out. - * - brg_endian.h is removed - * - * *************************************************************************/ - -#ifdef __sparc - /* opt64 uses un-aligned memory access that causes a BUS error with msg - * 'invalid address alignment' on SPARC. */ - #define KeccakOpt 32 -#elif PY_BIG_ENDIAN - /* opt64 is not yet supported on big endian platforms */ - #define KeccakOpt 32 -#elif SIZEOF_VOID_P == 8 - /* opt64 works only on little-endian 64bit platforms with unsigned int64 */ - #define KeccakOpt 64 -#else - /* opt32 is used for the remaining 32 and 64bit platforms */ - #define KeccakOpt 32 -#endif - -#if KeccakOpt == 64 - /* 64bit platforms with unsigned int64 */ - typedef uint64_t UINT64; - typedef unsigned char UINT8; -#endif -// kcp/KeccakP-1600-opt64.c doesn't need to define UINT8 -#define NOT_PYTHON 0 - -/* replacement for brg_endian.h */ -#define IS_LITTLE_ENDIAN 1234 -#define IS_BIG_ENDIAN 4321 -#if PY_LITTLE_ENDIAN -#define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -#endif -#if PY_BIG_ENDIAN -#define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -#endif - -/* Prevent bus errors on platforms requiring aligned accesses such ARM. */ -#if defined(HAVE_ALIGNED_REQUIRED) && !defined(NO_MISALIGNED_ACCESSES) -#define NO_MISALIGNED_ACCESSES -#endif - -/* mangle names */ -#define KeccakF1600_FastLoop_Absorb _PySHA3_KeccakF1600_FastLoop_Absorb -#define Keccak_HashFinal _PySHA3_Keccak_HashFinal -#define Keccak_HashInitialize _PySHA3_Keccak_HashInitialize -#define Keccak_HashSqueeze _PySHA3_Keccak_HashSqueeze -#define Keccak_HashUpdate _PySHA3_Keccak_HashUpdate -#define KeccakP1600_AddBytes _PySHA3_KeccakP1600_AddBytes -#define KeccakP1600_AddBytesInLane _PySHA3_KeccakP1600_AddBytesInLane -#define KeccakP1600_AddLanes _PySHA3_KeccakP1600_AddLanes -#define KeccakP1600_ExtractAndAddBytes _PySHA3_KeccakP1600_ExtractAndAddBytes -#define KeccakP1600_ExtractAndAddBytesInLane _PySHA3_KeccakP1600_ExtractAndAddBytesInLane -#define KeccakP1600_ExtractAndAddLanes _PySHA3_KeccakP1600_ExtractAndAddLanes -#define KeccakP1600_ExtractBytes _PySHA3_KeccakP1600_ExtractBytes -#define KeccakP1600_ExtractBytesInLane _PySHA3_KeccakP1600_ExtractBytesInLane -#define KeccakP1600_ExtractLanes _PySHA3_KeccakP1600_ExtractLanes -#define KeccakP1600_Initialize _PySHA3_KeccakP1600_Initialize -#define KeccakP1600_OverwriteBytes _PySHA3_KeccakP1600_OverwriteBytes -#define KeccakP1600_OverwriteBytesInLane _PySHA3_KeccakP1600_OverwriteBytesInLane -#define KeccakP1600_OverwriteLanes _PySHA3_KeccakP1600_OverwriteLanes -#define KeccakP1600_OverwriteWithZeroes _PySHA3_KeccakP1600_OverwriteWithZeroes -#define KeccakP1600_Permute_12rounds _PySHA3_KeccakP1600_Permute_12rounds -#define KeccakP1600_Permute_24rounds _PySHA3_KeccakP1600_Permute_24rounds -#define KeccakWidth1600_Sponge _PySHA3_KeccakWidth1600_Sponge -#define KeccakWidth1600_SpongeAbsorb _PySHA3_KeccakWidth1600_SpongeAbsorb -#define KeccakWidth1600_SpongeAbsorbLastFewBits _PySHA3_KeccakWidth1600_SpongeAbsorbLastFewBits -#define KeccakWidth1600_SpongeInitialize _PySHA3_KeccakWidth1600_SpongeInitialize -#define KeccakWidth1600_SpongeSqueeze _PySHA3_KeccakWidth1600_SpongeSqueeze -#if KeccakOpt == 32 -#define KeccakP1600_AddByte _PySHA3_KeccakP1600_AddByte -#define KeccakP1600_Permute_Nrounds _PySHA3_KeccakP1600_Permute_Nrounds -#define KeccakP1600_SetBytesInLaneToZero _PySHA3_KeccakP1600_SetBytesInLaneToZero -#endif - -/* we are only interested in KeccakP1600 */ -#define KeccakP200_excluded 1 -#define KeccakP400_excluded 1 -#define KeccakP800_excluded 1 - -/* inline all Keccak dependencies */ -#include "kcp/KeccakHash.h" -#include "kcp/KeccakSponge.h" -#include "kcp/KeccakHash.c" -#include "kcp/KeccakSponge.c" -#if KeccakOpt == 64 - #include "kcp/KeccakP-1600-opt64.c" -#elif KeccakOpt == 32 - #include "kcp/KeccakP-1600-inplace32BI.c" -#endif +#include "sha3.c" #define SHA3_MAX_DIGESTSIZE 64 /* 64 Bytes (512 Bits) for 224 to 512 */ -#define SHA3_LANESIZE (20 * 8) /* ExtractLane needs max uint64_t[20] extra. */ -#define SHA3_state Keccak_HashInstance -#define SHA3_init Keccak_HashInitialize -#define SHA3_process Keccak_HashUpdate -#define SHA3_done Keccak_HashFinal -#define SHA3_squeeze Keccak_HashSqueeze +#define SHA3_LANESIZE 0 +#define SHA3_state sha3_ctx_t +#define SHA3_init sha3_init +#define SHA3_process sha3_update +#define SHA3_done(state, digest) sha3_final(digest, state) +#define SHA3_squeeze(state, out, len) shake_xof(state), shake_out(state, out, len) #define SHA3_copystate(dest, src) memcpy(&(dest), &(src), sizeof(SHA3_state)) +// no optimization +#define KeccakOpt 0 + +typedef enum { SUCCESS = 1, FAIL = 0, BAD_HASHLEN = 2 } HashReturn; + typedef struct { PyTypeObject *sha3_224_type; PyTypeObject *sha3_256_type; PyTypeObject *sha3_384_type; PyTypeObject *sha3_512_type; -#ifdef PY_WITH_KECCAK - PyTypeObject *keccak_224_type; - PyTypeObject *keccak_256_type; - PyTypeObject *keccak_384_type; - PyTypeObject *keccak_512_type; -#endif PyTypeObject *shake_128_type; PyTypeObject *shake_256_type; } SHA3State; @@ -215,27 +115,17 @@ py_sha3_new_impl(PyTypeObject *type, PyObject *data, int usedforsecurity) assert(state != NULL); if (type == state->sha3_224_type) { - res = Keccak_HashInitialize_SHA3_224(&self->hash_state); + res = sha3_init(&self->hash_state, 28); } else if (type == state->sha3_256_type) { - res = Keccak_HashInitialize_SHA3_256(&self->hash_state); + res = sha3_init(&self->hash_state, 32); } else if (type == state->sha3_384_type) { - res = Keccak_HashInitialize_SHA3_384(&self->hash_state); + res = sha3_init(&self->hash_state, 48); } else if (type == state->sha3_512_type) { - res = Keccak_HashInitialize_SHA3_512(&self->hash_state); -#ifdef PY_WITH_KECCAK - } else if (type == state->keccak_224_type) { - res = Keccak_HashInitialize(&self->hash_state, 1152, 448, 224, 0x01); - } else if (type == state->keccak_256_type) { - res = Keccak_HashInitialize(&self->hash_state, 1088, 512, 256, 0x01); - } else if (type == state->keccak_384_type) { - res = Keccak_HashInitialize(&self->hash_state, 832, 768, 384, 0x01); - } else if (type == state->keccak_512_type) { - res = Keccak_HashInitialize(&self->hash_state, 576, 1024, 512, 0x01); -#endif + res = sha3_init(&self->hash_state, 64); } else if (type == state->shake_128_type) { - res = Keccak_HashInitialize_SHAKE128(&self->hash_state); + res = sha3_init(&self->hash_state, 16); } else if (type == state->shake_256_type) { - res = Keccak_HashInitialize_SHAKE256(&self->hash_state); + res = sha3_init(&self->hash_state, 32); } else { PyErr_BadInternalCall(); goto error; @@ -254,11 +144,11 @@ py_sha3_new_impl(PyTypeObject *type, PyObject *data, int usedforsecurity) * thus it's safe to release the GIL without locking the object. */ Py_BEGIN_ALLOW_THREADS - res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); + res = SHA3_process(&self->hash_state, buf.buf, buf.len); Py_END_ALLOW_THREADS } else { - res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); + res = SHA3_process(&self->hash_state, buf.buf, buf.len); } if (res != SUCCESS) { PyErr_SetString(PyExc_RuntimeError, @@ -344,7 +234,7 @@ _sha3_sha3_224_digest_impl(SHA3object *self) return NULL; } return PyBytes_FromStringAndSize((const char *)digest, - self->hash_state.fixedOutputLength / 8); + self->hash_state.mdlen); } @@ -372,7 +262,7 @@ _sha3_sha3_224_hexdigest_impl(SHA3object *self) return NULL; } return _Py_strhex((const char *)digest, - self->hash_state.fixedOutputLength / 8); + self->hash_state.mdlen); } @@ -405,12 +295,12 @@ _sha3_sha3_224_update(SHA3object *self, PyObject *data) if (self->lock) { Py_BEGIN_ALLOW_THREADS PyThread_acquire_lock(self->lock, 1); - res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); + res = SHA3_process(&self->hash_state, buf.buf, buf.len); PyThread_release_lock(self->lock); Py_END_ALLOW_THREADS } else { - res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); + res = SHA3_process(&self->hash_state, buf.buf, buf.len); } if (res != SUCCESS) { @@ -437,8 +327,8 @@ static PyMethodDef SHA3_methods[] = { static PyObject * SHA3_get_block_size(SHA3object *self, void *closure) { - int rate = self->hash_state.sponge.rate; - return PyLong_FromLong(rate / 8); + int rate = self->hash_state.rsiz; + return PyLong_FromLong(rate); } @@ -458,16 +348,6 @@ SHA3_get_name(SHA3object *self, void *closure) return PyUnicode_FromString("sha3_384"); } else if (type == state->sha3_512_type) { return PyUnicode_FromString("sha3_512"); -#ifdef PY_WITH_KECCAK - } else if (type == state->keccak_224_type) { - return PyUnicode_FromString("keccak_224"); - } else if (type == state->keccak_256_type) { - return PyUnicode_FromString("keccak_256"); - } else if (type == state->keccak_384_type) { - return PyUnicode_FromString("keccak_384"); - } else if (type == state->keccak_512_type) { - return PyUnicode_FromString("keccak_512"); -#endif } else if (type == state->shake_128_type) { return PyUnicode_FromString("shake_128"); } else if (type == state->shake_256_type) { @@ -482,14 +362,14 @@ SHA3_get_name(SHA3object *self, void *closure) static PyObject * SHA3_get_digest_size(SHA3object *self, void *closure) { - return PyLong_FromLong(self->hash_state.fixedOutputLength / 8); + return PyLong_FromLong(self->hash_state.mdlen); } static PyObject * SHA3_get_capacity_bits(SHA3object *self, void *closure) { - int capacity = 1600 - self->hash_state.sponge.rate; + int capacity = 1600 - self->hash_state.rsiz * 8; return PyLong_FromLong(capacity); } @@ -497,16 +377,14 @@ SHA3_get_capacity_bits(SHA3object *self, void *closure) static PyObject * SHA3_get_rate_bits(SHA3object *self, void *closure) { - unsigned int rate = self->hash_state.sponge.rate; + unsigned int rate = self->hash_state.rsiz * 8; return PyLong_FromLong(rate); } static PyObject * SHA3_get_suffix(SHA3object *self, void *closure) { - unsigned char suffix[2]; - suffix[0] = self->hash_state.delimitedSuffix; - suffix[1] = 0; + unsigned char suffix[2] = {0x06, 0}; return PyBytes_FromStringAndSize((const char *)suffix, 1); } @@ -520,12 +398,12 @@ static PyGetSetDef SHA3_getseters[] = { {NULL} /* Sentinel */ }; -#define SHA3_TYPE_SLOTS(type_slots_obj, type_doc, type_methods) \ +#define SHA3_TYPE_SLOTS(type_slots_obj, type_doc, type_methods, type_getseters) \ static PyType_Slot type_slots_obj[] = { \ {Py_tp_dealloc, SHA3_dealloc}, \ {Py_tp_doc, (char*)type_doc}, \ {Py_tp_methods, type_methods}, \ - {Py_tp_getset, SHA3_getseters}, \ + {Py_tp_getset, type_getseters}, \ {Py_tp_new, py_sha3_new}, \ {0,0} \ } @@ -560,62 +438,23 @@ PyDoc_STRVAR(sha3_512__doc__, \n\ Return a new SHA3 hash object with a hashbit length of 64 bytes."); -#ifdef PY_WITH_KECCAK -PyDoc_STRVAR(keccak_224__doc__, -"keccak_224([data], *, usedforsecurity=True) -> Keccak object\n\ -\n\ -Return a new Keccak hash object with a hashbit length of 28 bytes."); - -PyDoc_STRVAR(keccak_256__doc__, -"keccak_256([data], *, usedforsecurity=True) -> Keccak object\n\ -\n\ -Return a new Keccak hash object with a hashbit length of 32 bytes."); - -PyDoc_STRVAR(keccak_384__doc__, -"keccak_384([data], *, usedforsecurity=True) -> Keccak object\n\ -\n\ -Return a new Keccak hash object with a hashbit length of 48 bytes."); - -PyDoc_STRVAR(keccak_512__doc__, -"keccak_512([data], *, usedforsecurity=True) -> Keccak object\n\ -\n\ -Return a new Keccak hash object with a hashbit length of 64 bytes."); - -#endif - -SHA3_TYPE_SLOTS(sha3_224_slots, sha3_224__doc__, SHA3_methods); +SHA3_TYPE_SLOTS(sha3_224_slots, sha3_224__doc__, SHA3_methods, SHA3_getseters); SHA3_TYPE_SPEC(sha3_224_spec, "sha3_224", sha3_224_slots); -SHA3_TYPE_SLOTS(sha3_256_slots, sha3_256__doc__, SHA3_methods); +SHA3_TYPE_SLOTS(sha3_256_slots, sha3_256__doc__, SHA3_methods, SHA3_getseters); SHA3_TYPE_SPEC(sha3_256_spec, "sha3_256", sha3_256_slots); -SHA3_TYPE_SLOTS(sha3_384_slots, sha3_384__doc__, SHA3_methods); +SHA3_TYPE_SLOTS(sha3_384_slots, sha3_384__doc__, SHA3_methods, SHA3_getseters); SHA3_TYPE_SPEC(sha3_384_spec, "sha3_384", sha3_384_slots); -SHA3_TYPE_SLOTS(sha3_512_slots, sha3_512__doc__, SHA3_methods); +SHA3_TYPE_SLOTS(sha3_512_slots, sha3_512__doc__, SHA3_methods, SHA3_getseters); SHA3_TYPE_SPEC(sha3_512_spec, "sha3_512", sha3_512_slots); -#ifdef PY_WITH_KECCAK -SHA3_TYPE_SLOTS(Keccak_224_slots, keccak_224__doc__, SHA3_methods); -SHA3_TYPE_SPEC(Keccak_224_spec, "keccak_224", Keccak_224_slots); - -SHA3_TYPE_SLOTS(Keccak_256_slots, keccak_256__doc__, SHA3_methods); -SHA3_TYPE_SPEC(Keccak_256_spec, "keccak_256", Keccak_256_slots); - -SHA3_TYPE_SLOTS(Keccak_384_slots, keccak_384__doc__, SHA3_methods); -SHA3_TYPE_SPEC(Keccak_384_spec, "keccak_384", Keccak_384_slots); - -SHA3_TYPE_SLOTS(Keccak_512_slots, keccak_512__doc__, SHA3_methods); -SHA3_TYPE_SPEC(Keccak_512_spec, "keccak_512", Keccak_512_slots); -#endif - - static PyObject * _SHAKE_digest(SHA3object *self, unsigned long digestlen, int hex) { unsigned char *digest = NULL; SHA3_state temp; - int res; PyObject *result = NULL; if (digestlen >= (1 << 29)) { @@ -634,23 +473,13 @@ _SHAKE_digest(SHA3object *self, unsigned long digestlen, int hex) ENTER_HASHLIB(self); SHA3_copystate(temp, self->hash_state); LEAVE_HASHLIB(self); - res = SHA3_done(&temp, NULL); - if (res != SUCCESS) { - PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 done()"); - goto error; - } - res = SHA3_squeeze(&temp, digest, digestlen * 8); - if (res != SUCCESS) { - PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 Squeeze()"); - return NULL; - } + SHA3_squeeze(&temp, digest, digestlen); if (hex) { result = _Py_strhex((const char *)digest, digestlen); } else { result = PyBytes_FromStringAndSize((const char *)digest, digestlen); } - error: if (digest != NULL) { PyMem_Free(digest); } @@ -691,6 +520,30 @@ _sha3_shake_128_hexdigest_impl(SHA3object *self, unsigned long length) return _SHAKE_digest(self, length, 1); } +static PyObject * +SHAKE_get_digest_size(SHA3object *self, void *closure) +{ + return PyLong_FromLong(0); +} + +static PyObject * +SHAKE_get_suffix(SHA3object *self, void *closure) +{ + unsigned char suffix[2] = {0x1f, 0}; + return PyBytes_FromStringAndSize((const char *)suffix, 1); +} + + +static PyGetSetDef SHAKE_getseters[] = { + {"block_size", (getter)SHA3_get_block_size, NULL, NULL, NULL}, + {"name", (getter)SHA3_get_name, NULL, NULL, NULL}, + {"digest_size", (getter)SHAKE_get_digest_size, NULL, NULL, NULL}, + {"_capacity_bits", (getter)SHA3_get_capacity_bits, NULL, NULL, NULL}, + {"_rate_bits", (getter)SHA3_get_rate_bits, NULL, NULL, NULL}, + {"_suffix", (getter)SHAKE_get_suffix, NULL, NULL, NULL}, + {NULL} /* Sentinel */ +}; + static PyMethodDef SHAKE_methods[] = { _SHA3_SHA3_224_COPY_METHODDEF @@ -710,10 +563,10 @@ PyDoc_STRVAR(shake_256__doc__, \n\ Return a new SHAKE hash object."); -SHA3_TYPE_SLOTS(SHAKE128slots, shake_128__doc__, SHAKE_methods); +SHA3_TYPE_SLOTS(SHAKE128slots, shake_128__doc__, SHAKE_methods, SHAKE_getseters); SHA3_TYPE_SPEC(SHAKE128_spec, "shake_128", SHAKE128slots); -SHA3_TYPE_SLOTS(SHAKE256slots, shake_256__doc__, SHAKE_methods); +SHA3_TYPE_SLOTS(SHAKE256slots, shake_256__doc__, SHAKE_methods, SHAKE_getseters); SHA3_TYPE_SPEC(SHAKE256_spec, "shake_256", SHAKE256slots); @@ -725,12 +578,6 @@ _sha3_traverse(PyObject *module, visitproc visit, void *arg) Py_VISIT(state->sha3_256_type); Py_VISIT(state->sha3_384_type); Py_VISIT(state->sha3_512_type); -#ifdef PY_WITH_KECCAK - Py_VISIT(state->keccak_224_type); - Py_VISIT(state->keccak_256_type); - Py_VISIT(state->keccak_384_type); - Py_VISIT(state->keccak_512_type); -#endif Py_VISIT(state->shake_128_type); Py_VISIT(state->shake_256_type); return 0; @@ -744,12 +591,6 @@ _sha3_clear(PyObject *module) Py_CLEAR(state->sha3_256_type); Py_CLEAR(state->sha3_384_type); Py_CLEAR(state->sha3_512_type); -#ifdef PY_WITH_KECCAK - Py_CLEAR(state->keccak_224_type); - Py_CLEAR(state->keccak_256_type); - Py_CLEAR(state->keccak_384_type); - Py_CLEAR(state->keccak_512_type); -#endif Py_CLEAR(state->shake_128_type); Py_CLEAR(state->shake_256_type); return 0; @@ -782,12 +623,6 @@ _sha3_exec(PyObject *m) init_sha3type(sha3_256_type, sha3_256_spec); init_sha3type(sha3_384_type, sha3_384_spec); init_sha3type(sha3_512_type, sha3_512_spec); -#ifdef PY_WITH_KECCAK - init_sha3type(keccak_224_type, Keccak_224_spec); - init_sha3type(keccak_256_type, Keccak_256_spec); - init_sha3type(keccak_384_type, Keccak_384_spec); - init_sha3type(keccak_512_type, Keccak_512_spec); -#endif init_sha3type(shake_128_type, SHAKE128_spec); init_sha3type(shake_256_type, SHAKE256_spec); #undef init_sha3type @@ -796,7 +631,7 @@ _sha3_exec(PyObject *m) return -1; } if (PyModule_AddStringConstant(m, "implementation", - KeccakP1600_implementation) < 0) { + "tiny_sha3") < 0) { return -1; } From webhook-mailer at python.org Sun Mar 27 09:49:37 2022 From: webhook-mailer at python.org (vsajip) Date: Sun, 27 Mar 2022 13:49:37 -0000 Subject: [Python-checkins] bpo-45171: Fix stacklevel handling in logging. (GH-28287) Message-ID: https://github.com/python/cpython/commit/5ca6d7469be53960843df39bb900e9c3359f127f commit: 5ca6d7469be53960843df39bb900e9c3359f127f branch: main author: Jouke Witteveen committer: vsajip date: 2022-03-27T14:49:28+01:00 summary: bpo-45171: Fix stacklevel handling in logging. (GH-28287) files: A Misc/NEWS.d/next/Library/2021-09-11-16-06-54.bpo-45171.ec597j.rst M Lib/logging/__init__.py M Lib/test/test_logging.py diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index 160b1afcee0f9..e8054fb1f72ac 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -159,8 +159,8 @@ def addLevelName(level, levelName): finally: _releaseLock() -if hasattr(sys, '_getframe'): - currentframe = lambda: sys._getframe(3) +if hasattr(sys, "_getframe"): + currentframe = lambda: sys._getframe(1) else: #pragma: no cover def currentframe(): """Return the frame object for the caller's stack frame.""" @@ -184,13 +184,18 @@ def currentframe(): _srcfile = os.path.normcase(addLevelName.__code__.co_filename) # _srcfile is only used in conjunction with sys._getframe(). -# To provide compatibility with older versions of Python, set _srcfile -# to None if _getframe() is not available; this value will prevent -# findCaller() from being called. You can also do this if you want to avoid -# the overhead of fetching caller information, even when _getframe() is -# available. -#if not hasattr(sys, '_getframe'): -# _srcfile = None +# Setting _srcfile to None will prevent findCaller() from being called. This +# way, you can avoid the overhead of fetching caller information. + +# The following is based on warnings._is_internal_frame. It makes sure that +# frames of the import mechanism are skipped when logging at module level and +# using a stacklevel value greater than one. +def _is_internal_frame(frame): + """Signal whether the frame is a CPython or logging module internal.""" + filename = os.path.normcase(frame.f_code.co_filename) + return filename == _srcfile or ( + "importlib" in filename and "_bootstrap" in filename + ) def _checkLevel(level): @@ -1558,33 +1563,31 @@ def findCaller(self, stack_info=False, stacklevel=1): f = currentframe() #On some versions of IronPython, currentframe() returns None if #IronPython isn't run with -X:Frames. - if f is not None: - f = f.f_back - orig_f = f - while f and stacklevel > 1: - f = f.f_back - stacklevel -= 1 - if not f: - f = orig_f - rv = "(unknown file)", 0, "(unknown function)", None - while hasattr(f, "f_code"): - co = f.f_code - filename = os.path.normcase(co.co_filename) - if filename == _srcfile: - f = f.f_back - continue - sinfo = None - if stack_info: - sio = io.StringIO() - sio.write('Stack (most recent call last):\n') + if f is None: + return "(unknown file)", 0, "(unknown function)", None + while stacklevel > 0: + next_f = f.f_back + if next_f is None: + ##TODO: We've got options here + ## If we want to use the last (deepest) frame: + break + ## If we want to mimic the warnings module: + #return ("sys", 1, "(unknown function)", None) + ## If we want to be pedantic: + #raise ValueError("call stack is not deep enough") + f = next_f + if not _is_internal_frame(f): + stacklevel -= 1 + co = f.f_code + sinfo = None + if stack_info: + with io.StringIO() as sio: + sio.write("Stack (most recent call last):\n") traceback.print_stack(f, file=sio) sinfo = sio.getvalue() if sinfo[-1] == '\n': sinfo = sinfo[:-1] - sio.close() - rv = (co.co_filename, f.f_lineno, co.co_name, sinfo) - break - return rv + return co.co_filename, f.f_lineno, co.co_name, sinfo def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None, sinfo=None): diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 5f72a6dd5871a..00e354147a27c 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -5050,9 +5050,10 @@ def test_find_caller_with_stack_info(self): def test_find_caller_with_stacklevel(self): the_level = 1 + trigger = self.logger.warning def innermost(): - self.logger.warning('test', stacklevel=the_level) + trigger('test', stacklevel=the_level) def inner(): innermost() @@ -5074,6 +5075,16 @@ def outer(): self.assertEqual(records[-1].funcName, 'outer') self.assertGreater(records[-1].lineno, lineno) lineno = records[-1].lineno + trigger = self.logger.warn + outer() + self.assertEqual(records[-1].funcName, 'outer') + root_logger = logging.getLogger() + root_logger.addHandler(self.recording) + trigger = logging.warning + outer() + self.assertEqual(records[-1].funcName, 'outer') + root_logger.removeHandler(self.recording) + trigger = self.logger.warning the_level += 1 outer() self.assertEqual(records[-1].funcName, 'test_find_caller_with_stacklevel') diff --git a/Misc/NEWS.d/next/Library/2021-09-11-16-06-54.bpo-45171.ec597j.rst b/Misc/NEWS.d/next/Library/2021-09-11-16-06-54.bpo-45171.ec597j.rst new file mode 100644 index 0000000000000..eaa3fb2915e52 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-09-11-16-06-54.bpo-45171.ec597j.rst @@ -0,0 +1,4 @@ +Fix handling of the ``stacklevel`` argument to logging functions in the +:mod:`logging` module so that it is consistent accross all logging functions +and, as advertised, similar to the ``stacklevel`` argument used in +:meth:`~warnings.warn`. From webhook-mailer at python.org Sun Mar 27 14:22:13 2022 From: webhook-mailer at python.org (vsajip) Date: Sun, 27 Mar 2022 18:22:13 -0000 Subject: [Python-checkins] bpo-45171: Remove tests of deprecated logger.warn(). (GH-32139) Message-ID: https://github.com/python/cpython/commit/c12ba6b2ff7908c8970b978f149d51ecd3fb195c commit: c12ba6b2ff7908c8970b978f149d51ecd3fb195c branch: main author: Jouke Witteveen committer: vsajip date: 2022-03-27T19:22:05+01:00 summary: bpo-45171: Remove tests of deprecated logger.warn(). (GH-32139) files: M Lib/logging/__init__.py M Lib/test/test_logging.py diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index e8054fb1f72ac..d6315b047334e 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -1568,7 +1568,7 @@ def findCaller(self, stack_info=False, stacklevel=1): while stacklevel > 0: next_f = f.f_back if next_f is None: - ##TODO: We've got options here + ## We've got options here. ## If we want to use the last (deepest) frame: break ## If we want to mimic the warnings module: diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 00e354147a27c..f6f5977df2a1e 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -5075,9 +5075,6 @@ def outer(): self.assertEqual(records[-1].funcName, 'outer') self.assertGreater(records[-1].lineno, lineno) lineno = records[-1].lineno - trigger = self.logger.warn - outer() - self.assertEqual(records[-1].funcName, 'outer') root_logger = logging.getLogger() root_logger.addHandler(self.recording) trigger = logging.warning From webhook-mailer at python.org Sun Mar 27 14:46:37 2022 From: webhook-mailer at python.org (gvanrossum) Date: Sun, 27 Mar 2022 18:46:37 -0000 Subject: [Python-checkins] bpo-46429: tweak deepfreeze output (#32107) Message-ID: https://github.com/python/cpython/commit/785cc6770588de087d09e89a69110af2542be208 commit: 785cc6770588de087d09e89a69110af2542be208 branch: main author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> committer: gvanrossum date: 2022-03-27T11:46:22-07:00 summary: bpo-46429: tweak deepfreeze output (#32107) files: M Tools/scripts/deepfreeze.py diff --git a/Tools/scripts/deepfreeze.py b/Tools/scripts/deepfreeze.py index 1831c15784af7..dfa4b3a8eeb01 100644 --- a/Tools/scripts/deepfreeze.py +++ b/Tools/scripts/deepfreeze.py @@ -170,6 +170,8 @@ def generate_bytes(self, name: str, b: bytes) -> str: def generate_unicode(self, name: str, s: str) -> str: if s in identifiers: return f"&_Py_ID({s})" + if re.match(r'\A[A-Za-z0-9_]+\Z', s): + name = f"const_str_{s}" kind, ascii = analyze_character_width(s) if kind == PyUnicode_1BYTE_KIND: datatype = "uint8_t" @@ -326,6 +328,10 @@ def _generate_int_for_bits(self, name: str, i: int, digit: int) -> None: def generate_int(self, name: str, i: int) -> str: if -5 <= i <= 256: return f"(PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + {i}]" + if i >= 0: + name = f"const_int_{i}" + else: + name = f"const_int_negative_{abs(i)}" if abs(i) < 2**15: self._generate_int_for_bits(name, i, 2**15) else: From webhook-mailer at python.org Sun Mar 27 15:53:33 2022 From: webhook-mailer at python.org (Fidget-Spinner) Date: Sun, 27 Mar 2022 19:53:33 -0000 Subject: [Python-checkins] bpo-47127: Specialize calls for fastcall c methods with keywords (GH-32125) Message-ID: https://github.com/python/cpython/commit/58448cbd96f77ebc6fca1f8030bedc7744eb66ef commit: 58448cbd96f77ebc6fca1f8030bedc7744eb66ef branch: main author: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> committer: Fidget-Spinner date: 2022-03-28T03:53:25+08:00 summary: bpo-47127: Specialize calls for fastcall c methods with keywords (GH-32125) * add PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS files: A Misc/NEWS.d/next/Core and Builtins/2022-03-26-12-21-53.bpo-47127.Mh86RB.rst M Include/opcode.h M Lib/opcode.py M Python/ceval.c M Python/opcode_targets.h M Python/specialize.c diff --git a/Include/opcode.h b/Include/opcode.h index dfc7b72e3cdc6..0ce7c158bbd58 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -157,32 +157,33 @@ extern "C" { #define PRECALL_BOUND_METHOD 62 #define PRECALL_BUILTIN_CLASS 63 #define PRECALL_BUILTIN_FAST_WITH_KEYWORDS 64 -#define PRECALL_NO_KW_BUILTIN_FAST 65 -#define PRECALL_NO_KW_BUILTIN_O 66 -#define PRECALL_NO_KW_ISINSTANCE 67 -#define PRECALL_NO_KW_LEN 72 -#define PRECALL_NO_KW_LIST_APPEND 73 -#define PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST 76 -#define PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS 77 -#define PRECALL_NO_KW_METHOD_DESCRIPTOR_O 78 -#define PRECALL_NO_KW_STR_1 79 -#define PRECALL_NO_KW_TUPLE_1 80 -#define PRECALL_NO_KW_TYPE_1 81 -#define PRECALL_PYFUNC 140 -#define RESUME_QUICK 141 -#define STORE_ATTR_ADAPTIVE 143 -#define STORE_ATTR_INSTANCE_VALUE 150 -#define STORE_ATTR_SLOT 153 -#define STORE_ATTR_WITH_HINT 154 -#define STORE_FAST__LOAD_FAST 158 -#define STORE_FAST__STORE_FAST 159 -#define STORE_SUBSCR_ADAPTIVE 161 -#define STORE_SUBSCR_DICT 167 -#define STORE_SUBSCR_LIST_INT 168 -#define UNPACK_SEQUENCE_ADAPTIVE 169 -#define UNPACK_SEQUENCE_LIST 170 -#define UNPACK_SEQUENCE_TUPLE 173 -#define UNPACK_SEQUENCE_TWO_TUPLE 174 +#define PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 65 +#define PRECALL_NO_KW_BUILTIN_FAST 66 +#define PRECALL_NO_KW_BUILTIN_O 67 +#define PRECALL_NO_KW_ISINSTANCE 72 +#define PRECALL_NO_KW_LEN 73 +#define PRECALL_NO_KW_LIST_APPEND 76 +#define PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST 77 +#define PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS 78 +#define PRECALL_NO_KW_METHOD_DESCRIPTOR_O 79 +#define PRECALL_NO_KW_STR_1 80 +#define PRECALL_NO_KW_TUPLE_1 81 +#define PRECALL_NO_KW_TYPE_1 140 +#define PRECALL_PYFUNC 141 +#define RESUME_QUICK 143 +#define STORE_ATTR_ADAPTIVE 150 +#define STORE_ATTR_INSTANCE_VALUE 153 +#define STORE_ATTR_SLOT 154 +#define STORE_ATTR_WITH_HINT 158 +#define STORE_FAST__LOAD_FAST 159 +#define STORE_FAST__STORE_FAST 161 +#define STORE_SUBSCR_ADAPTIVE 167 +#define STORE_SUBSCR_DICT 168 +#define STORE_SUBSCR_LIST_INT 169 +#define UNPACK_SEQUENCE_ADAPTIVE 170 +#define UNPACK_SEQUENCE_LIST 173 +#define UNPACK_SEQUENCE_TUPLE 174 +#define UNPACK_SEQUENCE_TWO_TUPLE 175 #define DO_TRACING 255 extern const uint8_t _PyOpcode_Caches[256]; @@ -347,6 +348,7 @@ const uint8_t _PyOpcode_Deopt[256] = { [PRECALL_BOUND_METHOD] = PRECALL, [PRECALL_BUILTIN_CLASS] = PRECALL, [PRECALL_BUILTIN_FAST_WITH_KEYWORDS] = PRECALL, + [PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = PRECALL, [PRECALL_NO_KW_BUILTIN_FAST] = PRECALL, [PRECALL_NO_KW_BUILTIN_O] = PRECALL, [PRECALL_NO_KW_ISINSTANCE] = PRECALL, diff --git a/Lib/opcode.py b/Lib/opcode.py index 7a52c13579af7..0b463d3f183aa 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -294,6 +294,7 @@ def jabs_op(name, op, entries=0): "PRECALL_BOUND_METHOD", "PRECALL_BUILTIN_CLASS", "PRECALL_BUILTIN_FAST_WITH_KEYWORDS", + "PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS", "PRECALL_NO_KW_BUILTIN_FAST", "PRECALL_NO_KW_BUILTIN_O", "PRECALL_NO_KW_ISINSTANCE", diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-26-12-21-53.bpo-47127.Mh86RB.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-26-12-21-53.bpo-47127.Mh86RB.rst new file mode 100644 index 0000000000000..c4ec9774429d4 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-26-12-21-53.bpo-47127.Mh86RB.rst @@ -0,0 +1 @@ +Speed up calls to c functions with keyword arguments by 25% with specialization. Patch by Kumar Aditya. diff --git a/Python/ceval.c b/Python/ceval.c index 4824b192f4e48..8b59f4233a7b2 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -5090,6 +5090,38 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int DISPATCH(); } + TARGET(PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS) { + int is_meth = is_method(stack_pointer, oparg); + int total_args = oparg + is_meth; + PyObject *callable = PEEK(total_args + 1); + DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), PRECALL); + PyMethodDef *meth = ((PyMethodDescrObject *)callable)->d_method; + DEOPT_IF(meth->ml_flags != (METH_FASTCALL|METH_KEYWORDS), PRECALL); + STAT_INC(PRECALL, hit); + SKIP_CALL(); + int nargs = total_args-1; + STACK_SHRINK(nargs); + _PyCFunctionFastWithKeywords cfunc = (_PyCFunctionFastWithKeywords)(void(*)(void))meth->ml_meth; + PyObject *self = TOP(); + PyObject *res = cfunc(self, stack_pointer, nargs - KWNAMES_LEN(), call_shape.kwnames); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + call_shape.kwnames = NULL; + + /* Free the arguments. */ + for (int i = 0; i < nargs; i++) { + Py_DECREF(stack_pointer[i]); + } + Py_DECREF(self); + STACK_SHRINK(2-is_meth); + SET_TOP(res); + Py_DECREF(callable); + if (res == NULL) { + goto error; + } + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + TARGET(PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS) { assert(call_shape.kwnames == NULL); assert(oparg == 0 || oparg == 1); diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index 2aa6471abf99a..dbcacee7e0205 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -64,23 +64,23 @@ static void *opcode_targets[256] = { &&TARGET_PRECALL_BOUND_METHOD, &&TARGET_PRECALL_BUILTIN_CLASS, &&TARGET_PRECALL_BUILTIN_FAST_WITH_KEYWORDS, + &&TARGET_PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, &&TARGET_PRECALL_NO_KW_BUILTIN_FAST, &&TARGET_PRECALL_NO_KW_BUILTIN_O, - &&TARGET_PRECALL_NO_KW_ISINSTANCE, &&TARGET_GET_ITER, &&TARGET_GET_YIELD_FROM_ITER, &&TARGET_PRINT_EXPR, &&TARGET_LOAD_BUILD_CLASS, + &&TARGET_PRECALL_NO_KW_ISINSTANCE, &&TARGET_PRECALL_NO_KW_LEN, - &&TARGET_PRECALL_NO_KW_LIST_APPEND, &&TARGET_LOAD_ASSERTION_ERROR, &&TARGET_RETURN_GENERATOR, + &&TARGET_PRECALL_NO_KW_LIST_APPEND, &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST, &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS, &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_O, &&TARGET_PRECALL_NO_KW_STR_1, &&TARGET_PRECALL_NO_KW_TUPLE_1, - &&TARGET_PRECALL_NO_KW_TYPE_1, &&TARGET_LIST_TO_TUPLE, &&TARGET_RETURN_VALUE, &&TARGET_IMPORT_STAR, @@ -139,39 +139,40 @@ static void *opcode_targets[256] = { &&TARGET_LOAD_DEREF, &&TARGET_STORE_DEREF, &&TARGET_DELETE_DEREF, + &&TARGET_PRECALL_NO_KW_TYPE_1, &&TARGET_PRECALL_PYFUNC, - &&TARGET_RESUME_QUICK, &&TARGET_CALL_FUNCTION_EX, - &&TARGET_STORE_ATTR_ADAPTIVE, + &&TARGET_RESUME_QUICK, &&TARGET_EXTENDED_ARG, &&TARGET_LIST_APPEND, &&TARGET_SET_ADD, &&TARGET_MAP_ADD, &&TARGET_LOAD_CLASSDEREF, &&TARGET_COPY_FREE_VARS, - &&TARGET_STORE_ATTR_INSTANCE_VALUE, + &&TARGET_STORE_ATTR_ADAPTIVE, &&TARGET_RESUME, &&TARGET_MATCH_CLASS, + &&TARGET_STORE_ATTR_INSTANCE_VALUE, &&TARGET_STORE_ATTR_SLOT, - &&TARGET_STORE_ATTR_WITH_HINT, &&TARGET_FORMAT_VALUE, &&TARGET_BUILD_CONST_KEY_MAP, &&TARGET_BUILD_STRING, + &&TARGET_STORE_ATTR_WITH_HINT, &&TARGET_STORE_FAST__LOAD_FAST, - &&TARGET_STORE_FAST__STORE_FAST, &&TARGET_LOAD_METHOD, - &&TARGET_STORE_SUBSCR_ADAPTIVE, + &&TARGET_STORE_FAST__STORE_FAST, &&TARGET_LIST_EXTEND, &&TARGET_SET_UPDATE, &&TARGET_DICT_MERGE, &&TARGET_DICT_UPDATE, &&TARGET_PRECALL, + &&TARGET_STORE_SUBSCR_ADAPTIVE, &&TARGET_STORE_SUBSCR_DICT, &&TARGET_STORE_SUBSCR_LIST_INT, &&TARGET_UNPACK_SEQUENCE_ADAPTIVE, - &&TARGET_UNPACK_SEQUENCE_LIST, &&TARGET_CALL, &&TARGET_KW_NAMES, + &&TARGET_UNPACK_SEQUENCE_LIST, &&TARGET_UNPACK_SEQUENCE_TUPLE, &&TARGET_UNPACK_SEQUENCE_TWO_TUPLE, &&_unknown_opcode, @@ -253,6 +254,5 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, - &&_unknown_opcode, &&TARGET_DO_TRACING }; diff --git a/Python/specialize.c b/Python/specialize.c index 720bc7f241586..5839d7629466d 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -1446,6 +1446,10 @@ specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr, _Py_SET_OPCODE(*instr, PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST); return 0; } + case METH_FASTCALL|METH_KEYWORDS: { + _Py_SET_OPCODE(*instr, PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS); + return 0; + } } SPECIALIZATION_FAIL(PRECALL, builtin_call_fail_kind(descr->d_method->ml_flags)); return -1; From webhook-mailer at python.org Sun Mar 27 16:22:32 2022 From: webhook-mailer at python.org (gpshead) Date: Sun, 27 Mar 2022 20:22:32 -0000 Subject: [Python-checkins] bpo-44493: Add missing terminated NUL in sockaddr_un's length (GH-26866) Message-ID: https://github.com/python/cpython/commit/f6b3a07b7df60dc04d0260169ffef6e9796a2124 commit: f6b3a07b7df60dc04d0260169ffef6e9796a2124 branch: main author: ty committer: gpshead date: 2022-03-27T13:22:22-07:00 summary: bpo-44493: Add missing terminated NUL in sockaddr_un's length (GH-26866) Add missing terminated NUL in sockaddr_un's length - Linux: https://man7.org/linux/man-pages/man7/unix.7.html - *BSD: SUN_LEN files: A Misc/NEWS.d/next/Library/2021-07-26-10-46-49.bpo-44493.xp3CRH.rst M Modules/socketmodule.c diff --git a/Misc/NEWS.d/next/Library/2021-07-26-10-46-49.bpo-44493.xp3CRH.rst b/Misc/NEWS.d/next/Library/2021-07-26-10-46-49.bpo-44493.xp3CRH.rst new file mode 100644 index 0000000000000..390a7222bbf55 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-07-26-10-46-49.bpo-44493.xp3CRH.rst @@ -0,0 +1,3 @@ +Add missing terminated NUL in sockaddr_un's length + +This was potentially observable when using non-abstract AF_UNIX datagram sockets to processes written in another programming language. diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 7f7af1895bd9f..c7bc10b5dbbbc 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -1689,6 +1689,8 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, "AF_UNIX path too long"); goto unix_out; } + + *len_ret = path.len + offsetof(struct sockaddr_un, sun_path); } else #endif /* linux */ @@ -1700,10 +1702,13 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, goto unix_out; } addr->sun_path[path.len] = 0; + + /* including the tailing NUL */ + *len_ret = path.len + offsetof(struct sockaddr_un, sun_path) + 1; } addr->sun_family = s->sock_family; memcpy(addr->sun_path, path.buf, path.len); - *len_ret = path.len + offsetof(struct sockaddr_un, sun_path); + retval = 1; unix_out: PyBuffer_Release(&path); From webhook-mailer at python.org Sun Mar 27 23:12:26 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Mon, 28 Mar 2022 03:12:26 -0000 Subject: [Python-checkins] ctypes docs: Fix array-length reference to "non-negative" from "positive" (GH-32097) Message-ID: https://github.com/python/cpython/commit/76f14b0463dc2c53911eaf95e85374e511ba9bcc commit: 76f14b0463dc2c53911eaf95e85374e511ba9bcc branch: main author: Yonatan Goldschmidt committer: JelleZijlstra date: 2022-03-27T20:12:21-07:00 summary: ctypes docs: Fix array-length reference to "non-negative" from "positive" (GH-32097) files: M Doc/library/ctypes.rst diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index 6e147fc66eb14..dca4c74bab771 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -2512,7 +2512,7 @@ Arrays and pointers Abstract base class for arrays. The recommended way to create concrete array types is by multiplying any - :mod:`ctypes` data type with a positive integer. Alternatively, you can subclass + :mod:`ctypes` data type with a non-negative integer. Alternatively, you can subclass this type and define :attr:`_length_` and :attr:`_type_` class variables. Array elements can be read and written using standard subscript and slice accesses; for slice reads, the resulting object is From webhook-mailer at python.org Mon Mar 28 00:32:00 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Mon, 28 Mar 2022 04:32:00 -0000 Subject: [Python-checkins] bpo-28516: document contextlib.ExitStack.__enter__ behavior (GH-31636) Message-ID: https://github.com/python/cpython/commit/86384cf83f96fcaec03e2ad6516e2e24f20d3b92 commit: 86384cf83f96fcaec03e2ad6516e2e24f20d3b92 branch: main author: vidhya <96202776+Vidhyavinu at users.noreply.github.com> committer: JelleZijlstra date: 2022-03-27T21:31:32-07:00 summary: bpo-28516: document contextlib.ExitStack.__enter__ behavior (GH-31636) The enter_context is updated with following information: 'The :meth:`__enter__` method returns the ExitStack instance, and performs no additional operations.' Co-authored-by: Jelle Zijlstra files: M Doc/library/contextlib.rst diff --git a/Doc/library/contextlib.rst b/Doc/library/contextlib.rst index bb93088b3429e..38134c1f14319 100644 --- a/Doc/library/contextlib.rst +++ b/Doc/library/contextlib.rst @@ -502,6 +502,9 @@ Functions and classes provided: # the with statement, even if attempts to open files later # in the list raise an exception + The :meth:`__enter__` method returns the :class:`ExitStack` instance, and + performs no additional operations. + Each instance maintains a stack of registered callbacks that are called in reverse order when the instance is closed (either explicitly or implicitly at the end of a :keyword:`with` statement). Note that callbacks are *not* From webhook-mailer at python.org Mon Mar 28 04:44:05 2022 From: webhook-mailer at python.org (sweeneyde) Date: Mon, 28 Mar 2022 08:44:05 -0000 Subject: [Python-checkins] bpo-47070: Add _PyBytes_Repeat() (GH-31999) Message-ID: https://github.com/python/cpython/commit/850687df47b03e98c1433e6e70e71a8921eb4454 commit: 850687df47b03e98c1433e6e70e71a8921eb4454 branch: main author: Pieter Eendebak committer: sweeneyde <36520290+sweeneyde at users.noreply.github.com> date: 2022-03-28T04:43:45-04:00 summary: bpo-47070: Add _PyBytes_Repeat() (GH-31999) Use it where appropriate: the repeat functions of `array.array`, `bytes`, `bytearray`, and `str`. files: A Misc/NEWS.d/next/Core and Builtins/2022-03-19-21-50-59.bpo-47070.wPcsQh.rst M Include/internal/pycore_bytesobject.h M Modules/arraymodule.c M Objects/bytearrayobject.c M Objects/bytesobject.c M Objects/unicodeobject.c diff --git a/Include/internal/pycore_bytesobject.h b/Include/internal/pycore_bytesobject.h index b8061607a518d..9173a4f105f80 100644 --- a/Include/internal/pycore_bytesobject.h +++ b/Include/internal/pycore_bytesobject.h @@ -33,6 +33,19 @@ _PyBytes_ReverseFind(const char *haystack, Py_ssize_t len_haystack, const char *needle, Py_ssize_t len_needle, Py_ssize_t offset); + +/** Helper function to implement the repeat and inplace repeat methods on a buffer + * + * len_dest is assumed to be an integer multiple of len_src. + * If src equals dest, then assume the operation is inplace. + * + * This method repeately doubles the number of bytes copied to reduce + * the number of invocations of memcpy. + */ +PyAPI_FUNC(void) +_PyBytes_Repeat(char* dest, Py_ssize_t len_dest, + const char* src, Py_ssize_t len_src); + #ifdef __cplusplus } #endif diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-19-21-50-59.bpo-47070.wPcsQh.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-19-21-50-59.bpo-47070.wPcsQh.rst new file mode 100644 index 0000000000000..568974f251f32 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-19-21-50-59.bpo-47070.wPcsQh.rst @@ -0,0 +1,3 @@ +Improve performance of ``array_inplace_repeat`` by reducing the number of invocations of ``memcpy``. +Refactor the ``repeat`` and inplace ``repeat`` methods of ``array``, ``bytes``, ``bytearray`` +and ``unicodeobject`` to use the common ``_PyBytes_Repeat``. diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 18991f81480d0..a04e6a4e070d9 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -10,6 +10,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" #include "pycore_moduleobject.h" // _PyModule_GetState() +#include "pycore_bytesobject.h" // _PyBytes_Repeat #include "structmember.h" // PyMemberDef #include // offsetof() #include @@ -910,34 +911,24 @@ static PyObject * array_repeat(arrayobject *a, Py_ssize_t n) { array_state *state = find_array_state_by_type(Py_TYPE(a)); - Py_ssize_t size; - arrayobject *np; - Py_ssize_t oldbytes, newbytes; + if (n < 0) n = 0; - if ((Py_SIZE(a) != 0) && (n > PY_SSIZE_T_MAX / Py_SIZE(a))) { + const Py_ssize_t array_length = Py_SIZE(a); + if ((array_length != 0) && (n > PY_SSIZE_T_MAX / array_length)) { return PyErr_NoMemory(); } - size = Py_SIZE(a) * n; - np = (arrayobject *) newarrayobject(state->ArrayType, size, a->ob_descr); + Py_ssize_t size = array_length * n; + arrayobject* np = (arrayobject *) newarrayobject(state->ArrayType, size, a->ob_descr); if (np == NULL) return NULL; if (size == 0) return (PyObject *)np; - oldbytes = Py_SIZE(a) * a->ob_descr->itemsize; - newbytes = oldbytes * n; - /* this follows the code in unicode_repeat */ - if (oldbytes == 1) { - memset(np->ob_item, a->ob_item[0], newbytes); - } else { - Py_ssize_t done = oldbytes; - memcpy(np->ob_item, a->ob_item, oldbytes); - while (done < newbytes) { - Py_ssize_t ncopy = (done <= newbytes-done) ? done : newbytes-done; - memcpy(np->ob_item+done, np->ob_item, ncopy); - done += ncopy; - } - } + + const Py_ssize_t oldbytes = array_length * a->ob_descr->itemsize; + const Py_ssize_t newbytes = oldbytes * n; + _PyBytes_Repeat(np->ob_item, newbytes, a->ob_item, oldbytes); + return (PyObject *)np; } @@ -1075,27 +1066,23 @@ array_inplace_concat(arrayobject *self, PyObject *bb) static PyObject * array_inplace_repeat(arrayobject *self, Py_ssize_t n) { - char *items, *p; - Py_ssize_t size, i; + const Py_ssize_t array_size = Py_SIZE(self); - if (Py_SIZE(self) > 0) { + if (array_size > 0 && n != 1 ) { if (n < 0) n = 0; if ((self->ob_descr->itemsize != 0) && - (Py_SIZE(self) > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) { + (array_size > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) { return PyErr_NoMemory(); } - size = Py_SIZE(self) * self->ob_descr->itemsize; + Py_ssize_t size = array_size * self->ob_descr->itemsize; if (n > 0 && size > PY_SSIZE_T_MAX / n) { return PyErr_NoMemory(); } - if (array_resize(self, n * Py_SIZE(self)) == -1) + if (array_resize(self, n * array_size) == -1) return NULL; - items = p = self->ob_item; - for (i = 1; i < n; i++) { - p += size; - memcpy(p, items, size); - } + + _PyBytes_Repeat(self->ob_item, n*size, self->ob_item, size); } Py_INCREF(self); return (PyObject *)self; diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 74267cffcc9a3..3849337fbf77f 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -4,6 +4,7 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_bytes_methods.h" +#include "pycore_bytesobject.h" #include "pycore_object.h" // _PyObject_GC_UNTRACK() #include "pycore_strhex.h" // _Py_strhex_with_sep() #include "pycore_long.h" // _PyLong_FromUnsignedChar() @@ -319,37 +320,16 @@ bytearray_iconcat(PyByteArrayObject *self, PyObject *other) static PyObject * bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count) { - PyByteArrayObject *result; - Py_ssize_t mysize; - Py_ssize_t size; - const char *buf; - if (count < 0) count = 0; - mysize = Py_SIZE(self); + const Py_ssize_t mysize = Py_SIZE(self); if (count > 0 && mysize > PY_SSIZE_T_MAX / count) return PyErr_NoMemory(); - size = mysize * count; - result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size); - buf = PyByteArray_AS_STRING(self); + Py_ssize_t size = mysize * count; + PyByteArrayObject* result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size); + const char* buf = PyByteArray_AS_STRING(self); if (result != NULL && size != 0) { - if (mysize == 1) - memset(result->ob_bytes, buf[0], size); - else { - Py_ssize_t i, j; - - i = 0; - if (i < size) { - memcpy(result->ob_bytes, buf, mysize); - i = mysize; - } - // repeatedly double the number of bytes copied - while (i < size) { - j = Py_MIN(i, size - i); - memcpy(result->ob_bytes + i, result->ob_bytes, j); - i += j; - } - } + _PyBytes_Repeat(result->ob_bytes, size, buf, mysize); } return (PyObject *)result; } @@ -357,33 +337,22 @@ bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count) static PyObject * bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count) { - Py_ssize_t mysize; - Py_ssize_t size; - char *buf; - if (count < 0) count = 0; - mysize = Py_SIZE(self); + else if (count == 1) { + Py_INCREF(self); + return (PyObject*)self; + } + + const Py_ssize_t mysize = Py_SIZE(self); if (count > 0 && mysize > PY_SSIZE_T_MAX / count) return PyErr_NoMemory(); - size = mysize * count; + const Py_ssize_t size = mysize * count; if (PyByteArray_Resize((PyObject *)self, size) < 0) return NULL; - buf = PyByteArray_AS_STRING(self); - if (mysize == 1) - memset(buf, buf[0], size); - else { - Py_ssize_t i, j; - - i = mysize; - // repeatedly double the number of bytes copied - while (i < size) { - j = Py_MIN(i, size - i); - memcpy(buf + i, buf, j); - i += j; - } - } + char* buf = PyByteArray_AS_STRING(self); + _PyBytes_Repeat(buf, size, buf, mysize); Py_INCREF(self); return (PyObject *)self; diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 56c941a44bfd5..78c42c2c54b5f 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -4,7 +4,7 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() -#include "pycore_bytesobject.h" // _PyBytes_Find() +#include "pycore_bytesobject.h" // _PyBytes_Find(), _PyBytes_Repeat() #include "pycore_bytes_methods.h" // _Py_bytes_startswith() #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_format.h" // F_LJUST @@ -1421,8 +1421,6 @@ bytes_concat(PyObject *a, PyObject *b) static PyObject * bytes_repeat(PyBytesObject *a, Py_ssize_t n) { - Py_ssize_t i; - Py_ssize_t j; Py_ssize_t size; PyBytesObject *op; size_t nbytes; @@ -1457,20 +1455,9 @@ _Py_COMP_DIAG_IGNORE_DEPR_DECLS op->ob_shash = -1; _Py_COMP_DIAG_POP op->ob_sval[size] = '\0'; - if (Py_SIZE(a) == 1 && n > 0) { - memset(op->ob_sval, a->ob_sval[0] , n); - return (PyObject *) op; - } - i = 0; - if (i < size) { - memcpy(op->ob_sval, a->ob_sval, Py_SIZE(a)); - i = Py_SIZE(a); - } - while (i < size) { - j = (i <= size-i) ? i : size-i; - memcpy(op->ob_sval+i, op->ob_sval, j); - i += j; - } + + _PyBytes_Repeat(op->ob_sval, size, a->ob_sval, Py_SIZE(a)); + return (PyObject *) op; } @@ -3528,3 +3515,28 @@ _PyBytesWriter_WriteBytes(_PyBytesWriter *writer, void *ptr, return str; } + + +void +_PyBytes_Repeat(char* dest, Py_ssize_t len_dest, + const char* src, Py_ssize_t len_src) +{ + if (len_dest == 0) { + return; + } + if (len_src == 1) { + memset(dest, src[0], len_dest); + } + else { + if (src != dest) { + memcpy(dest, src, len_src); + } + Py_ssize_t copied = len_src; + while (copied < len_dest) { + Py_ssize_t bytes_to_copy = Py_MIN(copied, len_dest - copied); + memcpy(dest + copied, dest, bytes_to_copy); + copied += bytes_to_copy; + } + } +} + diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index ce3ebce1ff72d..72f9245afb79a 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -42,6 +42,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_atomic_funcs.h" // _Py_atomic_size_get() +#include "pycore_bytesobject.h" // _PyBytes_Repeat() #include "pycore_bytes_methods.h" // _Py_bytes_lower() #include "pycore_format.h" // F_LJUST #include "pycore_initconfig.h" // _PyStatus_OK() @@ -12782,17 +12783,10 @@ unicode_repeat(PyObject *str, Py_ssize_t len) } } else { - /* number of characters copied this far */ - Py_ssize_t done = PyUnicode_GET_LENGTH(str); Py_ssize_t char_size = PyUnicode_KIND(str); char *to = (char *) PyUnicode_DATA(u); - memcpy(to, PyUnicode_DATA(str), - PyUnicode_GET_LENGTH(str) * char_size); - while (done < nchars) { - n = (done <= nchars-done) ? done : nchars-done; - memcpy(to + (done * char_size), to, n * char_size); - done += n; - } + _PyBytes_Repeat(to, nchars * char_size, PyUnicode_DATA(str), + PyUnicode_GET_LENGTH(str) * char_size); } assert(_PyUnicode_CheckConsistency(u, 1)); From webhook-mailer at python.org Mon Mar 28 13:05:11 2022 From: webhook-mailer at python.org (ned-deily) Date: Mon, 28 Mar 2022 17:05:11 -0000 Subject: [Python-checkins] bpo-47138: Fix documentation build by pinning Jinja version to 3.0.3 (GH-32111) Message-ID: https://github.com/python/cpython/commit/25f00bfb264a3197ac91c41cdec15036fd8401f1 commit: 25f00bfb264a3197ac91c41cdec15036fd8401f1 branch: 3.7 author: m-aciek committer: ned-deily date: 2022-03-28T13:05:01-04:00 summary: bpo-47138: Fix documentation build by pinning Jinja version to 3.0.3 (GH-32111) files: A Misc/NEWS.d/next/Documentation/2022-03-28-12-39-20.bpo-47138.TEZRwC.rst M Doc/Makefile diff --git a/Doc/Makefile b/Doc/Makefile index 1393bcb52500e..1b8cbfa479e50 100644 --- a/Doc/Makefile +++ b/Doc/Makefile @@ -127,7 +127,7 @@ clean: venv: $(PYTHON) -m venv $(VENVDIR) - $(VENVDIR)/bin/python3 -m pip install -U Sphinx==2.3.1 blurb docutils==0.17.1 + $(VENVDIR)/bin/python3 -m pip install -U Sphinx==2.3.1 blurb docutils==0.17.1 Jinja2==3.0.3 @echo "The venv has been created in the $(VENVDIR) directory" dist: diff --git a/Misc/NEWS.d/next/Documentation/2022-03-28-12-39-20.bpo-47138.TEZRwC.rst b/Misc/NEWS.d/next/Documentation/2022-03-28-12-39-20.bpo-47138.TEZRwC.rst new file mode 100644 index 0000000000000..aa3ed79d5e29c --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-03-28-12-39-20.bpo-47138.TEZRwC.rst @@ -0,0 +1 @@ +Pin Jinja to a version compatible with Sphinx version 2.3.1. From webhook-mailer at python.org Mon Mar 28 13:06:25 2022 From: webhook-mailer at python.org (ned-deily) Date: Mon, 28 Mar 2022 17:06:25 -0000 Subject: [Python-checkins] bpo-47138: Fix documentation build by pinning Jinja version to 3.0.3 (GH-32154) Message-ID: https://github.com/python/cpython/commit/9194a7b8990a0feec1209b1e5694df3bf42906d8 commit: 9194a7b8990a0feec1209b1e5694df3bf42906d8 branch: 3.10 author: Hugo van Kemenade committer: ned-deily date: 2022-03-28T13:06:16-04:00 summary: bpo-47138: Fix documentation build by pinning Jinja version to 3.0.3 (GH-32154) Co-authored-by: Maciej Olko files: A Misc/NEWS.d/next/Documentation/2022-03-28-12-29-42.bpo-47138.2B4N-k.rst M Doc/requirements.txt diff --git a/Doc/requirements.txt b/Doc/requirements.txt index 95d320f4cb1f3..793df32ecf65f 100644 --- a/Doc/requirements.txt +++ b/Doc/requirements.txt @@ -8,6 +8,8 @@ sphinx==3.2.1 # version 3.2.1. It can be removed after bumping Sphinx version to at # least 3.5.4. docutils==0.17.1 +# Jinja version is pinned to a version compatible with Sphinx version 3.2.1. +jinja2==3.0.3 blurb diff --git a/Misc/NEWS.d/next/Documentation/2022-03-28-12-29-42.bpo-47138.2B4N-k.rst b/Misc/NEWS.d/next/Documentation/2022-03-28-12-29-42.bpo-47138.2B4N-k.rst new file mode 100644 index 0000000000000..e15148b73b23b --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-03-28-12-29-42.bpo-47138.2B4N-k.rst @@ -0,0 +1 @@ +Pin Jinja to a version compatible with Sphinx version 3.2.1. From webhook-mailer at python.org Mon Mar 28 13:20:01 2022 From: webhook-mailer at python.org (ned-deily) Date: Mon, 28 Mar 2022 17:20:01 -0000 Subject: [Python-checkins] bpo-47138: Fix documentation build by pinning Jinja version to 3.0.3 (GH-32153) Message-ID: https://github.com/python/cpython/commit/25c40bd994aa0da75283c5efdd71ba26c734b67e commit: 25c40bd994aa0da75283c5efdd71ba26c734b67e branch: 3.9 author: Hugo van Kemenade committer: ned-deily date: 2022-03-28T13:19:56-04:00 summary: bpo-47138: Fix documentation build by pinning Jinja version to 3.0.3 (GH-32153) Co-authored-by: Maciej Olko files: A Misc/NEWS.d/next/Documentation/2022-03-28-12-32-17.bpo-47138.TbLXgV.rst M Doc/requirements.txt diff --git a/Doc/requirements.txt b/Doc/requirements.txt index 1b75aed035ac9..cf659a0fbac2e 100644 --- a/Doc/requirements.txt +++ b/Doc/requirements.txt @@ -8,6 +8,8 @@ sphinx==2.4.4 # version 2.4.4. It can be removed after bumping Sphinx version to at # least 3.5.4. docutils==0.17.1 +# Jinja version is pinned to a version compatible with Sphinx version 2.4.4. +jinja2==3.0.3 blurb diff --git a/Misc/NEWS.d/next/Documentation/2022-03-28-12-32-17.bpo-47138.TbLXgV.rst b/Misc/NEWS.d/next/Documentation/2022-03-28-12-32-17.bpo-47138.TbLXgV.rst new file mode 100644 index 0000000000000..9dde4de2dc8b5 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-03-28-12-32-17.bpo-47138.TbLXgV.rst @@ -0,0 +1 @@ +Pin Jinja to a version compatible with Sphinx version 2.4.4. From webhook-mailer at python.org Mon Mar 28 14:26:59 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 28 Mar 2022 18:26:59 -0000 Subject: [Python-checkins] [3.10] bpo-44493: Add missing terminated NUL in sockaddr_un's length (GH-26866) (GH-32140) Message-ID: https://github.com/python/cpython/commit/5944807b09717d43bb017f700e8c451dd07199ed commit: 5944807b09717d43bb017f700e8c451dd07199ed branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-28T11:26:49-07:00 summary: [3.10] bpo-44493: Add missing terminated NUL in sockaddr_un's length (GH-26866) (GH-32140) Add missing terminated NUL in sockaddr_un's length - Linux: https://man7.org/linux/man-pages/man7/unix.7.html - *BSD: SUN_LEN (cherry picked from commit f6b3a07b7df60dc04d0260169ffef6e9796a2124) Co-authored-by: ty Automerge-Triggered-By: GH:gpshead files: A Misc/NEWS.d/next/Library/2021-07-26-10-46-49.bpo-44493.xp3CRH.rst M Modules/socketmodule.c diff --git a/Misc/NEWS.d/next/Library/2021-07-26-10-46-49.bpo-44493.xp3CRH.rst b/Misc/NEWS.d/next/Library/2021-07-26-10-46-49.bpo-44493.xp3CRH.rst new file mode 100644 index 0000000000000..390a7222bbf55 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-07-26-10-46-49.bpo-44493.xp3CRH.rst @@ -0,0 +1,3 @@ +Add missing terminated NUL in sockaddr_un's length + +This was potentially observable when using non-abstract AF_UNIX datagram sockets to processes written in another programming language. diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index ab8618b341544..392cc32f7fa2f 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -1680,6 +1680,8 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, "AF_UNIX path too long"); goto unix_out; } + + *len_ret = path.len + offsetof(struct sockaddr_un, sun_path); } else #endif /* linux */ @@ -1691,10 +1693,13 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, goto unix_out; } addr->sun_path[path.len] = 0; + + /* including the tailing NUL */ + *len_ret = path.len + offsetof(struct sockaddr_un, sun_path) + 1; } addr->sun_family = s->sock_family; memcpy(addr->sun_path, path.buf, path.len); - *len_ret = path.len + offsetof(struct sockaddr_un, sun_path); + retval = 1; unix_out: PyBuffer_Release(&path); From webhook-mailer at python.org Mon Mar 28 14:44:56 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Mon, 28 Mar 2022 18:44:56 -0000 Subject: [Python-checkins] Fix typo in the sqlite3 docs (GH-31915) Message-ID: https://github.com/python/cpython/commit/66584c890d016e40d707400130d1cd98f2aedde9 commit: 66584c890d016e40d707400130d1cd98f2aedde9 branch: main author: Jonathan committer: JelleZijlstra date: 2022-03-28T11:44:41-07:00 summary: Fix typo in the sqlite3 docs (GH-31915) Co-authored-by: Jonathan <89750679+AHypnotoad at users.noreply.github.com> files: M Lib/sqlite3/__init__.py diff --git a/Lib/sqlite3/__init__.py b/Lib/sqlite3/__init__.py index 0dedf186b1a1e..5a2dbd360fb49 100644 --- a/Lib/sqlite3/__init__.py +++ b/Lib/sqlite3/__init__.py @@ -21,7 +21,7 @@ # 3. This notice may not be removed or altered from any source distribution. """ -The sqlite3 extension module provides a DB-API 2.0 (PEP 249) compilant +The sqlite3 extension module provides a DB-API 2.0 (PEP 249) compliant interface to the SQLite library, and requires SQLite 3.7.15 or newer. To use the module, start by creating a database Connection object: From webhook-mailer at python.org Mon Mar 28 14:45:51 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Mon, 28 Mar 2022 18:45:51 -0000 Subject: [Python-checkins] bpo-28516: document contextlib.ExitStack.__enter__ behavior (GH-31636) (GH-32145) Message-ID: https://github.com/python/cpython/commit/1e3132b1c3ebff8d28a6dd353bf217cb97c41e81 commit: 1e3132b1c3ebff8d28a6dd353bf217cb97c41e81 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: JelleZijlstra date: 2022-03-28T11:45:45-07:00 summary: bpo-28516: document contextlib.ExitStack.__enter__ behavior (GH-31636) (GH-32145) The enter_context is updated with following information: 'The :meth:`__enter__` method returns the ExitStack instance, and performs no additional operations.' Co-authored-by: Jelle Zijlstra (cherry picked from commit 86384cf83f96fcaec03e2ad6516e2e24f20d3b92) Co-authored-by: vidhya <96202776+Vidhyavinu at users.noreply.github.com> Co-authored-by: Ned Deily files: M Doc/library/contextlib.rst diff --git a/Doc/library/contextlib.rst b/Doc/library/contextlib.rst index 66a0f17a9234b..d471c8ce52796 100644 --- a/Doc/library/contextlib.rst +++ b/Doc/library/contextlib.rst @@ -368,6 +368,9 @@ Functions and classes provided: # the with statement, even if attempts to open files later # in the list raise an exception + The :meth:`__enter__` method returns the :class:`ExitStack` instance, and + performs no additional operations. + Each instance maintains a stack of registered callbacks that are called in reverse order when the instance is closed (either explicitly or implicitly at the end of a :keyword:`with` statement). Note that callbacks are *not* From webhook-mailer at python.org Mon Mar 28 16:03:37 2022 From: webhook-mailer at python.org (gpshead) Date: Mon, 28 Mar 2022 20:03:37 -0000 Subject: [Python-checkins] [3.9] bpo-44493: Add missing terminated NUL in sockaddr_un's length (GH-26866) (GH-32140) (GH-32156) Message-ID: https://github.com/python/cpython/commit/dae09c2b819c2683ad870733451c050b59c3eb93 commit: dae09c2b819c2683ad870733451c050b59c3eb93 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: gpshead date: 2022-03-28T13:03:18-07:00 summary: [3.9] bpo-44493: Add missing terminated NUL in sockaddr_un's length (GH-26866) (GH-32140) (GH-32156) Add missing terminated NUL in sockaddr_un's length - Linux: https://man7.org/linux/man-pages/man7/unix.7.html - *BSD: SUN_LEN (cherry picked from commit f6b3a07b7df60dc04d0260169ffef6e9796a2124) Co-authored-by: ty Automerge-Triggered-By: GH:gpshead (cherry picked from commit 5944807b09717d43bb017f700e8c451dd07199ed) Co-authored-by: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> files: A Misc/NEWS.d/next/Library/2021-07-26-10-46-49.bpo-44493.xp3CRH.rst M Modules/socketmodule.c diff --git a/Misc/NEWS.d/next/Library/2021-07-26-10-46-49.bpo-44493.xp3CRH.rst b/Misc/NEWS.d/next/Library/2021-07-26-10-46-49.bpo-44493.xp3CRH.rst new file mode 100644 index 0000000000000..390a7222bbf55 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-07-26-10-46-49.bpo-44493.xp3CRH.rst @@ -0,0 +1,3 @@ +Add missing terminated NUL in sockaddr_un's length + +This was potentially observable when using non-abstract AF_UNIX datagram sockets to processes written in another programming language. diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index a22060d399082..6d6c92e4c95d1 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -1722,6 +1722,8 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, "AF_UNIX path too long"); goto unix_out; } + + *len_ret = path.len + offsetof(struct sockaddr_un, sun_path); } else #endif /* linux */ @@ -1733,10 +1735,13 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, goto unix_out; } addr->sun_path[path.len] = 0; + + /* including the tailing NUL */ + *len_ret = path.len + offsetof(struct sockaddr_un, sun_path) + 1; } addr->sun_family = s->sock_family; memcpy(addr->sun_path, path.buf, path.len); - *len_ret = path.len + offsetof(struct sockaddr_un, sun_path); + retval = 1; unix_out: PyBuffer_Release(&path); From webhook-mailer at python.org Mon Mar 28 16:38:48 2022 From: webhook-mailer at python.org (zooba) Date: Mon, 28 Mar 2022 20:38:48 -0000 Subject: [Python-checkins] bpo-47138: Ensure Windows docs build uses the same pinned version as other platforms (GH-32161) Message-ID: https://github.com/python/cpython/commit/295114dcd32b3aad5453e5e15e9e1befa0e5ca01 commit: 295114dcd32b3aad5453e5e15e9e1befa0e5ca01 branch: main author: Steve Dower committer: zooba date: 2022-03-28T21:38:31+01:00 summary: bpo-47138: Ensure Windows docs build uses the same pinned version as other platforms (GH-32161) files: M Doc/make.bat diff --git a/Doc/make.bat b/Doc/make.bat index 9eaaa46806829..f3e9b44d61d4a 100644 --- a/Doc/make.bat +++ b/Doc/make.bat @@ -13,7 +13,7 @@ if not defined SPHINXBUILD ( %PYTHON% -c "import sphinx" > nul 2> nul if errorlevel 1 ( echo Installing sphinx with %PYTHON% - %PYTHON% -m pip install sphinx==2.2.0 + %PYTHON% -m pip install -r requirements.txt if errorlevel 1 exit /B ) set SPHINXBUILD=%PYTHON% -c "import sphinx.cmd.build, sys; sys.exit(sphinx.cmd.build.main())" @@ -30,6 +30,7 @@ if not defined BLURB ( %PYTHON% -c "import blurb" > nul 2> nul if errorlevel 1 ( echo Installing blurb with %PYTHON% + rem Should have been installed with Sphinx earlier %PYTHON% -m pip install blurb if errorlevel 1 exit /B ) @@ -40,6 +41,7 @@ if not defined SPHINXLINT ( %PYTHON% -c "import sphinxlint" > nul 2> nul if errorlevel 1 ( echo Installing sphinx-lint with %PYTHON% + rem Should have been installed with Sphinx earlier %PYTHON% -m pip install sphinx-lint if errorlevel 1 exit /B ) From webhook-mailer at python.org Mon Mar 28 16:56:16 2022 From: webhook-mailer at python.org (ericsnowcurrently) Date: Mon, 28 Mar 2022 20:56:16 -0000 Subject: [Python-checkins] bpo-47146: Eliminate a race between make regen-deepfreeze and make regen-global-objects. (gh-32162) Message-ID: https://github.com/python/cpython/commit/4c116f716bd1c174d6530b9a7a5ed3863927a109 commit: 4c116f716bd1c174d6530b9a7a5ed3863927a109 branch: main author: Eric Snow committer: ericsnowcurrently date: 2022-03-28T14:56:05-06:00 summary: bpo-47146: Eliminate a race between make regen-deepfreeze and make regen-global-objects. (gh-32162) The race likely originated with gh-32061. https://bugs.python.org/issue47146 files: M Makefile.pre.in diff --git a/Makefile.pre.in b/Makefile.pre.in index fb5dd6a066c7d..e6c6a6ba53a6d 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1136,7 +1136,10 @@ regen-frozen: Tools/scripts/freeze_modules.py $(FROZEN_FILES_IN) # Deepfreeze targets .PHONY: regen-deepfreeze -regen-deepfreeze: $(DEEPFREEZE_OBJS) +regen-deepfreeze: + @# Possibly generate globals first, to make sure _bootstrap_python builds. + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_global_objects.py + $(MAKE) $(DEEPFREEZE_OBJS) DEEPFREEZE_DEPS=$(srcdir)/Tools/scripts/deepfreeze.py $(FREEZE_MODULE_DEPS) $(FROZEN_FILES_OUT) @@ -1178,12 +1181,10 @@ regen-importlib: regen-frozen # Global objects .PHONY: regen-global-objects -regen-global-objects: $(srcdir)/Tools/scripts/generate_global_objects.py - $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_global_objects.py - @# Run one more time after deepfreezing, to catch any globals added - @# there. This is necessary because the deep-frozen code isn't - @# commited to the repo. - $(MAKE) regen-deepfreeze +regen-global-objects: regen-deepfreeze + @# We already ran in once, before deepfreezing, to make sure + @# _bootstrap_python builds. Now we run it again to catch any + @# remaining globals, including those added by deepfreeze. $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_global_objects.py ############################################################################ From webhook-mailer at python.org Mon Mar 28 17:03:13 2022 From: webhook-mailer at python.org (iritkatriel) Date: Mon, 28 Mar 2022 21:03:13 -0000 Subject: [Python-checkins] bpo-26120: make pydoc exclude __future__ imports from the data block of the module (GH-30888) Message-ID: https://github.com/python/cpython/commit/15ba8167d78f9e66bd5b07c4e5cbb0463460310a commit: 15ba8167d78f9e66bd5b07c4e5cbb0463460310a branch: main author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-03-28T22:02:57+01:00 summary: bpo-26120: make pydoc exclude __future__ imports from the data block of the module (GH-30888) files: A Misc/NEWS.d/next/Library/2022-01-25-15-45-04.bpo-26120.YzrBMO.rst M Lib/pydoc.py M Lib/test/pydoc_mod.py diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 85eefa46b7299..7ae390852fa01 100755 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -54,6 +54,7 @@ class or function within a module or module in a package. If the # the current directory is changed with os.chdir(), an incorrect # path will be displayed. +import __future__ import builtins import importlib._bootstrap import importlib._bootstrap_external @@ -274,6 +275,8 @@ def _split_list(s, predicate): no.append(x) return yes, no +_future_feature_names = set(__future__.all_feature_names) + def visiblename(name, all=None, obj=None): """Decide whether to show documentation on a variable.""" # Certain special names are redundant or internal. @@ -288,6 +291,10 @@ def visiblename(name, all=None, obj=None): # Namedtuples have public fields and methods with a single leading underscore if name.startswith('_') and hasattr(obj, '_fields'): return True + # Ignore __future__ imports. + if name in _future_feature_names: + if isinstance(getattr(obj, name, None), __future__._Feature): + return False if all is not None: # only document that which the programmer exported in __all__ return name in all diff --git a/Lib/test/pydoc_mod.py b/Lib/test/pydoc_mod.py index f9bc4b89d3d0a..80c287fb10c31 100644 --- a/Lib/test/pydoc_mod.py +++ b/Lib/test/pydoc_mod.py @@ -1,5 +1,7 @@ """This is a test module for test_pydoc""" +from __future__ import print_function + import types import typing diff --git a/Misc/NEWS.d/next/Library/2022-01-25-15-45-04.bpo-26120.YzrBMO.rst b/Misc/NEWS.d/next/Library/2022-01-25-15-45-04.bpo-26120.YzrBMO.rst new file mode 100644 index 0000000000000..bc45b277d8d6f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-01-25-15-45-04.bpo-26120.YzrBMO.rst @@ -0,0 +1 @@ +:mod:`pydoc` now excludes __future__ imports from the module's data items. From webhook-mailer at python.org Mon Mar 28 17:08:45 2022 From: webhook-mailer at python.org (ericvsmith) Date: Mon, 28 Mar 2022 21:08:45 -0000 Subject: [Python-checkins] bpo-47129: Add more informative messages to f-string syntax errors (32127) Message-ID: https://github.com/python/cpython/commit/7b44ade018cfe6f54002a3cee43e8aa415d4d635 commit: 7b44ade018cfe6f54002a3cee43e8aa415d4d635 branch: main author: Maciej G?rski <36813763+macgors at users.noreply.github.com> committer: ericvsmith date: 2022-03-28T17:08:36-04:00 summary: bpo-47129: Add more informative messages to f-string syntax errors (32127) * Add more informative messages to f-string syntax errors * ?? Added by blurb_it. * Fix whitespaces * Change error message * Remove the 'else' statement (as sugested in review) Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> files: A Misc/NEWS.d/next/Core and Builtins/2022-03-26-16-35-57.bpo-47129.hDg2Vt.rst M Lib/test/test_fstring.py M Parser/string_parser.c diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index 0c255c2af2217..0c3372f033551 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -628,16 +628,27 @@ def test_missing_expression(self): ["f'{}'", "f'{ }'" "f' {} '", - "f'{!r}'", - "f'{ !r}'", "f'{10:{ }}'", "f' { } '", # The Python parser ignores also the following # whitespace characters in additional to a space. "f'''{\t\f\r\n}'''", + ]) + + # Different error messeges are raised when a specfier ('!', ':' or '=') is used after an empty expression + self.assertAllRaise(SyntaxError, "f-string: expression required before '!'", + ["f'{!r}'", + "f'{ !r}'", + "f'{!}'", + "f'''{\t\f\r\n!a}'''", + + # Catch empty expression before the + # missing closing brace. + "f'{!'", + "f'{!s:'", - # Catch the empty expression before the + # Catch empty expression before the # invalid conversion. "f'{!x}'", "f'{ !xr}'", @@ -645,16 +656,23 @@ def test_missing_expression(self): "f'{!x:a}'", "f'{ !xr:}'", "f'{ !xr:a}'", + ]) - "f'{!}'", - "f'{:}'", - - # We find the empty expression before the - # missing closing brace. - "f'{!'", - "f'{!s:'", + self.assertAllRaise(SyntaxError, "f-string: expression required before ':'", + ["f'{:}'", + "f'{ :!}'", + "f'{:2}'", + "f'''{\t\f\r\n:a}'''", "f'{:'", - "f'{:x'", + ]) + + self.assertAllRaise(SyntaxError, "f-string: expression required before '='", + ["f'{=}'", + "f'{ =}'", + "f'{ =:}'", + "f'{ =!}'", + "f'''{\t\f\r\n=}'''", + "f'{='", ]) # Different error message is raised for other whitespace characters. diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-26-16-35-57.bpo-47129.hDg2Vt.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-26-16-35-57.bpo-47129.hDg2Vt.rst new file mode 100644 index 0000000000000..1627aba41d636 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-26-16-35-57.bpo-47129.hDg2Vt.rst @@ -0,0 +1 @@ +Improve error messages in f-string syntax errors concerning empty expressions. diff --git a/Parser/string_parser.c b/Parser/string_parser.c index fae2a3648cf9f..65ddd46874b20 100644 --- a/Parser/string_parser.c +++ b/Parser/string_parser.c @@ -357,7 +357,12 @@ fstring_compile_expr(Parser *p, const char *expr_start, const char *expr_end, break; } } + if (s == expr_end) { + if (*expr_end == '!' || *expr_end == ':' || *expr_end == '=') { + RAISE_SYNTAX_ERROR("f-string: expression required before '%c'", *expr_end); + return NULL; + } RAISE_SYNTAX_ERROR("f-string: empty expression not allowed"); return NULL; } From webhook-mailer at python.org Mon Mar 28 17:50:34 2022 From: webhook-mailer at python.org (asvetlov) Date: Mon, 28 Mar 2022 21:50:34 -0000 Subject: [Python-checkins] bpo-27929: resolve names only for AF_INET/AF_INET6 with asyncio (GH-32131) Message-ID: https://github.com/python/cpython/commit/5c30388f3c586ba2f33e349e22e5949cb92de621 commit: 5c30388f3c586ba2f33e349e22e5949cb92de621 branch: main author: Vincent Bernat committer: asvetlov date: 2022-03-29T00:50:26+03:00 summary: bpo-27929: resolve names only for AF_INET/AF_INET6 with asyncio (GH-32131) Co-authored-by: Andrew Svetlov files: A Misc/NEWS.d/next/Library/2022-03-28-13-35-50.bpo-27929.j5mAmV.rst M Lib/asyncio/selector_events.py diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index 33ebc4b27808c..e99a50395e7cb 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -620,7 +620,8 @@ async def sock_connect(self, sock, address): if self._debug and sock.gettimeout() != 0: raise ValueError("the socket must be non-blocking") - if not hasattr(socket, 'AF_UNIX') or sock.family != socket.AF_UNIX: + if sock.family == socket.AF_INET or ( + base_events._HAS_IPv6 and sock.family == socket.AF_INET6): resolved = await self._ensure_resolved( address, family=sock.family, type=sock.type, proto=sock.proto, loop=self, diff --git a/Misc/NEWS.d/next/Library/2022-03-28-13-35-50.bpo-27929.j5mAmV.rst b/Misc/NEWS.d/next/Library/2022-03-28-13-35-50.bpo-27929.j5mAmV.rst new file mode 100644 index 0000000000000..4c80a10bc5684 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-28-13-35-50.bpo-27929.j5mAmV.rst @@ -0,0 +1,3 @@ +Fix :meth:`asyncio.loop.sock_connect` to only resolve names for :const:`socket.AF_INET` or +:const:`socket.AF_INET6` families. Resolution may not make sense for other families, +like :const:`socket.AF_BLUETOOTH` and :const:`socket.AF_UNIX`. From webhook-mailer at python.org Mon Mar 28 18:15:15 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 28 Mar 2022 22:15:15 -0000 Subject: [Python-checkins] bpo-27929: resolve names only for AF_INET/AF_INET6 with asyncio (GH-32131) Message-ID: https://github.com/python/cpython/commit/2bcbc3113dee6c35631595ec0d5ee3a8dd2a2ddd commit: 2bcbc3113dee6c35631595ec0d5ee3a8dd2a2ddd branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-28T15:15:05-07:00 summary: bpo-27929: resolve names only for AF_INET/AF_INET6 with asyncio (GH-32131) Co-authored-by: Andrew Svetlov (cherry picked from commit 5c30388f3c586ba2f33e349e22e5949cb92de621) Co-authored-by: Vincent Bernat files: A Misc/NEWS.d/next/Library/2022-03-28-13-35-50.bpo-27929.j5mAmV.rst M Lib/asyncio/selector_events.py diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index 71080b8ad16c6..572d4a8ce12d4 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -487,7 +487,8 @@ async def sock_connect(self, sock, address): if self._debug and sock.gettimeout() != 0: raise ValueError("the socket must be non-blocking") - if not hasattr(socket, 'AF_UNIX') or sock.family != socket.AF_UNIX: + if sock.family == socket.AF_INET or ( + base_events._HAS_IPv6 and sock.family == socket.AF_INET6): resolved = await self._ensure_resolved( address, family=sock.family, type=sock.type, proto=sock.proto, loop=self, diff --git a/Misc/NEWS.d/next/Library/2022-03-28-13-35-50.bpo-27929.j5mAmV.rst b/Misc/NEWS.d/next/Library/2022-03-28-13-35-50.bpo-27929.j5mAmV.rst new file mode 100644 index 0000000000000..4c80a10bc5684 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-28-13-35-50.bpo-27929.j5mAmV.rst @@ -0,0 +1,3 @@ +Fix :meth:`asyncio.loop.sock_connect` to only resolve names for :const:`socket.AF_INET` or +:const:`socket.AF_INET6` families. Resolution may not make sense for other families, +like :const:`socket.AF_BLUETOOTH` and :const:`socket.AF_UNIX`. From webhook-mailer at python.org Mon Mar 28 18:16:34 2022 From: webhook-mailer at python.org (miss-islington) Date: Mon, 28 Mar 2022 22:16:34 -0000 Subject: [Python-checkins] bpo-27929: resolve names only for AF_INET/AF_INET6 with asyncio (GH-32131) Message-ID: https://github.com/python/cpython/commit/f84fb55659079bbc99d4cd0441dc13ab07ac3dcf commit: f84fb55659079bbc99d4cd0441dc13ab07ac3dcf branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-28T15:16:30-07:00 summary: bpo-27929: resolve names only for AF_INET/AF_INET6 with asyncio (GH-32131) Co-authored-by: Andrew Svetlov (cherry picked from commit 5c30388f3c586ba2f33e349e22e5949cb92de621) Co-authored-by: Vincent Bernat files: A Misc/NEWS.d/next/Library/2022-03-28-13-35-50.bpo-27929.j5mAmV.rst M Lib/asyncio/selector_events.py diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index 71080b8ad16c6..572d4a8ce12d4 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -487,7 +487,8 @@ async def sock_connect(self, sock, address): if self._debug and sock.gettimeout() != 0: raise ValueError("the socket must be non-blocking") - if not hasattr(socket, 'AF_UNIX') or sock.family != socket.AF_UNIX: + if sock.family == socket.AF_INET or ( + base_events._HAS_IPv6 and sock.family == socket.AF_INET6): resolved = await self._ensure_resolved( address, family=sock.family, type=sock.type, proto=sock.proto, loop=self, diff --git a/Misc/NEWS.d/next/Library/2022-03-28-13-35-50.bpo-27929.j5mAmV.rst b/Misc/NEWS.d/next/Library/2022-03-28-13-35-50.bpo-27929.j5mAmV.rst new file mode 100644 index 0000000000000..4c80a10bc5684 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-28-13-35-50.bpo-27929.j5mAmV.rst @@ -0,0 +1,3 @@ +Fix :meth:`asyncio.loop.sock_connect` to only resolve names for :const:`socket.AF_INET` or +:const:`socket.AF_INET6` families. Resolution may not make sense for other families, +like :const:`socket.AF_BLUETOOTH` and :const:`socket.AF_UNIX`. From webhook-mailer at python.org Mon Mar 28 19:21:26 2022 From: webhook-mailer at python.org (zooba) Date: Mon, 28 Mar 2022 23:21:26 -0000 Subject: [Python-checkins] bpo-46566: Add new py.exe launcher implementation (GH-32062) Message-ID: https://github.com/python/cpython/commit/bad86a621af61f383b9f06fe4a08f66245df99e2 commit: bad86a621af61f383b9f06fe4a08f66245df99e2 branch: main author: Steve Dower committer: zooba date: 2022-03-29T00:21:08+01:00 summary: bpo-46566: Add new py.exe launcher implementation (GH-32062) files: A Lib/test/test_launcher.py A Misc/NEWS.d/next/Windows/2022-03-23-12-51-46.bpo-46566.4x4a7e.rst A PC/launcher-usage.txt A PC/launcher2.c M Doc/using/windows.rst M PC/pylauncher.rc M PCbuild/pylauncher.vcxproj M PCbuild/pywlauncher.vcxproj M Tools/msi/launcher/launcher.wixproj M Tools/msi/launcher/launcher_files.wxs diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index 618dfeac0a765..7e7be63d7da39 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -817,6 +817,13 @@ minor version. I.e. ``/usr/bin/python2.7-32`` will request usage of the by the "-64" suffix. Furthermore it is possible to specify a major and architecture without minor (i.e. ``/usr/bin/python3-64``). +.. versionchanged:: 3.11 + + The "-64" suffix is deprecated, and now implies "any architecture that is + not provably i386/32-bit". To request a specific environment, use the new + ``-V:`` argument with the complete tag. + + The ``/usr/bin/env`` form of shebang line has one further special property. Before looking for installed Python interpreters, this form will search the executable :envvar:`PATH` for a Python executable. This corresponds to the @@ -937,13 +944,65 @@ For example: Diagnostics ----------- -If an environment variable ``PYLAUNCH_DEBUG`` is set (to any value), the +If an environment variable :envvar:`PYLAUNCHER_DEBUG` is set (to any value), the launcher will print diagnostic information to stderr (i.e. to the console). While this information manages to be simultaneously verbose *and* terse, it should allow you to see what versions of Python were located, why a particular version was chosen and the exact command-line used to execute the -target Python. +target Python. It is primarily intended for testing and debugging. + +Dry Run +------- + +If an environment variable :envvar:`PYLAUNCHER_DRYRUN` is set (to any value), +the launcher will output the command it would have run, but will not actually +launch Python. This may be useful for tools that want to use the launcher to +detect and then launch Python directly. Note that the command written to +standard output is always encoded using UTF-8, and may not render correctly in +the console. + +Install on demand +----------------- + +If an environment variable :envvar:`PYLAUNCHER_ALLOW_INSTALL` is set (to any +value), and the requested Python version is not installed but is available on +the Microsoft Store, the launcher will attempt to install it. This may require +user interaction to complete, and you may need to run the command again. + +An additional :envvar:`PYLAUNCHER_ALWAYS_INSTALL` variable causes the launcher +to always try to install Python, even if it is detected. This is mainly intended +for testing (and should be used with :envvar:`PYLAUNCHER_DRYRUN`). + +Return codes +------------ +The following exit codes may be returned by the Python launcher. Unfortunately, +there is no way to distinguish these from the exit code of Python itself. + +The names of codes are as used in the sources, and are only for reference. There +is no way to access or resolve them apart from reading this page. Entries are +listed in alphabetical order of names. + ++-------------------+-------+-----------------------------------------------+ +| Name | Value | Description | ++===================+=======+===============================================+ +| RC_BAD_VENV_CFG | 107 | A :file:`pyvenv.cfg` was found but is corrupt.| ++-------------------+-------+-----------------------------------------------+ +| RC_CREATE_PROCESS | 101 | Failed to launch Python. | ++-------------------+-------+-----------------------------------------------+ +| RC_INSTALLING | 111 | An install was started, but the command will | +| | | need to be re-run after it completes. | ++-------------------+-------+-----------------------------------------------+ +| RC_INTERNAL_ERROR | 109 | Unexpected error. Please report a bug. | ++-------------------+-------+-----------------------------------------------+ +| RC_NO_COMMANDLINE | 108 | Unable to obtain command line from the | +| | | operating system. | ++-------------------+-------+-----------------------------------------------+ +| RC_NO_PYTHON | 103 | Unable to locate the requested version. | ++-------------------+-------+-----------------------------------------------+ +| RC_NO_VENV_CFG | 106 | A :file:`pyvenv.cfg` was required but not | +| | | found. | ++-------------------+-------+-----------------------------------------------+ .. _windows_finding_modules: diff --git a/Lib/test/test_launcher.py b/Lib/test/test_launcher.py new file mode 100644 index 0000000000000..2fb5aae628a67 --- /dev/null +++ b/Lib/test/test_launcher.py @@ -0,0 +1,423 @@ +import contextlib +import itertools +import os +import re +import subprocess +import sys +import sysconfig +import tempfile +import textwrap +import unittest +from pathlib import Path +from test import support + +if sys.platform != "win32": + raise unittest.SkipTest("test only applies to Windows") + +# Get winreg after the platform check +import winreg + + +PY_EXE = "py.exe" +if sys.executable.casefold().endswith("_d.exe".casefold()): + PY_EXE = "py_d.exe" + +# Registry data to create. On removal, everything beneath top-level names will +# be deleted. +TEST_DATA = { + "PythonTestSuite": { + "DisplayName": "Python Test Suite", + "SupportUrl": "https://www.python.org/", + "3.100": { + "DisplayName": "X.Y version", + "InstallPath": { + None: sys.prefix, + "ExecutablePath": "X.Y.exe", + } + }, + "3.100-32": { + "DisplayName": "X.Y-32 version", + "InstallPath": { + None: sys.prefix, + "ExecutablePath": "X.Y-32.exe", + } + }, + "3.100-arm64": { + "DisplayName": "X.Y-arm64 version", + "InstallPath": { + None: sys.prefix, + "ExecutablePath": "X.Y-arm64.exe", + "ExecutableArguments": "-X fake_arg_for_test", + } + }, + "ignored": { + "DisplayName": "Ignored because no ExecutablePath", + "InstallPath": { + None: sys.prefix, + } + }, + } +} + +TEST_PY_COMMANDS = textwrap.dedent(""" + [defaults] + py_python=PythonTestSuite/3.100 + py_python2=PythonTestSuite/3.100-32 + py_python3=PythonTestSuite/3.100-arm64 +""") + + +def create_registry_data(root, data): + def _create_registry_data(root, key, value): + if isinstance(value, dict): + # For a dict, we recursively create keys + with winreg.CreateKeyEx(root, key) as hkey: + for k, v in value.items(): + _create_registry_data(hkey, k, v) + elif isinstance(value, str): + # For strings, we set values. 'key' may be None in this case + winreg.SetValueEx(root, key, None, winreg.REG_SZ, value) + else: + raise TypeError("don't know how to create data for '{}'".format(value)) + + for k, v in data.items(): + _create_registry_data(root, k, v) + + +def enum_keys(root): + for i in itertools.count(): + try: + yield winreg.EnumKey(root, i) + except OSError as ex: + if ex.winerror == 259: + break + raise + + +def delete_registry_data(root, keys): + ACCESS = winreg.KEY_WRITE | winreg.KEY_ENUMERATE_SUB_KEYS + for key in list(keys): + with winreg.OpenKey(root, key, access=ACCESS) as hkey: + delete_registry_data(hkey, enum_keys(hkey)) + winreg.DeleteKey(root, key) + + +def is_installed(tag): + key = rf"Software\Python\PythonCore\{tag}\InstallPath" + for root, flag in [ + (winreg.HKEY_CURRENT_USER, 0), + (winreg.HKEY_LOCAL_MACHINE, winreg.KEY_WOW64_64KEY), + (winreg.HKEY_LOCAL_MACHINE, winreg.KEY_WOW64_32KEY), + ]: + try: + winreg.CloseKey(winreg.OpenKey(root, key, access=winreg.KEY_READ | flag)) + return True + except OSError: + pass + return False + + +class PreservePyIni: + def __init__(self, path, content): + self.path = Path(path) + self.content = content + self._preserved = None + + def __enter__(self): + try: + self._preserved = self.path.read_bytes() + except FileNotFoundError: + self._preserved = None + self.path.write_text(self.content, encoding="utf-16") + + def __exit__(self, *exc_info): + if self._preserved is None: + self.path.unlink() + else: + self.path.write_bytes(self._preserved) + + +class RunPyMixin: + py_exe = None + + @classmethod + def find_py(cls): + py_exe = None + if sysconfig.is_python_build(True): + py_exe = Path(sys.executable).parent / PY_EXE + else: + for p in os.getenv("PATH").split(";"): + if p: + py_exe = Path(p) / PY_EXE + if py_exe.is_file(): + break + if not py_exe: + raise unittest.SkipTest( + "cannot locate '{}' for test".format(PY_EXE) + ) + return py_exe + + def run_py(self, args, env=None, allow_fail=False, expect_returncode=0): + if not self.py_exe: + self.py_exe = self.find_py() + + env = {**os.environ, **(env or {}), "PYLAUNCHER_DEBUG": "1", "PYLAUNCHER_DRYRUN": "1"} + with subprocess.Popen( + [self.py_exe, *args], + env=env, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) as p: + p.stdin.close() + p.wait(10) + out = p.stdout.read().decode("utf-8", "replace") + err = p.stderr.read().decode("ascii", "replace") + if p.returncode != expect_returncode and support.verbose and not allow_fail: + print("++ COMMAND ++") + print([self.py_exe, *args]) + print("++ STDOUT ++") + print(out) + print("++ STDERR ++") + print(err) + if allow_fail and p.returncode != expect_returncode: + raise subprocess.CalledProcessError(p.returncode, [self.py_exe, *args], out, err) + else: + self.assertEqual(expect_returncode, p.returncode) + data = { + s.partition(":")[0]: s.partition(":")[2].lstrip() + for s in err.splitlines() + if not s.startswith("#") and ":" in s + } + data["stdout"] = out + data["stderr"] = err + return data + + def py_ini(self, content): + if not self.py_exe: + self.py_exe = self.find_py() + return PreservePyIni(self.py_exe.with_name("py.ini"), content) + + @contextlib.contextmanager + def script(self, content, encoding="utf-8"): + file = Path(tempfile.mktemp(dir=os.getcwd()) + ".py") + file.write_text(content, encoding=encoding) + try: + yield file + finally: + file.unlink() + + +class TestLauncher(unittest.TestCase, RunPyMixin): + @classmethod + def setUpClass(cls): + with winreg.CreateKey(winreg.HKEY_CURRENT_USER, rf"Software\Python") as key: + create_registry_data(key, TEST_DATA) + + if support.verbose: + p = subprocess.check_output("reg query HKCU\\Software\\Python /s") + print(p.decode('mbcs')) + + + @classmethod + def tearDownClass(cls): + with winreg.OpenKey(winreg.HKEY_CURRENT_USER, rf"Software\Python", access=winreg.KEY_WRITE | winreg.KEY_ENUMERATE_SUB_KEYS) as key: + delete_registry_data(key, TEST_DATA) + + + def test_version(self): + data = self.run_py(["-0"]) + self.assertEqual(self.py_exe, Path(data["argv0"])) + self.assertEqual(sys.version.partition(" ")[0], data["version"]) + + def test_help_option(self): + data = self.run_py(["-h"]) + self.assertEqual("True", data["SearchInfo.help"]) + + def test_list_option(self): + for opt, v1, v2 in [ + ("-0", "True", "False"), + ("-0p", "False", "True"), + ("--list", "True", "False"), + ("--list-paths", "False", "True"), + ]: + with self.subTest(opt): + data = self.run_py([opt]) + self.assertEqual(v1, data["SearchInfo.list"]) + self.assertEqual(v2, data["SearchInfo.listPaths"]) + + def test_list(self): + data = self.run_py(["--list"]) + found = {} + expect = {} + for line in data["stdout"].splitlines(): + m = re.match(r"\s*(.+?)\s+(.+)$", line) + if m: + found[m.group(1)] = m.group(2) + for company in TEST_DATA: + company_data = TEST_DATA[company] + tags = [t for t in company_data if isinstance(company_data[t], dict)] + for tag in tags: + arg = f"-V:{company}/{tag}" + expect[arg] = company_data[tag]["DisplayName"] + expect.pop(f"-V:{company}/ignored", None) + + actual = {k: v for k, v in found.items() if k in expect} + try: + self.assertDictEqual(expect, actual) + except: + if support.verbose: + print("*** STDOUT ***") + print(data["stdout"]) + raise + + def test_list_paths(self): + data = self.run_py(["--list-paths"]) + found = {} + expect = {} + for line in data["stdout"].splitlines(): + m = re.match(r"\s*(.+?)\s+(.+)$", line) + if m: + found[m.group(1)] = m.group(2) + for company in TEST_DATA: + company_data = TEST_DATA[company] + tags = [t for t in company_data if isinstance(company_data[t], dict)] + for tag in tags: + arg = f"-V:{company}/{tag}" + install = company_data[tag]["InstallPath"] + try: + expect[arg] = install["ExecutablePath"] + try: + expect[arg] += " " + install["ExecutableArguments"] + except KeyError: + pass + except KeyError: + expect[arg] = str(Path(install[None]) / Path(sys.executable).name) + + expect.pop(f"-V:{company}/ignored", None) + + actual = {k: v for k, v in found.items() if k in expect} + try: + self.assertDictEqual(expect, actual) + except: + if support.verbose: + print("*** STDOUT ***") + print(data["stdout"]) + raise + + def test_filter_to_company(self): + company = "PythonTestSuite" + data = self.run_py([f"-V:{company}/"]) + self.assertEqual("X.Y.exe", data["LaunchCommand"]) + self.assertEqual(company, data["env.company"]) + self.assertEqual("3.100", data["env.tag"]) + + def test_filter_to_tag(self): + company = "PythonTestSuite" + data = self.run_py([f"-V:3.100"]) + self.assertEqual("X.Y.exe", data["LaunchCommand"]) + self.assertEqual(company, data["env.company"]) + self.assertEqual("3.100", data["env.tag"]) + + data = self.run_py([f"-V:3.100-3"]) + self.assertEqual("X.Y-32.exe", data["LaunchCommand"]) + self.assertEqual(company, data["env.company"]) + self.assertEqual("3.100-32", data["env.tag"]) + + data = self.run_py([f"-V:3.100-a"]) + self.assertEqual("X.Y-arm64.exe -X fake_arg_for_test", data["LaunchCommand"]) + self.assertEqual(company, data["env.company"]) + self.assertEqual("3.100-arm64", data["env.tag"]) + + def test_filter_to_company_and_tag(self): + company = "PythonTestSuite" + data = self.run_py([f"-V:{company}/3.1"]) + self.assertEqual("X.Y.exe", data["LaunchCommand"]) + self.assertEqual(company, data["env.company"]) + self.assertEqual("3.100", data["env.tag"]) + + def test_search_major_3(self): + try: + data = self.run_py(["-3"], allow_fail=True) + except subprocess.CalledProcessError: + raise unittest.SkipTest("requires at least one Python 3.x install") + self.assertEqual("PythonCore", data["env.company"]) + self.assertTrue(data["env.tag"].startswith("3."), data["env.tag"]) + + def test_search_major_3_32(self): + try: + data = self.run_py(["-3-32"], allow_fail=True) + except subprocess.CalledProcessError: + if not any(is_installed(f"3.{i}-32") for i in range(5, 11)): + raise unittest.SkipTest("requires at least one 32-bit Python 3.x install") + raise + self.assertEqual("PythonCore", data["env.company"]) + self.assertTrue(data["env.tag"].startswith("3."), data["env.tag"]) + self.assertTrue(data["env.tag"].endswith("-32"), data["env.tag"]) + + def test_search_major_2(self): + try: + data = self.run_py(["-2"], allow_fail=True) + except subprocess.CalledProcessError: + if not is_installed("2.7"): + raise unittest.SkipTest("requires at least one Python 2.x install") + self.assertEqual("PythonCore", data["env.company"]) + self.assertTrue(data["env.tag"].startswith("2."), data["env.tag"]) + + def test_py_default(self): + with self.py_ini(TEST_PY_COMMANDS): + data = self.run_py(["-arg"]) + self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) + self.assertEqual("3.100", data["SearchInfo.tag"]) + self.assertEqual("X.Y.exe -arg", data["stdout"].strip()) + + def test_py2_default(self): + with self.py_ini(TEST_PY_COMMANDS): + data = self.run_py(["-2", "-arg"]) + self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) + self.assertEqual("3.100-32", data["SearchInfo.tag"]) + self.assertEqual("X.Y-32.exe -arg", data["stdout"].strip()) + + def test_py3_default(self): + with self.py_ini(TEST_PY_COMMANDS): + data = self.run_py(["-3", "-arg"]) + self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) + self.assertEqual("3.100-arm64", data["SearchInfo.tag"]) + self.assertEqual("X.Y-arm64.exe -X fake_arg_for_test -arg", data["stdout"].strip()) + + def test_py_shebang(self): + with self.py_ini(TEST_PY_COMMANDS): + with self.script("#! /usr/bin/env python -prearg") as script: + data = self.run_py([script, "-postarg"]) + self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) + self.assertEqual("3.100", data["SearchInfo.tag"]) + self.assertEqual(f"X.Y.exe -prearg {script} -postarg", data["stdout"].strip()) + + def test_py2_shebang(self): + with self.py_ini(TEST_PY_COMMANDS): + with self.script("#! /usr/bin/env python2 -prearg") as script: + data = self.run_py([script, "-postarg"]) + self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) + self.assertEqual("3.100-32", data["SearchInfo.tag"]) + self.assertEqual(f"X.Y-32.exe -prearg {script} -postarg", data["stdout"].strip()) + + def test_py3_shebang(self): + with self.py_ini(TEST_PY_COMMANDS): + with self.script("#! /usr/bin/env python3 -prearg") as script: + data = self.run_py([script, "-postarg"]) + self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) + self.assertEqual("3.100-arm64", data["SearchInfo.tag"]) + self.assertEqual(f"X.Y-arm64.exe -X fake_arg_for_test -prearg {script} -postarg", data["stdout"].strip()) + + def test_install(self): + data = self.run_py(["-V:3.10"], env={"PYLAUNCHER_ALWAYS_INSTALL": "1"}, expect_returncode=111) + cmd = data["stdout"].strip() + # If winget is runnable, we should find it. Otherwise, we'll be trying + # to open the Store. + try: + subprocess.check_call(["winget.exe", "--version"]) + except FileNotFoundError: + self.assertIn("ms-windows-store://", cmd) + else: + self.assertIn("winget.exe", cmd) + self.assertIn("9PJPW5LDXLZ5", cmd) diff --git a/Misc/NEWS.d/next/Windows/2022-03-23-12-51-46.bpo-46566.4x4a7e.rst b/Misc/NEWS.d/next/Windows/2022-03-23-12-51-46.bpo-46566.4x4a7e.rst new file mode 100644 index 0000000000000..b1822872113f7 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-03-23-12-51-46.bpo-46566.4x4a7e.rst @@ -0,0 +1,6 @@ +Upgraded :ref:`launcher` to support a new ``-V:company/tag`` argument for +full :pep:`514` support and to detect ARM64 installs. The ``-64`` suffix on +arguments is deprecated, but still selects any non-32-bit install. Setting +:envvar:`PYLAUNCHER_ALLOW_INSTALL` and specifying a version that is not +installed will attempt to install the requested version from the Microsoft +Store. diff --git a/PC/launcher-usage.txt b/PC/launcher-usage.txt new file mode 100644 index 0000000000000..aad103509daa2 --- /dev/null +++ b/PC/launcher-usage.txt @@ -0,0 +1,31 @@ +Python Launcher for Windows Version %s + +usage: +%s [launcher-args] [python-args] [script [script-args]] + +Launcher arguments: +-2 : Launch the latest Python 2.x version +-3 : Launch the latest Python 3.x version +-X.Y : Launch the specified Python version + +The above default to an architecture native runtime, but will select any +available. Add a "-32" to the argument to only launch 32-bit runtimes, +or add "-64" to omit 32-bit runtimes (this latter option is deprecated). + +To select a specific runtime, use the -V: options. + +-V:TAG : Launch a Python runtime with the specified tag +-V:COMPANY/TAG : Launch a Python runtime from the specified company and + with the specified tag + +-0 --list : List the available pythons +-0p --list-paths : List with paths + +If no options are given but a script is specified, the script is checked for a +shebang line. Otherwise, an active virtual environment or global default will +be selected. + +See https://docs.python.org/using/windows.html#python-launcher-for-windows for +additional configuration. + +The following help text is from Python: diff --git a/PC/launcher2.c b/PC/launcher2.c new file mode 100644 index 0000000000000..873538171d93e --- /dev/null +++ b/PC/launcher2.c @@ -0,0 +1,2264 @@ +/* + * Rewritten Python launcher for Windows + * + * This new rewrite properly handles PEP 514 and allows any registered Python + * runtime to be launched. It also enables auto-install of versions when they + * are requested but no installation can be found. + */ + +#define __STDC_WANT_LIB_EXT1__ 1 + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MS_WINDOWS +#include "patchlevel.h" + +#define MAXLEN PATHCCH_MAX_CCH +#define MSGSIZE 1024 + +#define RC_NO_STD_HANDLES 100 +#define RC_CREATE_PROCESS 101 +#define RC_BAD_VIRTUAL_PATH 102 +#define RC_NO_PYTHON 103 +#define RC_NO_MEMORY 104 +#define RC_NO_SCRIPT 105 +#define RC_NO_VENV_CFG 106 +#define RC_BAD_VENV_CFG 107 +#define RC_NO_COMMANDLINE 108 +#define RC_INTERNAL_ERROR 109 +#define RC_DUPLICATE_ITEM 110 +#define RC_INSTALLING 111 +#define RC_NO_PYTHON_AT_ALL 112 + +static FILE * log_fp = NULL; + +void +debug(wchar_t * format, ...) +{ + va_list va; + + if (log_fp != NULL) { + wchar_t buffer[MAXLEN]; + int r = 0; + va_start(va, format); + r = vswprintf_s(buffer, MAXLEN, format, va); + va_end(va); + + if (r <= 0) { + return; + } + fputws(buffer, log_fp); + while (r && isspace(buffer[r])) { + buffer[r--] = L'\0'; + } + if (buffer[0]) { + OutputDebugStringW(buffer); + } + } +} + + +void +formatWinerror(int rc, wchar_t * message, int size) +{ + FormatMessageW( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + message, size, NULL); +} + + +void +winerror(int err, wchar_t * format, ... ) +{ + va_list va; + wchar_t message[MSGSIZE]; + wchar_t win_message[MSGSIZE]; + int len; + + if (err == 0) { + err = GetLastError(); + } + + va_start(va, format); + len = _vsnwprintf_s(message, MSGSIZE, _TRUNCATE, format, va); + va_end(va); + + formatWinerror(err, win_message, MSGSIZE); + if (len >= 0) { + _snwprintf_s(&message[len], MSGSIZE - len, _TRUNCATE, L": %s", + win_message); + } + +#if !defined(_WINDOWS) + fwprintf(stderr, L"%s\n", message); +#else + MessageBoxW(NULL, message, L"Python Launcher is sorry to say ...", + MB_OK); +#endif +} + + +void +error(wchar_t * format, ... ) +{ + va_list va; + wchar_t message[MSGSIZE]; + + va_start(va, format); + _vsnwprintf_s(message, MSGSIZE, _TRUNCATE, format, va); + va_end(va); + +#if !defined(_WINDOWS) + fwprintf(stderr, L"%s\n", message); +#else + MessageBoxW(NULL, message, L"Python Launcher is sorry to say ...", + MB_OK); +#endif +} + + +typedef BOOL (*PIsWow64Process2)(HANDLE, USHORT*, USHORT*); + + +USHORT +_getNativeMachine() +{ + static USHORT _nativeMachine = IMAGE_FILE_MACHINE_UNKNOWN; + if (_nativeMachine == IMAGE_FILE_MACHINE_UNKNOWN) { + USHORT processMachine; + HMODULE kernel32 = GetModuleHandleW(L"kernel32.dll"); + PIsWow64Process2 IsWow64Process2 = kernel32 ? + (PIsWow64Process2)GetProcAddress(kernel32, "IsWow64Process2") : + NULL; + if (!IsWow64Process2) { + BOOL wow64Process; + if (!IsWow64Process(NULL, &wow64Process)) { + winerror(0, L"Checking process type"); + } else if (wow64Process) { + // We should always be a 32-bit executable, so if running + // under emulation, it must be a 64-bit host. + _nativeMachine = IMAGE_FILE_MACHINE_AMD64; + } else { + // Not running under emulation, and an old enough OS to not + // have IsWow64Process2, so assume it's x86. + _nativeMachine = IMAGE_FILE_MACHINE_I386; + } + } else if (!IsWow64Process2(NULL, &processMachine, &_nativeMachine)) { + winerror(0, L"Checking process type"); + } + } + return _nativeMachine; +} + + +bool +isAMD64Host() +{ + return _getNativeMachine() == IMAGE_FILE_MACHINE_AMD64; +} + + +bool +isARM64Host() +{ + return _getNativeMachine() == IMAGE_FILE_MACHINE_ARM64; +} + + +bool +isEnvVarSet(const wchar_t *name) +{ + /* only looking for non-empty, which means at least one character + and the null terminator */ + return GetEnvironmentVariableW(name, NULL, 0) >= 2; +} + + +bool +join(wchar_t *buffer, size_t bufferLength, const wchar_t *fragment) +{ + if (SUCCEEDED(PathCchCombineEx(buffer, bufferLength, buffer, fragment, PATHCCH_ALLOW_LONG_PATHS))) { + return true; + } + return false; +} + + +int +_compare(const wchar_t *x, int xLen, const wchar_t *y, int yLen) +{ + // Empty strings sort first + if (xLen == 0) { + return yLen == 0 ? 0 : -1; + } else if (yLen == 0) { + return 1; + } + switch (CompareStringEx( + LOCALE_NAME_INVARIANT, NORM_IGNORECASE | SORT_DIGITSASNUMBERS, + x, xLen, y, yLen, + NULL, NULL, 0 + )) { + case CSTR_LESS_THAN: + return -1; + case CSTR_EQUAL: + return 0; + case CSTR_GREATER_THAN: + return 1; + default: + winerror(0, L"Error comparing '%.*s' and '%.*s' (compare)", xLen, x, yLen, y); + return -1; + } +} + + +int +_compareArgument(const wchar_t *x, int xLen, const wchar_t *y, int yLen) +{ + // Empty strings sort first + if (xLen == 0) { + return yLen == 0 ? 0 : -1; + } else if (yLen == 0) { + return 1; + } + switch (CompareStringEx( + LOCALE_NAME_INVARIANT, 0, + x, xLen, y, yLen, + NULL, NULL, 0 + )) { + case CSTR_LESS_THAN: + return -1; + case CSTR_EQUAL: + return 0; + case CSTR_GREATER_THAN: + return 1; + default: + winerror(0, L"Error comparing '%.*s' and '%.*s' (compareArgument)", xLen, x, yLen, y); + return -1; + } +} + +int +_comparePath(const wchar_t *x, int xLen, const wchar_t *y, int yLen) +{ + // Empty strings sort first + if (xLen == 0) { + return yLen == 0 ? 0 : -1; + } else if (yLen == 0) { + return 1; + } + switch (CompareStringOrdinal(x, xLen, y, yLen, TRUE)) { + case CSTR_LESS_THAN: + return -1; + case CSTR_EQUAL: + return 0; + case CSTR_GREATER_THAN: + return 1; + default: + winerror(0, L"Error comparing '%.*s' and '%.*s' (comparePath)", xLen, x, yLen, y); + return -1; + } +} + + +bool +_startsWith(const wchar_t *x, int xLen, const wchar_t *y, int yLen) +{ + yLen = yLen < 0 ? (int)wcsnlen_s(y, MAXLEN) : yLen; + xLen = xLen < 0 ? (int)wcsnlen_s(x, MAXLEN) : xLen; + return xLen >= yLen && 0 == _compare(x, yLen, y, yLen); +} + + +bool +_startsWithArgument(const wchar_t *x, int xLen, const wchar_t *y, int yLen) +{ + yLen = yLen < 0 ? (int)wcsnlen_s(y, MAXLEN) : yLen; + xLen = xLen < 0 ? (int)wcsnlen_s(x, MAXLEN) : xLen; + return xLen >= yLen && 0 == _compareArgument(x, yLen, y, yLen); +} + + +/******************************************************************************\ + *** HELP TEXT *** +\******************************************************************************/ + + +int +showHelpText(wchar_t ** argv) +{ + // The help text is stored in launcher-usage.txt, which is compiled into + // the launcher and loaded at runtime if needed. + // + // The file must be UTF-8. There are two substitutions: + // %ls - PY_VERSION (as wchar_t*) + // %ls - argv[0] (as wchar_t*) + HRSRC res = FindResourceExW(NULL, L"USAGE", MAKEINTRESOURCE(1), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)); + HGLOBAL resData = res ? LoadResource(NULL, res) : NULL; + const char *usage = resData ? (const char*)LockResource(resData) : NULL; + if (usage == NULL) { + winerror(0, L"Unable to load usage text"); + return RC_INTERNAL_ERROR; + } + + DWORD cbData = SizeofResource(NULL, res); + DWORD cchUsage = MultiByteToWideChar(CP_UTF8, 0, usage, cbData, NULL, 0); + if (!cchUsage) { + winerror(0, L"Unable to preprocess usage text"); + return RC_INTERNAL_ERROR; + } + + cchUsage += 1; + wchar_t *wUsage = (wchar_t*)malloc(cchUsage * sizeof(wchar_t)); + cchUsage = MultiByteToWideChar(CP_UTF8, 0, usage, cbData, wUsage, cchUsage); + if (!cchUsage) { + winerror(0, L"Unable to preprocess usage text"); + free((void *)wUsage); + return RC_INTERNAL_ERROR; + } + // Ensure null termination + wUsage[cchUsage] = L'\0'; + + fwprintf(stdout, wUsage, (L"" PY_VERSION), argv[0]); + fflush(stdout); + + free((void *)wUsage); + + return 0; +} + + +/******************************************************************************\ + *** SEARCH INFO *** +\******************************************************************************/ + + +struct _SearchInfoBuffer { + struct _SearchInfoBuffer *next; + wchar_t buffer[0]; +}; + + +typedef struct { + // the original string, managed by the OS + const wchar_t *originalCmdLine; + // pointer into the cmdline to mark what we've consumed + const wchar_t *restOfCmdLine; + // if known/discovered, the full executable path of our runtime + const wchar_t *executablePath; + // pointer and length into cmdline for the file to check for a + // shebang line, if any. Length can be -1 if the string is null + // terminated. + const wchar_t *scriptFile; + int scriptFileLength; + // pointer and length into cmdline or a static string with the + // name of the target executable. Length can be -1 if the string + // is null terminated. + const wchar_t *executable; + int executableLength; + // pointer and length into a string with additional interpreter + // arguments to include before restOfCmdLine. Length can be -1 if + // the string is null terminated. + const wchar_t *executableArgs; + int executableArgsLength; + // pointer and length into cmdline or a static string with the + // company name for PEP 514 lookup. Length can be -1 if the string + // is null terminated. + const wchar_t *company; + int companyLength; + // pointer and length into cmdline or a static string with the + // tag for PEP 514 lookup. Length can be -1 if the string is + // null terminated. + const wchar_t *tag; + int tagLength; + // if true, treats 'tag' as a non-PEP 514 filter + bool oldStyleTag; + // if true, we had an old-style tag with '-64' suffix, and so do not + // want to match tags like '3.x-32' + bool exclude32Bit; + // if true, we had an old-style tag with '-32' suffix, and so *only* + // want to match tags like '3.x-32' + bool only32Bit; + // if true, allow PEP 514 lookup to override 'executable' + bool allowExecutableOverride; + // if true, allow a nearby pyvenv.cfg to locate the executable + bool allowPyvenvCfg; + // if true, allow defaults (env/py.ini) to clarify/override tags + bool allowDefaults; + // if true, prefer windowed (console-less) executable + bool windowed; + // if true, only list detected runtimes without launching + bool list; + // if true, only list detected runtimes with paths without launching + bool listPaths; + // if true, display help message before contiuning + bool help; + // dynamically allocated buffers to free later + struct _SearchInfoBuffer *_buffer; +} SearchInfo; + + +wchar_t * +allocSearchInfoBuffer(SearchInfo *search, int wcharCount) +{ + struct _SearchInfoBuffer *buffer = (struct _SearchInfoBuffer*)malloc( + sizeof(struct _SearchInfoBuffer) + + wcharCount * sizeof(wchar_t) + ); + if (!buffer) { + return NULL; + } + buffer->next = search->_buffer; + search->_buffer = buffer; + return buffer->buffer; +} + + +void +freeSearchInfo(SearchInfo *search) +{ + struct _SearchInfoBuffer *b = search->_buffer; + search->_buffer = NULL; + while (b) { + struct _SearchInfoBuffer *nextB = b->next; + free((void *)b); + b = nextB; + } +} + + +void +_debugStringAndLength(const wchar_t *s, int len, const wchar_t *name) +{ + if (!s) { + debug(L"%s: (null)\n", name); + } else if (len == 0) { + debug(L"%s: (empty)\n", name); + } else if (len < 0) { + debug(L"%s: %s\n", name, s); + } else { + debug(L"%s: %.*ls\n", name, len, s); + } +} + + +void +dumpSearchInfo(SearchInfo *search) +{ + if (!log_fp) { + return; + } + +#define DEBUGNAME(s) L"SearchInfo." ## s +#define DEBUG(s) debug(DEBUGNAME(#s) L": %s\n", (search->s) ? (search->s) : L"(null)") +#define DEBUG_2(s, sl) _debugStringAndLength((search->s), (search->sl), DEBUGNAME(#s)) +#define DEBUG_BOOL(s) debug(DEBUGNAME(#s) L": %s\n", (search->s) ? L"True" : L"False") + DEBUG(originalCmdLine); + DEBUG(restOfCmdLine); + DEBUG(executablePath); + DEBUG_2(scriptFile, scriptFileLength); + DEBUG_2(executable, executableLength); + DEBUG_2(executableArgs, executableArgsLength); + DEBUG_2(company, companyLength); + DEBUG_2(tag, tagLength); + DEBUG_BOOL(oldStyleTag); + DEBUG_BOOL(exclude32Bit); + DEBUG_BOOL(only32Bit); + DEBUG_BOOL(allowDefaults); + DEBUG_BOOL(allowExecutableOverride); + DEBUG_BOOL(windowed); + DEBUG_BOOL(list); + DEBUG_BOOL(listPaths); + DEBUG_BOOL(help); +#undef DEBUG_BOOL +#undef DEBUG_2 +#undef DEBUG +#undef DEBUGNAME +} + + +int +findArgumentLength(const wchar_t *buffer, int bufferLength) +{ + if (bufferLength < 0) { + bufferLength = (int)wcsnlen_s(buffer, MAXLEN); + } + if (bufferLength == 0) { + return 0; + } + const wchar_t *end; + int i; + + if (buffer[0] != L'"') { + end = wcschr(buffer, L' '); + if (!end) { + return bufferLength; + } + i = (int)(end - buffer); + return i < bufferLength ? i : bufferLength; + } + + i = 0; + while (i < bufferLength) { + end = wcschr(&buffer[i + 1], L'"'); + if (!end) { + return bufferLength; + } + + i = (int)(end - buffer); + if (i >= bufferLength) { + return bufferLength; + } + + int j = i; + while (j > 1 && buffer[--j] == L'\\') { + if (j > 0 && buffer[--j] == L'\\') { + // Even number, so back up and keep counting + } else { + // Odd number, so it's escaped and we want to keep searching + continue; + } + } + + // Non-escaped quote with space after it - end of the argument! + if (i + 1 >= bufferLength || isspace(buffer[i + 1])) { + return i + 1; + } + } + + return bufferLength; +} + + +const wchar_t * +findArgumentEnd(const wchar_t *buffer, int bufferLength) +{ + return &buffer[findArgumentLength(buffer, bufferLength)]; +} + + +/******************************************************************************\ + *** COMMAND-LINE PARSING *** +\******************************************************************************/ + + +int +parseCommandLine(SearchInfo *search) +{ + if (!search || !search->originalCmdLine) { + return RC_NO_COMMANDLINE; + } + + const wchar_t *tail = findArgumentEnd(search->originalCmdLine, -1); + const wchar_t *end = tail; + search->restOfCmdLine = tail; + while (--tail != search->originalCmdLine) { + if (*tail == L'.' && end == search->restOfCmdLine) { + end = tail; + } else if (*tail == L'\\' || *tail == L'/') { + ++tail; + break; + } + } + // Without special cases, we can now fill in the search struct + int tailLen = (int)(end ? (end - tail) : wcsnlen_s(tail, MAXLEN)); + search->executableLength = -1; + + // Our special cases are as follows +#define MATCHES(s) (0 == _comparePath(tail, tailLen, (s), -1)) +#define STARTSWITH(s) _startsWith(tail, tailLen, (s), -1) + if (MATCHES(L"py")) { + search->executable = L"python.exe"; + search->allowExecutableOverride = true; + search->allowDefaults = true; + } else if (MATCHES(L"pyw")) { + search->executable = L"pythonw.exe"; + search->allowExecutableOverride = true; + search->allowDefaults = true; + search->windowed = true; + } else if (MATCHES(L"py_d")) { + search->executable = L"python_d.exe"; + search->allowExecutableOverride = true; + search->allowDefaults = true; + } else if (MATCHES(L"pyw_d")) { + search->executable = L"pythonw_d.exe"; + search->allowExecutableOverride = true; + search->allowDefaults = true; + search->windowed = true; + } else if (STARTSWITH(L"python3")) { + search->executable = L"python.exe"; + search->tag = &tail[6]; + search->tagLength = tailLen - 6; + search->allowExecutableOverride = true; + search->oldStyleTag = true; + search->allowPyvenvCfg = true; + } else if (STARTSWITH(L"pythonw3")) { + search->executable = L"pythonw.exe"; + search->tag = &tail[7]; + search->tagLength = tailLen - 7; + search->allowExecutableOverride = true; + search->oldStyleTag = true; + search->allowPyvenvCfg = true; + search->windowed = true; + } else { + search->executable = tail; + search->executableLength = tailLen; + search->allowPyvenvCfg = true; + } +#undef STARTSWITH +#undef MATCHES + + // First argument might be one of our options. If so, consume it, + // update flags and then set restOfCmdLine. + const wchar_t *arg = search->restOfCmdLine; + while(*arg && isspace(*arg)) { ++arg; } +#define MATCHES(s) (0 == _compareArgument(arg, argLen, (s), -1)) +#define STARTSWITH(s) _startsWithArgument(arg, argLen, (s), -1) + if (*arg && *arg == L'-' && *++arg) { + tail = arg; + while (*tail && !isspace(*tail)) { ++tail; } + int argLen = (int)(tail - arg); + if (argLen > 0) { + if (STARTSWITH(L"2") || STARTSWITH(L"3")) { + // All arguments starting with 2 or 3 are assumed to be version tags + search->tag = arg; + search->tagLength = argLen; + search->oldStyleTag = true; + search->restOfCmdLine = tail; + // If the tag ends with -64, we want to exclude 32-bit runtimes + // (If the tag ends with -32, it will be filtered later) + if (argLen > 3) { + if (0 == _compareArgument(&arg[argLen - 3], 3, L"-64", 3)) { + search->tagLength -= 3; + search->exclude32Bit = true; + } else if (0 == _compareArgument(&arg[argLen - 3], 3, L"-32", 3)) { + search->tagLength -= 3; + search->only32Bit = true; + } + } + } else if (STARTSWITH(L"V:") || STARTSWITH(L"-version:")) { + // Arguments starting with 'V:' specify company and/or tag + const wchar_t *argStart = wcschr(arg, L':') + 1; + const wchar_t *tagStart = wcschr(argStart, L'/') ; + if (tagStart) { + search->company = argStart; + search->companyLength = (int)(tagStart - argStart); + search->tag = tagStart + 1; + } else { + search->tag = argStart; + } + search->tagLength = (int)(tail - search->tag); + search->restOfCmdLine = tail; + } else if (MATCHES(L"0") || MATCHES(L"-list")) { + search->list = true; + search->restOfCmdLine = tail; + } else if (MATCHES(L"0p") || MATCHES(L"-list-paths")) { + search->listPaths = true; + search->restOfCmdLine = tail; + } else if (MATCHES(L"h") || MATCHES(L"-help")) { + search->help = true; + // Do not update restOfCmdLine so that we trigger the help + // message from whichever interpreter we select + } + } + } +#undef STARTSWITH +#undef MATCHES + + // Might have a script filename. If it looks like a filename, add + // it to the SearchInfo struct for later reference. + arg = search->restOfCmdLine; + while(*arg && isspace(*arg)) { ++arg; } + if (*arg && *arg != L'-') { + search->scriptFile = arg; + if (*arg == L'"') { + ++search->scriptFile; + while (*++arg && *arg != L'"') { } + } else { + while (*arg && !isspace(*arg)) { ++arg; } + } + search->scriptFileLength = (int)(arg - search->scriptFile); + } + + return 0; +} + + +int +_decodeShebang(SearchInfo *search, const char *buffer, int bufferLength, bool onlyUtf8, wchar_t **decoded, int *decodedLength) +{ + DWORD cp = CP_UTF8; + int wideLen = MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, buffer, bufferLength, NULL, 0); + if (!wideLen) { + cp = CP_ACP; + wideLen = MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, buffer, bufferLength, NULL, 0); + if (!wideLen) { + debug(L"# Failed to decode shebang line (0x%08X)\n", GetLastError()); + return RC_BAD_VIRTUAL_PATH; + } + } + wchar_t *b = allocSearchInfoBuffer(search, wideLen + 1); + if (!b) { + return RC_NO_MEMORY; + } + wideLen = MultiByteToWideChar(cp, 0, buffer, bufferLength, b, wideLen + 1); + if (!wideLen) { + debug(L"# Failed to decode shebang line (0x%08X)\n", GetLastError()); + return RC_BAD_VIRTUAL_PATH; + } + b[wideLen] = L'\0'; + *decoded = b; + *decodedLength = wideLen; + return 0; +} + + +bool +_shebangStartsWith(const wchar_t *buffer, int bufferLength, const wchar_t *prefix, const wchar_t **rest) +{ + int prefixLength = (int)wcsnlen_s(prefix, MAXLEN); + if (bufferLength < prefixLength) { + return false; + } + if (rest) { + *rest = &buffer[prefixLength]; + } + return _startsWithArgument(buffer, bufferLength, prefix, prefixLength); +} + + +int +_readIni(const wchar_t *section, const wchar_t *settingName, wchar_t *buffer, int bufferLength) +{ + wchar_t iniPath[MAXLEN]; + int n; + if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, iniPath)) && + join(iniPath, MAXLEN, L"py.ini")) { + debug(L"# Reading from %s for %s/%s\n", iniPath, section, settingName); + n = GetPrivateProfileStringW(section, settingName, NULL, buffer, bufferLength, iniPath); + if (n) { + debug(L"# Found %s in %s\n", settingName, iniPath); + return true; + } else if (GetLastError() == ERROR_FILE_NOT_FOUND) { + debug(L"# Did not find file %s\n", iniPath); + } else { + winerror(0, L"Failed to read from %s\n", iniPath); + } + } + if (GetModuleFileNameW(NULL, iniPath, MAXLEN) && + SUCCEEDED(PathCchRemoveFileSpec(iniPath, MAXLEN)) && + join(iniPath, MAXLEN, L"py.ini")) { + debug(L"# Reading from %s for %s/%s\n", iniPath, section, settingName); + n = GetPrivateProfileStringW(section, settingName, NULL, buffer, MAXLEN, iniPath); + if (n) { + debug(L"# Found %s in %s\n", settingName, iniPath); + return n; + } else if (GetLastError() == ERROR_FILE_NOT_FOUND) { + debug(L"# Did not find file %s\n", iniPath); + } else { + winerror(0, L"Failed to read from %s\n", iniPath); + } + } + return 0; +} + + +bool +_findCommand(SearchInfo *search, const wchar_t *command, int commandLength) +{ + wchar_t commandBuffer[MAXLEN]; + wchar_t buffer[MAXLEN]; + wcsncpy_s(commandBuffer, MAXLEN, command, commandLength); + int n = _readIni(L"commands", commandBuffer, buffer, MAXLEN); + if (!n) { + return false; + } + wchar_t *path = allocSearchInfoBuffer(search, n + 1); + if (!path) { + return false; + } + wcscpy_s(path, n + 1, buffer); + search->executablePath = path; + return true; +} + + +int +checkShebang(SearchInfo *search) +{ + // Do not check shebang if a tag was provided or if no script file + // was found on the command line. + if (search->tag || !search->scriptFile) { + return 0; + } + + if (search->scriptFileLength < 0) { + search->scriptFileLength = (int)wcsnlen_s(search->scriptFile, MAXLEN); + } + + wchar_t *scriptFile = (wchar_t*)malloc(sizeof(wchar_t) * (search->scriptFileLength + 1)); + if (!scriptFile) { + return RC_NO_MEMORY; + } + + wcsncpy_s(scriptFile, search->scriptFileLength + 1, + search->scriptFile, search->scriptFileLength); + + HANDLE hFile = CreateFileW(scriptFile, GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, OPEN_EXISTING, 0, NULL); + + if (hFile == INVALID_HANDLE_VALUE) { + debug(L"# Failed to open %s for shebang parsing (0x%08X)\n", + scriptFile, GetLastError()); + free(scriptFile); + return 0; + } + + DWORD bytesRead = 0; + char buffer[4096]; + if (!ReadFile(hFile, buffer, sizeof(buffer), &bytesRead, NULL)) { + debug(L"# Failed to read %s for shebang parsing (0x%08X)\n", + scriptFile, GetLastError()); + free(scriptFile); + return 0; + } + + CloseHandle(hFile); + debug(L"# Read %d bytes from %s to find shebang line\n", bytesRead, scriptFile); + free(scriptFile); + + + char *b = buffer; + bool onlyUtf8 = false; + if (bytesRead > 3 && *b == 0xEF) { + if (*++b == 0xBB && *++b == 0xBF) { + // Allow a UTF-8 BOM + ++b; + bytesRead -= 3; + onlyUtf8 = true; + } else { + debug(L"# Invalid BOM in shebang line"); + return 0; + } + } + if (bytesRead <= 2 || b[0] != '#' || b[1] != '!') { + // No shebang (#!) at start of line + debug(L"# No valid shebang line"); + return 0; + } + ++b; + --bytesRead; + while (--bytesRead > 0 && isspace(*++b)) { } + char *start = b; + while (--bytesRead > 0 && *++b != '\r' && *b != '\n') { } + wchar_t *shebang; + int shebangLength; + int exitCode = _decodeShebang(search, start, (int)(b - start + 1), onlyUtf8, &shebang, &shebangLength); + if (exitCode) { + return exitCode; + } + debug(L"Shebang: %s\n", shebang); + + // Handle some known, case-sensitive shebang templates + const wchar_t *command; + int commandLength; + static const wchar_t *shebangTemplates[] = { + L"/usr/bin/env ", + L"/usr/bin/", + L"/usr/local/bin/", + L"", + NULL + }; + for (const wchar_t **tmpl = shebangTemplates; *tmpl; ++tmpl) { + if (_shebangStartsWith(shebang, shebangLength, *tmpl, &command)) { + commandLength = 0; + while (command[commandLength] && !isspace(command[commandLength])) { + commandLength += 1; + } + if (!commandLength) { + } else if (_findCommand(search, command, commandLength)) { + search->executableArgs = &command[commandLength]; + search->executableArgsLength = shebangLength - commandLength; + debug(L"# Treating shebang command '%.*s' as %s\n", + commandLength, command, search->executablePath); + } else if (_shebangStartsWith(command, commandLength, L"python", NULL)) { + search->tag = &command[6]; + search->tagLength = commandLength - 6; + search->oldStyleTag = true; + search->executableArgs = &command[commandLength]; + search->executableArgsLength = shebangLength - commandLength; + debug(L"# Treating shebang command '%.*s' as 'py -%.*s'\n", + commandLength, command, search->tagLength, search->tag); + } else { + debug(L"# Found shebang command but could not execute it: %.*s\n", + commandLength, command); + } + break; + } + } + + return 0; +} + + +int +checkDefaults(SearchInfo *search) +{ + if (!search->allowDefaults || search->list || search->listPaths) { + return 0; + } + + wchar_t buffer[MAXLEN]; + int n; + + // If no tag was provided at all, look for an active virtual environment + if (!search->tag || !search->tagLength) { + n = GetEnvironmentVariableW(L"VIRTUAL_ENV", buffer, MAXLEN); + if (n && join(buffer, MAXLEN, L"Scripts") && join(buffer, MAXLEN, search->executable)) { + if (INVALID_FILE_ATTRIBUTES != GetFileAttributesW(buffer)) { + n = (int)wcsnlen_s(buffer, MAXLEN) + 1; + wchar_t *path = allocSearchInfoBuffer(search, n); + if (!path) { + return RC_NO_MEMORY; + } + search->executablePath = path; + wcscpy_s(path, n, buffer); + return 0; + } else { + debug(L"Python executable %s missing from virtual env\n", buffer); + } + } + } + + // Only resolve old-style (or absent) tags to defaults + if (search->tag && search->tagLength && !search->oldStyleTag) { + return 0; + } + + // If tag is only a major version number, expand it from the environment + // or an ini file + const wchar_t *settingName = NULL; + if (!search->tag || !search->tagLength) { + settingName = L"py_python"; + } else if (0 == wcsncmp(search->tag, L"3", search->tagLength)) { + settingName = L"py_python3"; + } else if (0 == wcsncmp(search->tag, L"2", search->tagLength)) { + settingName = L"py_python2"; + } else { + debug(L"# Cannot select defaults for tag '%.*s'\n", search->tagLength, search->tag); + return 0; + } + + // First, try to read an environment variable + n = GetEnvironmentVariableW(settingName, buffer, MAXLEN); + + // If none found, check in our two .ini files instead + if (!n) { + n = _readIni(L"defaults", settingName, buffer, MAXLEN); + } + + if (n) { + wchar_t *tag = allocSearchInfoBuffer(search, n + 1); + if (!tag) { + return RC_NO_MEMORY; + } + wcscpy_s(tag, n + 1, buffer); + wchar_t *slash = wcschr(tag, L'/'); + if (!slash) { + search->tag = tag; + search->tagLength = n; + } else { + search->company = tag; + search->companyLength = (int)(slash - tag); + search->tag = slash + 1; + search->tagLength = n - (search->companyLength + 1); + search->oldStyleTag = false; + } + } + + return 0; +} + +/******************************************************************************\ + *** ENVIRONMENT SEARCH *** +\******************************************************************************/ + +typedef struct EnvironmentInfo { + /* We use a binary tree and sort on insert */ + struct EnvironmentInfo *prev; + struct EnvironmentInfo *next; + /* parent is only used when constructing */ + struct EnvironmentInfo *parent; + const wchar_t *company; + const wchar_t *tag; + int internalSortKey; + const wchar_t *installDir; + const wchar_t *executablePath; + const wchar_t *executableArgs; + const wchar_t *architecture; + const wchar_t *displayName; +} EnvironmentInfo; + + +int +copyWstr(const wchar_t **dest, const wchar_t *src) +{ + if (!dest) { + return RC_NO_MEMORY; + } + if (!src) { + *dest = NULL; + return 0; + } + size_t n = wcsnlen_s(src, MAXLEN - 1) + 1; + wchar_t *buffer = (wchar_t*)malloc(n * sizeof(wchar_t)); + if (!buffer) { + return RC_NO_MEMORY; + } + wcsncpy_s(buffer, n, src, n - 1); + *dest = (const wchar_t*)buffer; + return 0; +} + + +EnvironmentInfo * +newEnvironmentInfo(const wchar_t *company, const wchar_t *tag) +{ + EnvironmentInfo *env = (EnvironmentInfo *)malloc(sizeof(EnvironmentInfo)); + if (!env) { + return NULL; + } + memset(env, 0, sizeof(EnvironmentInfo)); + int exitCode = copyWstr(&env->company, company); + if (exitCode) { + free((void *)env); + return NULL; + } + exitCode = copyWstr(&env->tag, tag); + if (exitCode) { + free((void *)env->company); + free((void *)env); + return NULL; + } + return env; +} + + +void +freeEnvironmentInfo(EnvironmentInfo *env) +{ + if (env) { + free((void *)env->company); + free((void *)env->tag); + free((void *)env->installDir); + free((void *)env->executablePath); + free((void *)env->executableArgs); + free((void *)env->displayName); + freeEnvironmentInfo(env->prev); + env->prev = NULL; + freeEnvironmentInfo(env->next); + env->next = NULL; + free((void *)env); + } +} + + +/* Specific string comparisons for sorting the tree */ + +int +_compareCompany(const wchar_t *x, const wchar_t *y) +{ + bool coreX = 0 == _compare(x, -1, L"PythonCore", -1); + bool coreY = 0 == _compare(y, -1, L"PythonCore", -1); + if (coreX) { + return coreY ? 0 : -1; + } else if (coreY) { + return 1; + } + return _compare(x, -1, y, -1); +} + + +int +_compareTag(const wchar_t *x, const wchar_t *y) +{ + // Compare up to the first dash. If not equal, that's our sort order + const wchar_t *xDash = wcschr(x, L'-'); + const wchar_t *yDash = wcschr(y, L'-'); + int xToDash = xDash ? (int)(xDash - x) : -1; + int yToDash = yDash ? (int)(yDash - y) : -1; + int r = _compare(x, xToDash, y, yToDash); + if (r) { + return r; + } + // If we're equal up to the first dash, we want to sort one with + // no dash *after* one with a dash. Otherwise, a reversed compare. + // This works out because environments are sorted in descending tag + // order, so that higher versions (probably) come first. + // For PythonCore, our "X.Y" structure ensures that higher versions + // come first. Everyone else will just have to deal with it. + if (xDash && yDash) { + return _compare(yDash, -1, xDash, -1); + } else if (xDash) { + return -1; + } else if (yDash) { + return 1; + } + return 0; +} + + +int +addEnvironmentInfo(EnvironmentInfo **root, EnvironmentInfo *node) +{ + EnvironmentInfo *r = *root; + if (!r) { + *root = node; + node->parent = NULL; + return 0; + } + // Sort by company name + switch (_compareCompany(node->company, r->company)) { + case -1: + return addEnvironmentInfo(&r->prev, node); + case 1: + return addEnvironmentInfo(&r->next, node); + case 0: + break; + } + // Then by tag (descending) + switch (_compareTag(node->tag, r->tag)) { + case -1: + return addEnvironmentInfo(&r->next, node); + case 1: + return addEnvironmentInfo(&r->prev, node); + case 0: + break; + } + // Then keep the one with the lowest internal sort key + if (r->internalSortKey < node->internalSortKey) { + // Replace the current node + node->parent = r->parent; + if (node->parent) { + if (node->parent->prev == r) { + node->parent->prev = node; + } else if (node->parent->next == r) { + node->parent->next = node; + } else { + debug(L"# Inconsistent parent value in tree\n"); + freeEnvironmentInfo(node); + return RC_INTERNAL_ERROR; + } + } + node->next = r->next; + node->prev = r->prev; + } else { + debug(L"# not adding %s/%s/%i to tree\n", node->company, node->tag, node->internalSortKey); + freeEnvironmentInfo(node); + return RC_DUPLICATE_ITEM; + } + return 0; +} + + +/******************************************************************************\ + *** REGISTRY SEARCH *** +\******************************************************************************/ + + +int +_registryReadString(const wchar_t **dest, HKEY root, const wchar_t *subkey, const wchar_t *value) +{ + // Note that this is bytes (hence 'cb'), not characters ('cch') + DWORD cbData = 0; + DWORD flags = RRF_RT_REG_SZ | RRF_RT_REG_EXPAND_SZ; + + if (ERROR_SUCCESS != RegGetValueW(root, subkey, value, flags, NULL, NULL, &cbData)) { + return 0; + } + + wchar_t *buffer = (wchar_t*)malloc(cbData); + if (!buffer) { + return RC_NO_MEMORY; + } + + if (ERROR_SUCCESS == RegGetValueW(root, subkey, value, flags, NULL, buffer, &cbData)) { + *dest = buffer; + } else { + free((void *)buffer); + } + return 0; +} + + +int +_combineWithInstallDir(const wchar_t **dest, const wchar_t *installDir, const wchar_t *fragment, int fragmentLength) +{ + wchar_t buffer[MAXLEN]; + wchar_t fragmentBuffer[MAXLEN]; + if (wcsncpy_s(fragmentBuffer, MAXLEN, fragment, fragmentLength)) { + return RC_NO_MEMORY; + } + + if (FAILED(PathCchCombineEx(buffer, MAXLEN, installDir, fragmentBuffer, PATHCCH_ALLOW_LONG_PATHS))) { + return RC_NO_MEMORY; + } + + return copyWstr(dest, buffer); +} + + +int +_registryReadEnvironment(const SearchInfo *search, HKEY root, EnvironmentInfo *env, const wchar_t *fallbackArch) +{ + int exitCode = _registryReadString(&env->installDir, root, L"InstallPath", NULL); + if (exitCode) { + return exitCode; + } + if (!env->installDir) { + return RC_NO_PYTHON; + } + + // If pythonw.exe requested, check specific value + if (search->windowed) { + exitCode = _registryReadString(&env->executablePath, root, L"InstallPath", L"WindowedExecutablePath"); + if (!exitCode && env->executablePath) { + exitCode = _registryReadString(&env->executableArgs, root, L"InstallPath", L"WindowedExecutableArguments"); + } + } + if (exitCode) { + return exitCode; + } + + // Missing windowed path or non-windowed request means we use ExecutablePath + if (!env->executablePath) { + exitCode = _registryReadString(&env->executablePath, root, L"InstallPath", L"ExecutablePath"); + if (!exitCode && env->executablePath) { + exitCode = _registryReadString(&env->executableArgs, root, L"InstallPath", L"ExecutableArguments"); + } + } + if (exitCode) { + return exitCode; + } + + exitCode = _registryReadString(&env->architecture, root, NULL, L"SysArchitecture"); + if (exitCode) { + return exitCode; + } + + exitCode = _registryReadString(&env->displayName, root, NULL, L"DisplayName"); + if (exitCode) { + return exitCode; + } + + // Only PythonCore entries will infer executablePath from installDir and architecture from the binary + if (0 == _compare(env->company, -1, L"PythonCore", -1)) { + if (!env->executablePath) { + exitCode = _combineWithInstallDir( + &env->executablePath, + env->installDir, + search->executable, + search->executableLength + ); + if (exitCode) { + return exitCode; + } + } + if (!env->architecture && env->executablePath && fallbackArch) { + copyWstr(&env->architecture, fallbackArch); + } + } + + if (!env->executablePath) { + debug(L"# %s/%s has no executable path\n", env->company, env->tag); + return RC_NO_PYTHON; + } + + return 0; +} + +int +_registrySearchTags(const SearchInfo *search, EnvironmentInfo **result, HKEY root, int sortKey, const wchar_t *company, const wchar_t *fallbackArch) +{ + wchar_t buffer[256]; + int err = 0; + int exitCode = 0; + for (int i = 0; exitCode == 0; ++i) { + DWORD cchBuffer = sizeof(buffer) / sizeof(buffer[0]); + err = RegEnumKeyExW(root, i, buffer, &cchBuffer, NULL, NULL, NULL, NULL); + if (err) { + if (err != ERROR_NO_MORE_ITEMS) { + winerror(0, L"Failed to read installs (tags) from the registry"); + } + break; + } + HKEY subkey; + if (ERROR_SUCCESS == RegOpenKeyExW(root, buffer, 0, KEY_READ, &subkey)) { + EnvironmentInfo *env = newEnvironmentInfo(company, buffer); + env->internalSortKey = sortKey; + exitCode = _registryReadEnvironment(search, subkey, env, fallbackArch); + RegCloseKey(subkey); + if (exitCode == RC_NO_PYTHON) { + freeEnvironmentInfo(env); + exitCode = 0; + } else if (!exitCode) { + exitCode = addEnvironmentInfo(result, env); + if (exitCode == RC_DUPLICATE_ITEM) { + exitCode = 0; + } else if (exitCode) { + freeEnvironmentInfo(env); + } + } + } + } + return exitCode; +} + + +int +registrySearch(const SearchInfo *search, EnvironmentInfo **result, HKEY root, int sortKey, const wchar_t *fallbackArch) +{ + wchar_t buffer[256]; + int err = 0; + int exitCode = 0; + for (int i = 0; exitCode == 0; ++i) { + DWORD cchBuffer = sizeof(buffer) / sizeof(buffer[0]); + err = RegEnumKeyExW(root, i, buffer, &cchBuffer, NULL, NULL, NULL, NULL); + if (err) { + if (err != ERROR_NO_MORE_ITEMS) { + winerror(0, L"Failed to read distributors (company) from the registry"); + } + break; + } + HKEY subkey; + if (ERROR_SUCCESS == RegOpenKeyExW(root, buffer, 0, KEY_READ, &subkey)) { + exitCode = _registrySearchTags(search, result, subkey, sortKey, buffer, fallbackArch); + RegCloseKey(subkey); + } + } + return exitCode; +} + + +/******************************************************************************\ + *** APP PACKAGE SEARCH *** +\******************************************************************************/ + +int +appxSearch(const SearchInfo *search, EnvironmentInfo **result, const wchar_t *packageFamilyName, const wchar_t *tag, int sortKey) +{ + wchar_t realTag[32]; + wchar_t buffer[MAXLEN]; + const wchar_t *exeName = search->executable; + if (!exeName || search->allowExecutableOverride) { + exeName = search->windowed ? L"pythonw.exe" : L"python.exe"; + } + + if (FAILED(SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, buffer)) || + !join(buffer, MAXLEN, L"Microsoft\\WindowsApps") || + !join(buffer, MAXLEN, packageFamilyName) || + !join(buffer, MAXLEN, exeName)) { + return RC_INTERNAL_ERROR; + } + + if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW(buffer)) { + return RC_NO_PYTHON; + } + + // Assume packages are native architecture, which means we need to append + // the '-arm64' on ARM64 host. + wcscpy_s(realTag, 32, tag); + if (isARM64Host()) { + wcscat_s(realTag, 32, L"-arm64"); + } + + EnvironmentInfo *env = newEnvironmentInfo(L"PythonCore", realTag); + if (!env) { + return RC_NO_MEMORY; + } + env->internalSortKey = sortKey; + if (isAMD64Host()) { + copyWstr(&env->architecture, L"64bit"); + } else if (isARM64Host()) { + copyWstr(&env->architecture, L"ARM64"); + } + + copyWstr(&env->executablePath, buffer); + + if (swprintf_s(buffer, MAXLEN, L"Python %s (Store)", tag)) { + copyWstr(&env->displayName, buffer); + } + + int exitCode = addEnvironmentInfo(result, env); + if (exitCode == RC_DUPLICATE_ITEM) { + exitCode = 0; + } else if (exitCode) { + freeEnvironmentInfo(env); + } + + + return exitCode; +} + + +/******************************************************************************\ + *** COLLECT ENVIRONMENTS *** +\******************************************************************************/ + + +struct RegistrySearchInfo { + // Registry subkey to search + const wchar_t *subkey; + // Registry hive to search + HKEY hive; + // Flags to use when opening the subkey + DWORD flags; + // Internal sort key to select between "identical" environments discovered + // through different methods + int sortKey; + // Fallback value to assume for PythonCore entries missing a SysArchitecture value + const wchar_t *fallbackArch; +}; + + +struct RegistrySearchInfo REGISTRY_SEARCH[] = { + { + L"Software\\Python", + HKEY_CURRENT_USER, + KEY_READ, + 1, + NULL + }, + { + L"Software\\Python", + HKEY_LOCAL_MACHINE, + KEY_READ | KEY_WOW64_64KEY, + 3, + L"64bit" + }, + { + L"Software\\Python", + HKEY_LOCAL_MACHINE, + KEY_READ | KEY_WOW64_32KEY, + 4, + L"32bit" + }, + { NULL, 0, 0, 0, NULL } +}; + + +struct AppxSearchInfo { + // The package family name. Can be found for an installed package using the + // Powershell "Get-AppxPackage" cmdlet + const wchar_t *familyName; + // The tag to treat the installation as + const wchar_t *tag; + // Internal sort key to select between "identical" environments discovered + // through different methods + int sortKey; +}; + + +struct AppxSearchInfo APPX_SEARCH[] = { + // Releases made through the Store + { L"PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0", L"3.11", 10 }, + { L"PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0", L"3.10", 10 }, + { L"PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0", L"3.9", 10 }, + { L"PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0", L"3.8", 10 }, + + // Side-loadable releases. Note that the publisher ID changes whenever we + // renew our code-signing certificate, so the newer ID has a higher + // priority (lower sortKey) + { L"PythonSoftwareFoundation.Python.3.11_3847v3x7pw1km", L"3.11", 11 }, + { L"PythonSoftwareFoundation.Python.3.11_hd69rhyc2wevp", L"3.11", 12 }, + { L"PythonSoftwareFoundation.Python.3.10_3847v3x7pw1km", L"3.10", 11 }, + { L"PythonSoftwareFoundation.Python.3.10_hd69rhyc2wevp", L"3.10", 12 }, + { L"PythonSoftwareFoundation.Python.3.9_3847v3x7pw1km", L"3.9", 11 }, + { L"PythonSoftwareFoundation.Python.3.9_hd69rhyc2wevp", L"3.9", 12 }, + { L"PythonSoftwareFoundation.Python.3.8_hd69rhyc2wevp", L"3.8", 12 }, + { NULL, NULL, 0 } +}; + + +int +collectEnvironments(const SearchInfo *search, EnvironmentInfo **result) +{ + int exitCode = 0; + EnvironmentInfo *env = NULL; + if (!result) { + return RC_INTERNAL_ERROR; + } + *result = NULL; + + if (search->executablePath) { + env = newEnvironmentInfo(NULL, NULL); + return copyWstr(&env->executablePath, search->executablePath); + } + + HKEY root; + + for (struct RegistrySearchInfo *info = REGISTRY_SEARCH; info->subkey; ++info) { + if (ERROR_SUCCESS == RegOpenKeyExW(info->hive, info->subkey, 0, info->flags, &root)) { + exitCode = registrySearch(search, result, root, info->sortKey, info->fallbackArch); + RegCloseKey(root); + } + if (exitCode) { + return exitCode; + } + } + + for (struct AppxSearchInfo *info = APPX_SEARCH; info->familyName; ++info) { + exitCode = appxSearch(search, result, info->familyName, info->tag, info->sortKey); + if (exitCode && exitCode != RC_NO_PYTHON) { + return exitCode; + } + } + + return 0; +} + + +/******************************************************************************\ + *** INSTALL ON DEMAND *** +\******************************************************************************/ + +struct StoreSearchInfo { + // The tag a user is looking for + const wchar_t *tag; + // The Store ID for a package if it can be installed from the Microsoft + // Store. These are obtained from the dashboard at + // https://partner.microsoft.com/dashboard + const wchar_t *storeId; +}; + + +struct StoreSearchInfo STORE_SEARCH[] = { + { L"3", /* 3.10 */ L"9PJPW5LDXLZ5" }, + { L"3.11", L"9NRWMJP3717K" }, + { L"3.10", L"9PJPW5LDXLZ5" }, + { L"3.9", L"9P7QFQMJRFP7" }, + { L"3.8", L"9MSSZTT1N39L" }, + { NULL, NULL } +}; + + +int +_installEnvironment(const wchar_t *command, const wchar_t *arguments) +{ + SHELLEXECUTEINFOW siw = { + sizeof(SHELLEXECUTEINFOW), + SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NO_CONSOLE, + NULL, NULL, + command, arguments, NULL, + SW_SHOWNORMAL + }; + + debug(L"# Installing with %s %s\n", command, arguments); + if (isEnvVarSet(L"PYLAUNCHER_DRYRUN")) { + debug(L"# Exiting due to PYLAUNCHER_DRYRUN\n"); + fflush(stdout); + int mode = _setmode(_fileno(stdout), _O_U8TEXT); + if (arguments) { + fwprintf_s(stdout, L"\"%s\" %s\n", command, arguments); + } else { + fwprintf_s(stdout, L"\"%s\"\n", command); + } + fflush(stdout); + if (mode >= 0) { + _setmode(_fileno(stdout), mode); + } + return RC_INSTALLING; + } + + if (!ShellExecuteExW(&siw)) { + return RC_NO_PYTHON; + } + + if (!siw.hProcess) { + return RC_INSTALLING; + } + + WaitForSingleObjectEx(siw.hProcess, INFINITE, FALSE); + DWORD exitCode = 0; + if (GetExitCodeProcess(siw.hProcess, &exitCode) && exitCode == 0) { + return 0; + } + return RC_INSTALLING; +} + + +const wchar_t *WINGET_COMMAND = L"Microsoft\\WindowsApps\\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\\winget.exe"; +const wchar_t *WINGET_ARGUMENTS = L"install -q %s --exact --accept-package-agreements --source msstore"; + +const wchar_t *MSSTORE_COMMAND = L"ms-windows-store://pdp/?productid=%s"; + +int +installEnvironment(const SearchInfo *search) +{ + // No tag? No installing + if (!search->tag || !search->tagLength) { + debug(L"# Cannot install Python with no tag specified\n"); + return RC_NO_PYTHON; + } + + // PEP 514 tag but not PythonCore? No installing + if (!search->oldStyleTag && + search->company && search->companyLength && + 0 != _compare(search->company, search->companyLength, L"PythonCore", -1)) { + debug(L"# Cannot install for company %.*s\n", search->companyLength, search->company); + return RC_NO_PYTHON; + } + + const wchar_t *storeId = NULL; + for (struct StoreSearchInfo *info = STORE_SEARCH; info->tag; ++info) { + if (0 == _compare(search->tag, search->tagLength, info->tag, -1)) { + storeId = info->storeId; + break; + } + } + + if (!storeId) { + return RC_NO_PYTHON; + } + + int exitCode; + wchar_t command[MAXLEN]; + wchar_t arguments[MAXLEN]; + if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, command)) && + join(command, MAXLEN, WINGET_COMMAND) && + swprintf_s(arguments, MAXLEN, WINGET_ARGUMENTS, storeId)) { + if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW(command)) { + formatWinerror(GetLastError(), arguments, MAXLEN); + debug(L"# Skipping %s: %s\n", command, arguments); + } else { + fputws(L"Launching winget to install Python. The following output is from the install process\n\ +***********************************************************************\n", stdout); + exitCode = _installEnvironment(command, arguments); + if (exitCode == RC_INSTALLING) { + fputws(L"***********************************************************************\n\ +Please check the install status and run your command again.", stderr); + return exitCode; + } else if (exitCode) { + return exitCode; + } + fputws(L"***********************************************************************\n\ +Install appears to have succeeded. Searching for new matching installs.\n", stdout); + return 0; + } + } + + if (swprintf_s(command, MAXLEN, MSSTORE_COMMAND, storeId)) { + fputws(L"Opening the Microsoft Store to install Python. After installation, " + L"please run your command again.\n", stderr); + exitCode = _installEnvironment(command, NULL); + if (exitCode) { + return exitCode; + } + return 0; + } + + return RC_NO_PYTHON; +} + +/******************************************************************************\ + *** ENVIRONMENT SELECT *** +\******************************************************************************/ + +bool +_companyMatches(const SearchInfo *search, const EnvironmentInfo *env) +{ + if (!search->company || !search->companyLength) { + return true; + } + return 0 == _compare(env->company, -1, search->company, search->companyLength); +} + + +bool +_tagMatches(const SearchInfo *search, const EnvironmentInfo *env) +{ + if (!search->tag || !search->tagLength) { + return true; + } + return _startsWith(env->tag, -1, search->tag, search->tagLength); +} + + +bool +_is32Bit(const EnvironmentInfo *env) +{ + if (env->architecture) { + return 0 == _compare(env->architecture, -1, L"32bit", -1); + } + return false; +} + + +int +_selectEnvironment(const SearchInfo *search, EnvironmentInfo *env, EnvironmentInfo **best) +{ + int exitCode = 0; + while (env) { + exitCode = _selectEnvironment(search, env->prev, best); + + if (exitCode && exitCode != RC_NO_PYTHON) { + return exitCode; + } else if (!exitCode && *best) { + return 0; + } + + if (!search->oldStyleTag) { + if (_companyMatches(search, env) && _tagMatches(search, env)) { + // Because of how our sort tree is set up, we will walk up the + // "prev" side and implicitly select the "best" best. By + // returning straight after a match, we skip the entire "next" + // branch and won't ever select a "worse" best. + *best = env; + return 0; + } + } else if (0 == _compare(env->company, -1, L"PythonCore", -1)) { + // Old-style tags can only match PythonCore entries + if (_startsWith(env->tag, -1, search->tag, search->tagLength)) { + if (search->exclude32Bit && _is32Bit(env)) { + debug(L"# Excluding %s/%s because it looks like 32bit\n", env->company, env->tag); + } else if (search->only32Bit && !_is32Bit(env)) { + debug(L"# Excluding %s/%s because it doesn't look 32bit\n", env->company, env->tag); + } else { + *best = env; + return 0; + } + } + } + + env = env->next; + } + return RC_NO_PYTHON; +} + +int +selectEnvironment(const SearchInfo *search, EnvironmentInfo *root, EnvironmentInfo **best) +{ + if (!best) { + return RC_INTERNAL_ERROR; + } + if (!root) { + *best = NULL; + return RC_NO_PYTHON_AT_ALL; + } + if (!root->next && !root->prev) { + *best = root; + return 0; + } + + EnvironmentInfo *result = NULL; + int exitCode = _selectEnvironment(search, root, &result); + if (!exitCode) { + *best = result; + } + + return exitCode; +} + + +/******************************************************************************\ + *** LIST ENVIRONMENTS *** +\******************************************************************************/ + +#define TAGWIDTH 16 + +int +_printEnvironment(const EnvironmentInfo *env, FILE *out, bool showPath, const wchar_t *argument) +{ + if (showPath) { + if (env->executablePath && env->executablePath[0]) { + if (env->executableArgs && env->executableArgs[0]) { + fwprintf(out, L" %-*s %s %s\n", TAGWIDTH, argument, env->executablePath, env->executableArgs); + } else { + fwprintf(out, L" %-*s %s\n", TAGWIDTH, argument, env->executablePath); + } + } else if (env->installDir && env->installDir[0]) { + fwprintf(out, L" %-*s %s\n", TAGWIDTH, argument, env->installDir); + } else { + fwprintf(out, L" %s\n", argument); + } + } else if (env->displayName) { + fwprintf(out, L" %-*s %s\n", TAGWIDTH, argument, env->displayName); + } else { + fwprintf(out, L" %s\n", argument); + } + return 0; +} + + +int +_listAllEnvironments(EnvironmentInfo *env, FILE * out, bool showPath, bool *isDefault) +{ + wchar_t buffer[256]; + while (env) { + int exitCode = _listAllEnvironments(env->prev, out, showPath, isDefault); + if (exitCode) { + return exitCode; + } + + if (!env->company || !env->tag) { + buffer[0] = L'\0'; + } else if (0 == _compare(env->company, -1, L"PythonCore", -1)) { + swprintf_s(buffer, sizeof(buffer) / sizeof(buffer[0]), L"-V:%s", env->tag); + } else { + swprintf_s(buffer, sizeof(buffer) / sizeof(buffer[0]), L"-V:%s/%s", env->company, env->tag); + } + if (buffer[0]) { + if (*isDefault) { + wcscat_s(buffer, sizeof(buffer) / sizeof(buffer[0]), L" *"); + *isDefault = false; + } + exitCode = _printEnvironment(env, out, showPath, buffer); + if (exitCode) { + return exitCode; + } + } + + env = env->next; + } + return 0; +} + + +int +listEnvironments(EnvironmentInfo *env, FILE * out, bool showPath) +{ + bool isDefault = true; + + if (!env) { + fwprintf_s(stdout, L"No installed Pythons found!\n"); + return 0; + } + + /* TODO: Do we want to display these? + In favour, helps users see that '-3' is a good option + Against, repeats the next line of output + SearchInfo majorSearch; + EnvironmentInfo *major; + int exitCode; + + if (showPath) { + memset(&majorSearch, 0, sizeof(majorSearch)); + majorSearch.company = L"PythonCore"; + majorSearch.companyLength = -1; + majorSearch.tag = L"3"; + majorSearch.tagLength = -1; + majorSearch.oldStyleTag = true; + major = NULL; + exitCode = selectEnvironment(&majorSearch, env, &major); + if (!exitCode && major) { + exitCode = _printEnvironment(major, out, showPath, L"-3 *"); + isDefault = false; + if (exitCode) { + return exitCode; + } + } + majorSearch.tag = L"2"; + major = NULL; + exitCode = selectEnvironment(&majorSearch, env, &major); + if (!exitCode && major) { + exitCode = _printEnvironment(major, out, showPath, L"-2"); + if (exitCode) { + return exitCode; + } + } + } + */ + + int mode = _setmode(_fileno(out), _O_U8TEXT); + int exitCode = _listAllEnvironments(env, out, showPath, &isDefault); + fflush(out); + if (mode >= 0) { + _setmode(_fileno(out), mode); + } + return exitCode; +} + + +/******************************************************************************\ + *** INTERPRETER LAUNCH *** +\******************************************************************************/ + + +int +calculateCommandLine(const SearchInfo *search, const EnvironmentInfo *launch, wchar_t *buffer, int bufferLength) +{ + int exitCode = 0; + const wchar_t *executablePath = NULL; + + // Construct command line from a search override, or else the selected + // environment's executablePath + if (search->executablePath) { + executablePath = search->executablePath; + } else if (launch && launch->executablePath) { + executablePath = launch->executablePath; + } + + // If we have an executable path, put it at the start of the command, but + // only if the search allowed an override. + // Otherwise, use the environment's installDir and the search's default + // executable name. + if (executablePath && search->allowExecutableOverride) { + if (wcschr(executablePath, L' ') && executablePath[0] != L'"') { + buffer[0] = L'"'; + exitCode = wcscpy_s(&buffer[1], bufferLength - 1, executablePath); + if (!exitCode) { + exitCode = wcscat_s(buffer, bufferLength, L"\""); + } + } else { + exitCode = wcscpy_s(buffer, bufferLength, executablePath); + } + } else if (launch) { + if (!launch->installDir) { + fwprintf_s(stderr, L"Cannot launch %s %s because no install directory was specified", + launch->company, launch->tag); + exitCode = RC_NO_PYTHON; + } else if (!search->executable || !search->executableLength) { + fwprintf_s(stderr, L"Cannot launch %s %s because no executable name is available", + launch->company, launch->tag); + exitCode = RC_NO_PYTHON; + } else { + wchar_t executable[256]; + wcsncpy_s(executable, 256, search->executable, search->executableLength); + if ((wcschr(launch->installDir, L' ') && launch->installDir[0] != L'"') || + (wcschr(executable, L' ') && executable[0] != L'"')) { + buffer[0] = L'"'; + exitCode = wcscpy_s(&buffer[1], bufferLength - 1, launch->installDir); + if (!exitCode) { + exitCode = join(buffer, bufferLength, executable) ? 0 : RC_NO_MEMORY; + } + if (!exitCode) { + exitCode = wcscat_s(buffer, bufferLength, L"\""); + } + } else { + exitCode = wcscpy_s(buffer, bufferLength, launch->installDir); + if (!exitCode) { + exitCode = join(buffer, bufferLength, executable) ? 0 : RC_NO_MEMORY; + } + } + } + } else { + exitCode = RC_NO_PYTHON; + } + + if (!exitCode && launch && launch->executableArgs) { + exitCode = wcscat_s(buffer, bufferLength, L" "); + if (!exitCode) { + exitCode = wcscat_s(buffer, bufferLength, launch->executableArgs); + } + } + + if (!exitCode && search->executableArgs) { + if (search->executableArgsLength < 0) { + exitCode = wcscat_s(buffer, bufferLength, search->executableArgs); + } else if (search->executableArgsLength > 0) { + int end = (int)wcsnlen_s(buffer, MAXLEN); + if (end < bufferLength - (search->executableArgsLength + 1)) { + exitCode = wcsncpy_s(&buffer[end], bufferLength - end, + search->executableArgs, search->executableArgsLength); + } + } + } + + if (!exitCode && search->restOfCmdLine) { + exitCode = wcscat_s(buffer, bufferLength, search->restOfCmdLine); + } + + return exitCode; +} + + + +BOOL +_safeDuplicateHandle(HANDLE in, HANDLE * pout, const wchar_t *nameForError) +{ + BOOL ok; + HANDLE process = GetCurrentProcess(); + DWORD rc; + + *pout = NULL; + ok = DuplicateHandle(process, in, process, pout, 0, TRUE, + DUPLICATE_SAME_ACCESS); + if (!ok) { + rc = GetLastError(); + if (rc == ERROR_INVALID_HANDLE) { + debug(L"DuplicateHandle returned ERROR_INVALID_HANDLE\n"); + ok = TRUE; + } + else { + winerror(0, L"Failed to duplicate %s handle", nameForError); + } + } + return ok; +} + +BOOL WINAPI +ctrl_c_handler(DWORD code) +{ + return TRUE; /* We just ignore all control events. */ +} + + +int +launchEnvironment(const SearchInfo *search, const EnvironmentInfo *launch, wchar_t *launchCommand) +{ + HANDLE job; + JOBOBJECT_EXTENDED_LIMIT_INFORMATION info; + DWORD rc; + BOOL ok; + STARTUPINFOW si; + PROCESS_INFORMATION pi; + + // If this is a dryrun, do not actually launch + if (isEnvVarSet(L"PYLAUNCHER_DRYRUN")) { + debug(L"LaunchCommand: %s\n", launchCommand); + debug(L"# Exiting due to PYLAUNCHER_DRYRUN variable\n"); + fflush(stdout); + int mode = _setmode(_fileno(stdout), _O_U8TEXT); + fwprintf(stdout, L"%s\n", launchCommand); + fflush(stdout); + if (mode >= 0) { + _setmode(_fileno(stdout), mode); + } + return 0; + } + +#if defined(_WINDOWS) + /* + When explorer launches a Windows (GUI) application, it displays + the "app starting" (the "pointer + hourglass") cursor for a number + of seconds, or until the app does something UI-ish (eg, creating a + window, or fetching a message). As this launcher doesn't do this + directly, that cursor remains even after the child process does these + things. We avoid that by doing a simple post+get message. + See http://bugs.python.org/issue17290 and + https://bitbucket.org/vinay.sajip/pylauncher/issue/20/busy-cursor-for-a-long-time-when-running + */ + MSG msg; + + PostMessage(0, 0, 0, 0); + GetMessage(&msg, 0, 0, 0); +#endif + + debug(L"# about to run: %s\n", launchCommand); + job = CreateJobObject(NULL, NULL); + ok = QueryInformationJobObject(job, JobObjectExtendedLimitInformation, + &info, sizeof(info), &rc); + if (!ok || (rc != sizeof(info)) || !job) { + winerror(0, L"Failed to query job information"); + return RC_CREATE_PROCESS; + } + info.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | + JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK; + ok = SetInformationJobObject(job, JobObjectExtendedLimitInformation, &info, + sizeof(info)); + if (!ok) { + winerror(0, L"Failed to update job information"); + return RC_CREATE_PROCESS; + } + memset(&si, 0, sizeof(si)); + GetStartupInfoW(&si); + if (!_safeDuplicateHandle(GetStdHandle(STD_INPUT_HANDLE), &si.hStdInput, L"stdin") || + !_safeDuplicateHandle(GetStdHandle(STD_OUTPUT_HANDLE), &si.hStdOutput, L"stdout") || + !_safeDuplicateHandle(GetStdHandle(STD_ERROR_HANDLE), &si.hStdError, L"stderr")) { + return RC_NO_STD_HANDLES; + } + + ok = SetConsoleCtrlHandler(ctrl_c_handler, TRUE); + if (!ok) { + winerror(0, L"Failed to update Control-C handler"); + return RC_NO_STD_HANDLES; + } + + si.dwFlags = STARTF_USESTDHANDLES; + ok = CreateProcessW(NULL, launchCommand, NULL, NULL, TRUE, + 0, NULL, NULL, &si, &pi); + if (!ok) { + winerror(0, L"Unable to create process using '%s'", launchCommand); + return RC_CREATE_PROCESS; + } + AssignProcessToJobObject(job, pi.hProcess); + CloseHandle(pi.hThread); + WaitForSingleObjectEx(pi.hProcess, INFINITE, FALSE); + ok = GetExitCodeProcess(pi.hProcess, &rc); + if (!ok) { + winerror(0, L"Failed to get exit code of process"); + return RC_CREATE_PROCESS; + } + debug(L"child process exit code: %d\n", rc); + return rc; +} + + +/******************************************************************************\ + *** PROCESS CONTROLLER *** +\******************************************************************************/ + + +int +performSearch(SearchInfo *search, EnvironmentInfo **envs) +{ + // First parse the command line for options + int exitCode = parseCommandLine(search); + if (exitCode) { + return exitCode; + } + + // Check for a shebang line in our script file + // (or return quickly if no script file was specified) + exitCode = checkShebang(search); + if (exitCode) { + return exitCode; + } + + // Resolve old-style tags (possibly from a shebang) against py.ini entries + // and environment variables. + exitCode = checkDefaults(search); + if (exitCode) { + return exitCode; + } + + // If debugging is enabled, list our search criteria + dumpSearchInfo(search); + + // Find all matching environments + exitCode = collectEnvironments(search, envs); + if (exitCode) { + return exitCode; + } + + return 0; +} + + +int +process(int argc, wchar_t ** argv) +{ + int exitCode = 0; + SearchInfo search = {0}; + EnvironmentInfo *envs = NULL; + EnvironmentInfo *env = NULL; + wchar_t launchCommand[MAXLEN]; + + memset(launchCommand, 0, sizeof(launchCommand)); + + if (isEnvVarSet(L"PYLAUNCHER_DEBUG")) { + setvbuf(stderr, (char *)NULL, _IONBF, 0); + log_fp = stderr; + debug(L"argv0: %s\nversion: %S\n", argv[0], PY_VERSION); + } + + search.originalCmdLine = GetCommandLineW(); + + exitCode = performSearch(&search, &envs); + if (exitCode) { + goto abort; + } + + // Display the help text, but only exit on error + if (search.help) { + exitCode = showHelpText(argv); + if (exitCode) { + goto abort; + } + } + + // List all environments, then exit + if (search.list || search.listPaths) { + exitCode = listEnvironments(envs, stdout, search.listPaths); + goto abort; + } + + // When debugging, list all discovered environments anyway + if (log_fp) { + exitCode = listEnvironments(envs, log_fp, true); + if (exitCode) { + goto abort; + } + } + + // Select best environment + env = NULL; + if (search.executablePath == NULL) { + exitCode = selectEnvironment(&search, envs, &env); + // If none found, and if permitted, install it + if (exitCode == RC_NO_PYTHON && isEnvVarSet(L"PYLAUNCHER_ALLOW_INSTALL") || + isEnvVarSet(L"PYLAUNCHER_ALWAYS_INSTALL")) { + exitCode = installEnvironment(&search); + if (!exitCode) { + // Successful install, so we need to re-scan and select again + exitCode = performSearch(&search, &envs); + if (exitCode) { + goto abort; + } + env = NULL; + exitCode = selectEnvironment(&search, envs, &env); + } + } + if (exitCode == RC_NO_PYTHON) { + fputws(L"No suitable Python runtime found\n", stderr); + fputws(L"Pass --list (-0) to see all detected environments on your machine\n", stderr); + if (!isEnvVarSet(L"PYLAUNCHER_ALLOW_INSTALL") && search.oldStyleTag) { + fputws(L"or set environment variable PYLAUNCHER_ALLOW_INSTALL to use winget\n" + L"or open the Microsoft Store to the requested version.\n", stderr); + } + goto abort; + } + if (exitCode == RC_NO_PYTHON_AT_ALL) { + fputws(L"No installed Python found!\n", stderr); + goto abort; + } + if (exitCode) { + goto abort; + } + + if (env) { + debug(L"env.company: %s\nenv.tag: %s\n", env->company, env->tag); + } else { + debug(L"env.company: (null)\nenv.tag: (null)\n"); + } + } + + exitCode = calculateCommandLine(&search, env, launchCommand, sizeof(launchCommand) / sizeof(launchCommand[0])); + if (exitCode) { + goto abort; + } + + // Launch selected runtime + exitCode = launchEnvironment(&search, env, launchCommand); + +abort: + freeSearchInfo(&search); + freeEnvironmentInfo(envs); + return exitCode; +} + + +#if defined(_WINDOWS) + +int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + LPWSTR lpstrCmd, int nShow) +{ + return process(__argc, __wargv); +} + +#else + +int cdecl wmain(int argc, wchar_t ** argv) +{ + return process(argc, argv); +} + +#endif diff --git a/PC/pylauncher.rc b/PC/pylauncher.rc index ff7e71e0fdb4e..11862643aa698 100644 --- a/PC/pylauncher.rc +++ b/PC/pylauncher.rc @@ -25,6 +25,9 @@ 7 ICON DISCARDABLE "icons\setup.ico" #endif +1 USAGE "launcher-usage.txt" + + ///////////////////////////////////////////////////////////////////////////// // // Version diff --git a/PCbuild/pylauncher.vcxproj b/PCbuild/pylauncher.vcxproj index 550e0842300fb..35f2f7e505bf9 100644 --- a/PCbuild/pylauncher.vcxproj +++ b/PCbuild/pylauncher.vcxproj @@ -76,7 +76,7 @@ Application - MultiByte + Unicode @@ -95,12 +95,12 @@ MultiThreaded - version.lib;%(AdditionalDependencies) + shell32.lib;pathcch.lib;%(AdditionalDependencies) Console - + diff --git a/PCbuild/pywlauncher.vcxproj b/PCbuild/pywlauncher.vcxproj index 44e3fc2927235..e50b69aefe2b9 100644 --- a/PCbuild/pywlauncher.vcxproj +++ b/PCbuild/pywlauncher.vcxproj @@ -95,12 +95,12 @@ MultiThreaded - version.lib;%(AdditionalDependencies) + shell32.lib;pathcch.lib;%(AdditionalDependencies) Windows - + diff --git a/Tools/msi/launcher/launcher.wixproj b/Tools/msi/launcher/launcher.wixproj index 7ff169029e4fe..de770bdd3006c 100644 --- a/Tools/msi/launcher/launcher.wixproj +++ b/Tools/msi/launcher/launcher.wixproj @@ -8,6 +8,7 @@ UpgradeCode=1B68A0EC-4DD3-5134-840E-73854B0863F1;SuppressUpgradeTable=1;$(DefineConstants) true ICE80 + <_Rebuild>Build @@ -18,18 +19,27 @@ - - - + + + + <_Rebuild>Rebuild + + + + + + + + - - + + - - + + - - + + diff --git a/Tools/msi/launcher/launcher_files.wxs b/Tools/msi/launcher/launcher_files.wxs index 5b79d76bdfe67..2c6c808137a6f 100644 --- a/Tools/msi/launcher/launcher_files.wxs +++ b/Tools/msi/launcher/launcher_files.wxs @@ -33,6 +33,15 @@ + From webhook-mailer at python.org Mon Mar 28 19:46:26 2022 From: webhook-mailer at python.org (zooba) Date: Mon, 28 Mar 2022 23:46:26 -0000 Subject: [Python-checkins] bpo-47138: Ensure Windows docs build uses the same pinned version as other platforms (GH-32161) Message-ID: https://github.com/python/cpython/commit/0dfabf9b4a58b835b61fc3d17784d4746f677e56 commit: 0dfabf9b4a58b835b61fc3d17784d4746f677e56 branch: 3.10 author: Steve Dower committer: zooba date: 2022-03-29T00:46:18+01:00 summary: bpo-47138: Ensure Windows docs build uses the same pinned version as other platforms (GH-32161) files: M Doc/make.bat diff --git a/Doc/make.bat b/Doc/make.bat index 7fde063642771..ac66b56e9a3ef 100644 --- a/Doc/make.bat +++ b/Doc/make.bat @@ -13,7 +13,7 @@ if not defined SPHINXBUILD ( %PYTHON% -c "import sphinx" > nul 2> nul if errorlevel 1 ( echo Installing sphinx with %PYTHON% - %PYTHON% -m pip install sphinx==2.2.0 + %PYTHON% -m pip install -r requirements.txt if errorlevel 1 exit /B ) set SPHINXBUILD=%PYTHON% -c "import sphinx.cmd.build, sys; sys.exit(sphinx.cmd.build.main())" @@ -30,6 +30,7 @@ if not defined BLURB ( %PYTHON% -c "import blurb" > nul 2> nul if errorlevel 1 ( echo Installing blurb with %PYTHON% + rem Should have been installed with Sphinx earlier %PYTHON% -m pip install blurb if errorlevel 1 exit /B ) From webhook-mailer at python.org Mon Mar 28 20:10:54 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 29 Mar 2022 00:10:54 -0000 Subject: [Python-checkins] bpo-47138: Ensure Windows docs build uses the same pinned version as other platforms (GH-32161) Message-ID: https://github.com/python/cpython/commit/d2c6a4428d52c108f4b06dcd1bb86023541c60ce commit: d2c6a4428d52c108f4b06dcd1bb86023541c60ce branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-28T17:10:30-07:00 summary: bpo-47138: Ensure Windows docs build uses the same pinned version as other platforms (GH-32161) (cherry picked from commit 0dfabf9b4a58b835b61fc3d17784d4746f677e56) Co-authored-by: Steve Dower files: M Doc/make.bat diff --git a/Doc/make.bat b/Doc/make.bat index 7fde063642771..ac66b56e9a3ef 100644 --- a/Doc/make.bat +++ b/Doc/make.bat @@ -13,7 +13,7 @@ if not defined SPHINXBUILD ( %PYTHON% -c "import sphinx" > nul 2> nul if errorlevel 1 ( echo Installing sphinx with %PYTHON% - %PYTHON% -m pip install sphinx==2.2.0 + %PYTHON% -m pip install -r requirements.txt if errorlevel 1 exit /B ) set SPHINXBUILD=%PYTHON% -c "import sphinx.cmd.build, sys; sys.exit(sphinx.cmd.build.main())" @@ -30,6 +30,7 @@ if not defined BLURB ( %PYTHON% -c "import blurb" > nul 2> nul if errorlevel 1 ( echo Installing blurb with %PYTHON% + rem Should have been installed with Sphinx earlier %PYTHON% -m pip install blurb if errorlevel 1 exit /B ) From webhook-mailer at python.org Mon Mar 28 22:07:20 2022 From: webhook-mailer at python.org (sweeneyde) Date: Tue, 29 Mar 2022 02:07:20 -0000 Subject: [Python-checkins] bpo-47053: Refactor BINARY_OP_INPLACE_ADD_UNICODE (GH-32122) Message-ID: https://github.com/python/cpython/commit/788154919c2d843a0a995994bf2aed2d074761ec commit: 788154919c2d843a0a995994bf2aed2d074761ec branch: main author: Dennis Sweeney <36520290+sweeneyde at users.noreply.github.com> committer: sweeneyde <36520290+sweeneyde at users.noreply.github.com> date: 2022-03-28T22:07:05-04:00 summary: bpo-47053: Refactor BINARY_OP_INPLACE_ADD_UNICODE (GH-32122) files: M Python/ceval.c diff --git a/Python/ceval.c b/Python/ceval.c index 8b59f4233a7b2..4b9d33404bb78 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2003,28 +2003,32 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); _Py_CODEUNIT true_next = next_instr[INLINE_CACHE_ENTRIES_BINARY_OP]; - int next_oparg = _Py_OPARG(true_next); assert(_Py_OPCODE(true_next) == STORE_FAST || _Py_OPCODE(true_next) == STORE_FAST__LOAD_FAST); - /* In the common case, there are 2 references to the value - * stored in 'variable' when the v = v + ... is performed: one - * on the value stack (in 'v') and one still stored in the - * 'variable'. We try to delete the variable now to reduce - * the refcnt to 1. - */ - PyObject *var = GETLOCAL(next_oparg); - DEOPT_IF(var != left, BINARY_OP); + PyObject **target_local = &GETLOCAL(_Py_OPARG(true_next)); + DEOPT_IF(*target_local != left, BINARY_OP); STAT_INC(BINARY_OP, hit); - GETLOCAL(next_oparg) = NULL; + /* Handle `left = left + right` or `left += right` for str. + * + * When possible, extend `left` in place rather than + * allocating a new PyUnicodeObject. This attempts to avoid + * quadratic behavior when one neglects to use str.join(). + * + * If `left` has only two references remaining (one from + * the stack, one in the locals), DECREFing `left` leaves + * only the locals reference, so PyUnicode_Append knows + * that the string is safe to mutate. + */ assert(Py_REFCNT(left) >= 2); Py_DECREF(left); // XXX never need to dealloc - STACK_SHRINK(1); - PyUnicode_Append(&TOP(), right); + STACK_SHRINK(2); + PyUnicode_Append(target_local, right); Py_DECREF(right); - if (TOP() == NULL) { + if (*target_local == NULL) { goto error; } - JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP); + // The STORE_FAST is already done. + JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP + 1); NOTRACE_DISPATCH(); } From webhook-mailer at python.org Mon Mar 28 22:40:04 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Tue, 29 Mar 2022 02:40:04 -0000 Subject: [Python-checkins] [3.10] bpo-28516: document contextlib.ExitStack.__enter__ behavior (GH-31636) (GH-32171) Message-ID: https://github.com/python/cpython/commit/604d003ab4d1084ef828ebca1b28f2bf1b93c744 commit: 604d003ab4d1084ef828ebca1b28f2bf1b93c744 branch: 3.10 author: Jelle Zijlstra committer: JelleZijlstra date: 2022-03-28T19:39:55-07:00 summary: [3.10] bpo-28516: document contextlib.ExitStack.__enter__ behavior (GH-31636) (GH-32171) The enter_context is updated with following information: 'The :meth:`__enter__` method returns the ExitStack instance, and performs no additional operations.' Co-authored-by: Jelle Zijlstra (cherry picked from commit 86384cf83f96fcaec03e2ad6516e2e24f20d3b92) Co-authored-by: vidhya <96202776+Vidhyavinu at users.noreply.github.com> files: M Doc/library/contextlib.rst diff --git a/Doc/library/contextlib.rst b/Doc/library/contextlib.rst index b6ec6b8c876be..0fe3206540e80 100644 --- a/Doc/library/contextlib.rst +++ b/Doc/library/contextlib.rst @@ -485,6 +485,9 @@ Functions and classes provided: # the with statement, even if attempts to open files later # in the list raise an exception + The :meth:`__enter__` method returns the :class:`ExitStack` instance, and + performs no additional operations. + Each instance maintains a stack of registered callbacks that are called in reverse order when the instance is closed (either explicitly or implicitly at the end of a :keyword:`with` statement). Note that callbacks are *not* From webhook-mailer at python.org Mon Mar 28 22:40:42 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Tue, 29 Mar 2022 02:40:42 -0000 Subject: [Python-checkins] Fix typo in the sqlite3 docs (GH-31915) (GH-32158) Message-ID: https://github.com/python/cpython/commit/d6d170fa80f66876f913475ff96e8c344329b218 commit: d6d170fa80f66876f913475ff96e8c344329b218 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: JelleZijlstra date: 2022-03-28T19:40:38-07:00 summary: Fix typo in the sqlite3 docs (GH-31915) (GH-32158) Co-authored-by: Jonathan <89750679+AHypnotoad at users.noreply.github.com> (cherry picked from commit 66584c890d016e40d707400130d1cd98f2aedde9) Co-authored-by: Jonathan files: M Lib/sqlite3/__init__.py diff --git a/Lib/sqlite3/__init__.py b/Lib/sqlite3/__init__.py index 1e717450c29bf..34a9c047dd607 100644 --- a/Lib/sqlite3/__init__.py +++ b/Lib/sqlite3/__init__.py @@ -21,7 +21,7 @@ # 3. This notice may not be removed or altered from any source distribution. """ -The sqlite3 extension module provides a DB-API 2.0 (PEP 249) compilant +The sqlite3 extension module provides a DB-API 2.0 (PEP 249) compliant interface to the SQLite library, and requires SQLite 3.7.15 or newer. To use the module, start by creating a database Connection object: From webhook-mailer at python.org Mon Mar 28 22:47:45 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Tue, 29 Mar 2022 02:47:45 -0000 Subject: [Python-checkins] ctypes docs: Fix array-length reference to "non-negative" from "positive" (GH-32097) (GH-32143) Message-ID: https://github.com/python/cpython/commit/5f0305b383ab15eb19061e5aa069c224000fed4b commit: 5f0305b383ab15eb19061e5aa069c224000fed4b branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: JelleZijlstra date: 2022-03-28T19:47:37-07:00 summary: ctypes docs: Fix array-length reference to "non-negative" from "positive" (GH-32097) (GH-32143) (cherry picked from commit 76f14b0463dc2c53911eaf95e85374e511ba9bcc) Co-authored-by: Yonatan Goldschmidt Co-authored-by: Jelle Zijlstra files: M Doc/library/ctypes.rst diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index c10e54f153243..7665f214916db 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -2513,7 +2513,7 @@ Arrays and pointers Abstract base class for arrays. The recommended way to create concrete array types is by multiplying any - :mod:`ctypes` data type with a positive integer. Alternatively, you can subclass + :mod:`ctypes` data type with a non-negative integer. Alternatively, you can subclass this type and define :attr:`_length_` and :attr:`_type_` class variables. Array elements can be read and written using standard subscript and slice accesses; for slice reads, the resulting object is From webhook-mailer at python.org Mon Mar 28 22:48:01 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Tue, 29 Mar 2022 02:48:01 -0000 Subject: [Python-checkins] ctypes docs: Fix array-length reference to "non-negative" from "positive" (GH-32097) (GH-32142) Message-ID: https://github.com/python/cpython/commit/11408ff47e7b05b7979f7c5fa29567312960a16e commit: 11408ff47e7b05b7979f7c5fa29567312960a16e branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: JelleZijlstra date: 2022-03-28T19:47:57-07:00 summary: ctypes docs: Fix array-length reference to "non-negative" from "positive" (GH-32097) (GH-32142) (cherry picked from commit 76f14b0463dc2c53911eaf95e85374e511ba9bcc) Co-authored-by: Yonatan Goldschmidt Co-authored-by: Jelle Zijlstra files: M Doc/library/ctypes.rst diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index c10e54f153243..7665f214916db 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -2513,7 +2513,7 @@ Arrays and pointers Abstract base class for arrays. The recommended way to create concrete array types is by multiplying any - :mod:`ctypes` data type with a positive integer. Alternatively, you can subclass + :mod:`ctypes` data type with a non-negative integer. Alternatively, you can subclass this type and define :attr:`_length_` and :attr:`_type_` class variables. Array elements can be read and written using standard subscript and slice accesses; for slice reads, the resulting object is From webhook-mailer at python.org Tue Mar 29 00:21:36 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Tue, 29 Mar 2022 04:21:36 -0000 Subject: [Python-checkins] Fix typo in the sqlite3 docs (GH-31915) (GH-32157) Message-ID: https://github.com/python/cpython/commit/370900d7d8ba29eb52e419c3163599b4ac55f121 commit: 370900d7d8ba29eb52e419c3163599b4ac55f121 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: JelleZijlstra date: 2022-03-28T21:21:27-07:00 summary: Fix typo in the sqlite3 docs (GH-31915) (GH-32157) Co-authored-by: Jonathan <89750679+AHypnotoad at users.noreply.github.com> (cherry picked from commit 66584c890d016e40d707400130d1cd98f2aedde9) Co-authored-by: Jonathan Co-authored-by: Jelle Zijlstra files: M Lib/sqlite3/__init__.py diff --git a/Lib/sqlite3/__init__.py b/Lib/sqlite3/__init__.py index 0dedf186b1a1e..5a2dbd360fb49 100644 --- a/Lib/sqlite3/__init__.py +++ b/Lib/sqlite3/__init__.py @@ -21,7 +21,7 @@ # 3. This notice may not be removed or altered from any source distribution. """ -The sqlite3 extension module provides a DB-API 2.0 (PEP 249) compilant +The sqlite3 extension module provides a DB-API 2.0 (PEP 249) compliant interface to the SQLite library, and requires SQLite 3.7.15 or newer. To use the module, start by creating a database Connection object: From webhook-mailer at python.org Tue Mar 29 10:31:25 2022 From: webhook-mailer at python.org (serhiy-storchaka) Date: Tue, 29 Mar 2022 14:31:25 -0000 Subject: [Python-checkins] bpo-35859: Fix a few long-standing bugs in re engine (GH-12427) Message-ID: https://github.com/python/cpython/commit/356997cccc21a3391175d20e9ef03d434675b496 commit: 356997cccc21a3391175d20e9ef03d434675b496 branch: main author: Ma Lin committer: serhiy-storchaka date: 2022-03-29T17:31:01+03:00 summary: bpo-35859: Fix a few long-standing bugs in re engine (GH-12427) In rare cases, capturing group could get wrong result. Regular expression engines in Perl and Java have similar bugs. The new behavior now matches the behavior of more modern RE engines: in the regex module and in PHP, Ruby and Node.js. files: A Misc/NEWS.d/next/Library/2019-03-14-09-08-25.bpo-35859.8lFdLe.rst M Doc/whatsnew/3.11.rst M Lib/test/test_re.py M Modules/_sre.c M Modules/sre_lib.h diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 41e4659b0f779..837d8c8cbd016 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -718,6 +718,11 @@ Changes in the Python API deprecated since Python 3.6. (Contributed by Serhiy Storchaka in :issue:`47066`.) +* :mod:`re` module: Fix a few long-standing bugs where, in rare cases, + capturing group could get wrong result. So the result may be different than + before. + (Contributed by Ma Lin in :issue:`35859`.) + * The *population* parameter of :func:`random.sample` must be a sequence. Automatic conversion of sets to lists is no longer supported. If the sample size is larger than the population size, a :exc:`ValueError` is raised. diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index fd6db6a300d03..85716fbe2a8e8 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -2033,6 +2033,75 @@ def test_bug_34294(self): {'tag': 'foo', 'text': None}, {'tag': 'foo', 'text': None}]) + def test_MARK_PUSH_macro_bug(self): + # issue35859, MARK_PUSH() macro didn't protect MARK-0 if it + # was the only available mark. + self.assertEqual(re.match(r'(ab|a)*?b', 'ab').groups(), ('a',)) + self.assertEqual(re.match(r'(ab|a)+?b', 'ab').groups(), ('a',)) + self.assertEqual(re.match(r'(ab|a){0,2}?b', 'ab').groups(), ('a',)) + self.assertEqual(re.match(r'(.b|a)*?b', 'ab').groups(), ('a',)) + + def test_MIN_UNTIL_mark_bug(self): + # Fixed in issue35859, reported in issue9134. + # JUMP_MIN_UNTIL_2 should MARK_PUSH() if in a repeat + s = 'axxzbcz' + p = r'(?:(?:a|bc)*?(xx)??z)*' + self.assertEqual(re.match(p, s).groups(), ('xx',)) + + # test-case provided by issue9134 + s = 'xtcxyzxc' + p = r'((x|yz)+?(t)??c)*' + m = re.match(p, s) + self.assertEqual(m.span(), (0, 8)) + self.assertEqual(m.span(2), (6, 7)) + self.assertEqual(m.groups(), ('xyzxc', 'x', 't')) + + def test_REPEAT_ONE_mark_bug(self): + # issue35859 + # JUMP_REPEAT_ONE_1 should MARK_PUSH() if in a repeat + s = 'aabaab' + p = r'(?:[^b]*a(?=(b)|(a))ab)*' + m = re.match(p, s) + self.assertEqual(m.span(), (0, 6)) + self.assertEqual(m.span(2), (4, 5)) + self.assertEqual(m.groups(), (None, 'a')) + + # JUMP_REPEAT_ONE_2 should MARK_PUSH() if in a repeat + s = 'abab' + p = r'(?:[^b]*(?=(b)|(a))ab)*' + m = re.match(p, s) + self.assertEqual(m.span(), (0, 4)) + self.assertEqual(m.span(2), (2, 3)) + self.assertEqual(m.groups(), (None, 'a')) + + self.assertEqual(re.match(r'(ab?)*?b', 'ab').groups(), ('a',)) + + def test_MIN_REPEAT_ONE_mark_bug(self): + # issue35859 + # JUMP_MIN_REPEAT_ONE should MARK_PUSH() if in a repeat + s = 'abab' + p = r'(?:.*?(?=(a)|(b))b)*' + m = re.match(p, s) + self.assertEqual(m.span(), (0, 4)) + self.assertEqual(m.span(2), (3, 4)) + self.assertEqual(m.groups(), (None, 'b')) + + s = 'axxzaz' + p = r'(?:a*?(xx)??z)*' + self.assertEqual(re.match(p, s).groups(), ('xx',)) + + def test_ASSERT_NOT_mark_bug(self): + # Fixed in issue35859, reported in issue725149. + # JUMP_ASSERT_NOT should LASTMARK_SAVE() + self.assertEqual(re.match(r'(?!(..)c)', 'ab').groups(), (None,)) + + # JUMP_ASSERT_NOT should MARK_PUSH() if in a repeat + m = re.match(r'((?!(ab)c)(.))*', 'abab') + self.assertEqual(m.span(), (0, 4)) + self.assertEqual(m.span(1), (3, 4)) + self.assertEqual(m.span(3), (3, 4)) + self.assertEqual(m.groups(), ('b', None, 'b')) + def test_bug_40736(self): with self.assertRaisesRegex(TypeError, "got 'int'"): re.search("x*", 5) diff --git a/Misc/NEWS.d/next/Library/2019-03-14-09-08-25.bpo-35859.8lFdLe.rst b/Misc/NEWS.d/next/Library/2019-03-14-09-08-25.bpo-35859.8lFdLe.rst new file mode 100644 index 0000000000000..8c88ef01164e4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-03-14-09-08-25.bpo-35859.8lFdLe.rst @@ -0,0 +1,2 @@ +:mod:`re` module, fix a few bugs about capturing group. In rare cases, +capturing group gets an incorrect string. Patch by Ma Lin. diff --git a/Modules/_sre.c b/Modules/_sre.c index 35bdb4f3d2202..48193f82475a4 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -532,6 +532,14 @@ state_getslice(SRE_STATE* state, Py_ssize_t index, PyObject* string, int empty) } else { i = STATE_OFFSET(state, state->mark[index]); j = STATE_OFFSET(state, state->mark[index+1]); + + /* check wrong span */ + if (i > j) { + PyErr_SetString(PyExc_SystemError, + "The span of capturing group is wrong," + " please report a bug for the re module."); + return NULL; + } } return getslice(state->isbytes, state->beginning, string, i, j); @@ -2477,6 +2485,15 @@ pattern_new_match(_sremodulestate* module_state, if (j+1 <= state->lastmark && state->mark[j] && state->mark[j+1]) { match->mark[j+2] = ((char*) state->mark[j] - base) / n; match->mark[j+3] = ((char*) state->mark[j+1] - base) / n; + + /* check wrong span */ + if (match->mark[j+2] > match->mark[j+3]) { + PyErr_SetString(PyExc_SystemError, + "The span of capturing group is wrong," + " please report a bug for the re module."); + Py_DECREF(match); + return NULL; + } } else match->mark[j+2] = match->mark[j+3] = -1; /* undefined */ diff --git a/Modules/sre_lib.h b/Modules/sre_lib.h index a82210ff94a0f..8e4e714eada38 100644 --- a/Modules/sre_lib.h +++ b/Modules/sre_lib.h @@ -449,20 +449,20 @@ do { \ DATA_STACK_LOOKUP_AT(state,t,p,pos) #define MARK_PUSH(lastmark) \ - do if (lastmark > 0) { \ + do if (lastmark >= 0) { \ i = lastmark; /* ctx->lastmark may change if reallocated */ \ DATA_STACK_PUSH(state, state->mark, (i+1)*sizeof(void*)); \ } while (0) #define MARK_POP(lastmark) \ - do if (lastmark > 0) { \ + do if (lastmark >= 0) { \ DATA_STACK_POP(state, state->mark, (lastmark+1)*sizeof(void*), 1); \ } while (0) #define MARK_POP_KEEP(lastmark) \ - do if (lastmark > 0) { \ + do if (lastmark >= 0) { \ DATA_STACK_POP(state, state->mark, (lastmark+1)*sizeof(void*), 0); \ } while (0) #define MARK_POP_DISCARD(lastmark) \ - do if (lastmark > 0) { \ + do if (lastmark >= 0) { \ DATA_STACK_POP_DISCARD(state, (lastmark+1)*sizeof(void*)); \ } while (0) @@ -770,8 +770,7 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) /* <0=skip> code ... */ TRACE(("|%p|%p|BRANCH\n", ctx->pattern, ctx->ptr)); LASTMARK_SAVE(); - ctx->u.rep = state->repeat; - if (ctx->u.rep) + if (state->repeat) MARK_PUSH(ctx->lastmark); for (; ctx->pattern[0]; ctx->pattern += ctx->pattern[0]) { if (ctx->pattern[1] == SRE_OP_LITERAL && @@ -786,16 +785,16 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) state->ptr = ctx->ptr; DO_JUMP(JUMP_BRANCH, jump_branch, ctx->pattern+1); if (ret) { - if (ctx->u.rep) + if (state->repeat) MARK_POP_DISCARD(ctx->lastmark); RETURN_ON_ERROR(ret); RETURN_SUCCESS; } - if (ctx->u.rep) + if (state->repeat) MARK_POP_KEEP(ctx->lastmark); LASTMARK_RESTORE(); } - if (ctx->u.rep) + if (state->repeat) MARK_POP_DISCARD(ctx->lastmark); RETURN_FAILURE; @@ -841,6 +840,8 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) } LASTMARK_SAVE(); + if (state->repeat) + MARK_PUSH(ctx->lastmark); if (ctx->pattern[ctx->pattern[0]] == SRE_OP_LITERAL) { /* tail starts with a literal. skip positions where @@ -858,16 +859,20 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) DO_JUMP(JUMP_REPEAT_ONE_1, jump_repeat_one_1, ctx->pattern+ctx->pattern[0]); if (ret) { + if (state->repeat) + MARK_POP_DISCARD(ctx->lastmark); RETURN_ON_ERROR(ret); RETURN_SUCCESS; } - + if (state->repeat) + MARK_POP_KEEP(ctx->lastmark); LASTMARK_RESTORE(); ctx->ptr--; ctx->count--; } - + if (state->repeat) + MARK_POP_DISCARD(ctx->lastmark); } else { /* general case */ while (ctx->count >= (Py_ssize_t) ctx->pattern[1]) { @@ -875,13 +880,20 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) DO_JUMP(JUMP_REPEAT_ONE_2, jump_repeat_one_2, ctx->pattern+ctx->pattern[0]); if (ret) { + if (state->repeat) + MARK_POP_DISCARD(ctx->lastmark); RETURN_ON_ERROR(ret); RETURN_SUCCESS; } + if (state->repeat) + MARK_POP_KEEP(ctx->lastmark); + LASTMARK_RESTORE(); + ctx->ptr--; ctx->count--; - LASTMARK_RESTORE(); } + if (state->repeat) + MARK_POP_DISCARD(ctx->lastmark); } RETURN_FAILURE; @@ -930,15 +942,24 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) } else { /* general case */ LASTMARK_SAVE(); + if (state->repeat) + MARK_PUSH(ctx->lastmark); + while ((Py_ssize_t)ctx->pattern[2] == SRE_MAXREPEAT || ctx->count <= (Py_ssize_t)ctx->pattern[2]) { state->ptr = ctx->ptr; DO_JUMP(JUMP_MIN_REPEAT_ONE,jump_min_repeat_one, ctx->pattern+ctx->pattern[0]); if (ret) { + if (state->repeat) + MARK_POP_DISCARD(ctx->lastmark); RETURN_ON_ERROR(ret); RETURN_SUCCESS; } + if (state->repeat) + MARK_POP_KEEP(ctx->lastmark); + LASTMARK_RESTORE(); + state->ptr = ctx->ptr; ret = SRE(count)(state, ctx->pattern+3, 1); RETURN_ON_ERROR(ret); @@ -948,8 +969,9 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) assert(ret == 1); ctx->ptr++; ctx->count++; - LASTMARK_RESTORE(); } + if (state->repeat) + MARK_POP_DISCARD(ctx->lastmark); } RETURN_FAILURE; @@ -1098,8 +1120,9 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) tail matches */ state->repeat = ctx->u.rep->prev; DO_JUMP(JUMP_MAX_UNTIL_3, jump_max_until_3, ctx->pattern); + state->repeat = ctx->u.rep; // restore repeat before return + RETURN_ON_SUCCESS(ret); - state->repeat = ctx->u.rep; state->ptr = ctx->ptr; RETURN_FAILURE; @@ -1132,21 +1155,29 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) RETURN_FAILURE; } - LASTMARK_SAVE(); - /* see if the tail matches */ state->repeat = ctx->u.rep->prev; + + LASTMARK_SAVE(); + if (state->repeat) + MARK_PUSH(ctx->lastmark); + DO_JUMP(JUMP_MIN_UNTIL_2, jump_min_until_2, ctx->pattern); + SRE_REPEAT *repeat_of_tail = state->repeat; + state->repeat = ctx->u.rep; // restore repeat before return + if (ret) { + if (repeat_of_tail) + MARK_POP_DISCARD(ctx->lastmark); RETURN_ON_ERROR(ret); RETURN_SUCCESS; } + if (repeat_of_tail) + MARK_POP(ctx->lastmark); + LASTMARK_RESTORE(); - state->repeat = ctx->u.rep; state->ptr = ctx->ptr; - LASTMARK_RESTORE(); - if ((ctx->count >= (Py_ssize_t) ctx->u.rep->pattern[2] && ctx->u.rep->pattern[2] != SRE_MAXREPEAT) || state->ptr == ctx->u.rep->last_ptr) @@ -1444,11 +1475,20 @@ SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel) ctx->ptr, ctx->pattern[1])); if (ctx->ptr - (SRE_CHAR *)state->beginning >= (Py_ssize_t)ctx->pattern[1]) { state->ptr = ctx->ptr - ctx->pattern[1]; + LASTMARK_SAVE(); + if (state->repeat) + MARK_PUSH(ctx->lastmark); + DO_JUMP0(JUMP_ASSERT_NOT, jump_assert_not, ctx->pattern+2); if (ret) { + if (state->repeat) + MARK_POP_DISCARD(ctx->lastmark); RETURN_ON_ERROR(ret); RETURN_FAILURE; } + if (state->repeat) + MARK_POP(ctx->lastmark); + LASTMARK_RESTORE(); } ctx->pattern += ctx->pattern[0]; break; From webhook-mailer at python.org Tue Mar 29 11:02:33 2022 From: webhook-mailer at python.org (asvetlov) Date: Tue, 29 Mar 2022 15:02:33 -0000 Subject: [Python-checkins] bpo-14265: Adds fully qualified test name to unittest output (GH-32138) Message-ID: https://github.com/python/cpython/commit/755be9b1505af591b9f2ee424a6525b6c2b65ce9 commit: 755be9b1505af591b9f2ee424a6525b6c2b65ce9 branch: main author: Sam Ezeh committer: asvetlov date: 2022-03-29T18:02:09+03:00 summary: bpo-14265: Adds fully qualified test name to unittest output (GH-32138) Co-authored-by: Andrew Svetlov files: A Misc/NEWS.d/next/Library/2022-03-27-10-41-24.bpo-14265.OBMlAi.rst M Doc/library/unittest.rst M Lib/unittest/case.py M Lib/unittest/test/test_result.py M Misc/ACKS diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst index 06df8ce3ad69b..9b8b75acce514 100644 --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -139,9 +139,9 @@ line, the above script produces an output that looks like this:: Passing the ``-v`` option to your test script will instruct :func:`unittest.main` to enable a higher level of verbosity, and produce the following output:: - test_isupper (__main__.TestStringMethods) ... ok - test_split (__main__.TestStringMethods) ... ok - test_upper (__main__.TestStringMethods) ... ok + test_isupper (__main__.TestStringMethods.test_isupper) ... ok + test_split (__main__.TestStringMethods.test_split) ... ok + test_upper (__main__.TestStringMethods.test_upper) ... ok ---------------------------------------------------------------------- Ran 3 tests in 0.001s @@ -565,10 +565,10 @@ Basic skipping looks like this:: This is the output of running the example above in verbose mode:: - test_format (__main__.MyTestCase) ... skipped 'not supported in this library version' - test_nothing (__main__.MyTestCase) ... skipped 'demonstrating skipping' - test_maybe_skipped (__main__.MyTestCase) ... skipped 'external resource not available' - test_windows_support (__main__.MyTestCase) ... skipped 'requires Windows' + test_format (__main__.MyTestCase.test_format) ... skipped 'not supported in this library version' + test_nothing (__main__.MyTestCase.test_nothing) ... skipped 'demonstrating skipping' + test_maybe_skipped (__main__.MyTestCase.test_maybe_skipped) ... skipped 'external resource not available' + test_windows_support (__main__.MyTestCase.test_windows_support) ... skipped 'requires Windows' ---------------------------------------------------------------------- Ran 4 tests in 0.005s @@ -661,27 +661,33 @@ For example, the following test:: will produce the following output:: ====================================================================== - FAIL: test_even (__main__.NumbersTest) (i=1) + FAIL: test_even (__main__.NumbersTest.test_even) (i=1) + Test that numbers between 0 and 5 are all even. ---------------------------------------------------------------------- Traceback (most recent call last): - File "subtests.py", line 32, in test_even + File "subtests.py", line 11, in test_even self.assertEqual(i % 2, 0) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ AssertionError: 1 != 0 ====================================================================== - FAIL: test_even (__main__.NumbersTest) (i=3) + FAIL: test_even (__main__.NumbersTest.test_even) (i=3) + Test that numbers between 0 and 5 are all even. ---------------------------------------------------------------------- Traceback (most recent call last): - File "subtests.py", line 32, in test_even + File "subtests.py", line 11, in test_even self.assertEqual(i % 2, 0) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ AssertionError: 1 != 0 ====================================================================== - FAIL: test_even (__main__.NumbersTest) (i=5) + FAIL: test_even (__main__.NumbersTest.test_even) (i=5) + Test that numbers between 0 and 5 are all even. ---------------------------------------------------------------------- Traceback (most recent call last): - File "subtests.py", line 32, in test_even + File "subtests.py", line 11, in test_even self.assertEqual(i % 2, 0) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ AssertionError: 1 != 0 Without using a subtest, execution would stop after the first failure, @@ -689,7 +695,7 @@ and the error would be less easy to diagnose because the value of ``i`` wouldn't be displayed:: ====================================================================== - FAIL: test_even (__main__.NumbersTest) + FAIL: test_even (__main__.NumbersTest.test_even) ---------------------------------------------------------------------- Traceback (most recent call last): File "subtests.py", line 32, in test_even diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py index 0d550204a7687..55770c06d7c5d 100644 --- a/Lib/unittest/case.py +++ b/Lib/unittest/case.py @@ -478,7 +478,7 @@ def __hash__(self): return hash((type(self), self._testMethodName)) def __str__(self): - return "%s (%s)" % (self._testMethodName, strclass(self.__class__)) + return "%s (%s.%s)" % (self._testMethodName, strclass(self.__class__), self._testMethodName) def __repr__(self): return "<%s testMethod=%s>" % \ diff --git a/Lib/unittest/test/test_result.py b/Lib/unittest/test/test_result.py index c616f28dfee92..b0cc3d867d6e5 100644 --- a/Lib/unittest/test/test_result.py +++ b/Lib/unittest/test/test_result.py @@ -423,7 +423,7 @@ def testGetDescriptionWithoutDocstring(self): self.assertEqual( result.getDescription(self), 'testGetDescriptionWithoutDocstring (' + __name__ + - '.Test_TextTestResult)') + '.Test_TextTestResult.testGetDescriptionWithoutDocstring)') def testGetSubTestDescriptionWithoutDocstring(self): with self.subTest(foo=1, bar=2): @@ -431,13 +431,14 @@ def testGetSubTestDescriptionWithoutDocstring(self): self.assertEqual( result.getDescription(self._subtest), 'testGetSubTestDescriptionWithoutDocstring (' + __name__ + - '.Test_TextTestResult) (foo=1, bar=2)') + '.Test_TextTestResult.testGetSubTestDescriptionWithoutDocstring) (foo=1, bar=2)') + with self.subTest('some message'): result = unittest.TextTestResult(None, True, 1) self.assertEqual( result.getDescription(self._subtest), 'testGetSubTestDescriptionWithoutDocstring (' + __name__ + - '.Test_TextTestResult) [some message]') + '.Test_TextTestResult.testGetSubTestDescriptionWithoutDocstring) [some message]') def testGetSubTestDescriptionWithoutDocstringAndParams(self): with self.subTest(): @@ -445,10 +446,11 @@ def testGetSubTestDescriptionWithoutDocstringAndParams(self): self.assertEqual( result.getDescription(self._subtest), 'testGetSubTestDescriptionWithoutDocstringAndParams ' - '(' + __name__ + '.Test_TextTestResult) ()') + '(' + __name__ + '.Test_TextTestResult.testGetSubTestDescriptionWithoutDocstringAndParams) ' + '()') def testGetSubTestDescriptionForFalsyValues(self): - expected = 'testGetSubTestDescriptionForFalsyValues (%s.Test_TextTestResult) [%s]' + expected = 'testGetSubTestDescriptionForFalsyValues (%s.Test_TextTestResult.testGetSubTestDescriptionForFalsyValues) [%s]' result = unittest.TextTestResult(None, True, 1) for arg in [0, None, []]: with self.subTest(arg): @@ -464,7 +466,8 @@ def testGetNestedSubTestDescriptionWithoutDocstring(self): self.assertEqual( result.getDescription(self._subtest), 'testGetNestedSubTestDescriptionWithoutDocstring ' - '(' + __name__ + '.Test_TextTestResult) (baz=2, bar=3, foo=1)') + '(' + __name__ + '.Test_TextTestResult.testGetNestedSubTestDescriptionWithoutDocstring) ' + '(baz=2, bar=3, foo=1)') def testGetDuplicatedNestedSubTestDescriptionWithoutDocstring(self): with self.subTest(foo=1, bar=2): @@ -473,7 +476,7 @@ def testGetDuplicatedNestedSubTestDescriptionWithoutDocstring(self): self.assertEqual( result.getDescription(self._subtest), 'testGetDuplicatedNestedSubTestDescriptionWithoutDocstring ' - '(' + __name__ + '.Test_TextTestResult) (baz=3, bar=4, foo=1)') + '(' + __name__ + '.Test_TextTestResult.testGetDuplicatedNestedSubTestDescriptionWithoutDocstring) (baz=3, bar=4, foo=1)') @unittest.skipIf(sys.flags.optimize >= 2, "Docstrings are omitted with -O2 and above") @@ -483,7 +486,7 @@ def testGetDescriptionWithOneLineDocstring(self): self.assertEqual( result.getDescription(self), ('testGetDescriptionWithOneLineDocstring ' - '(' + __name__ + '.Test_TextTestResult)\n' + '(' + __name__ + '.Test_TextTestResult.testGetDescriptionWithOneLineDocstring)\n' 'Tests getDescription() for a method with a docstring.')) @unittest.skipIf(sys.flags.optimize >= 2, @@ -495,7 +498,9 @@ def testGetSubTestDescriptionWithOneLineDocstring(self): self.assertEqual( result.getDescription(self._subtest), ('testGetSubTestDescriptionWithOneLineDocstring ' - '(' + __name__ + '.Test_TextTestResult) (foo=1, bar=2)\n' + '(' + __name__ + '.Test_TextTestResult.testGetSubTestDescriptionWithOneLineDocstring) ' + '(foo=1, bar=2)\n' + 'Tests getDescription() for a method with a docstring.')) @unittest.skipIf(sys.flags.optimize >= 2, @@ -508,7 +513,7 @@ def testGetDescriptionWithMultiLineDocstring(self): self.assertEqual( result.getDescription(self), ('testGetDescriptionWithMultiLineDocstring ' - '(' + __name__ + '.Test_TextTestResult)\n' + '(' + __name__ + '.Test_TextTestResult.testGetDescriptionWithMultiLineDocstring)\n' 'Tests getDescription() for a method with a longer ' 'docstring.')) @@ -523,7 +528,8 @@ def testGetSubTestDescriptionWithMultiLineDocstring(self): self.assertEqual( result.getDescription(self._subtest), ('testGetSubTestDescriptionWithMultiLineDocstring ' - '(' + __name__ + '.Test_TextTestResult) (foo=1, bar=2)\n' + '(' + __name__ + '.Test_TextTestResult.testGetSubTestDescriptionWithMultiLineDocstring) ' + '(foo=1, bar=2)\n' 'Tests getDescription() for a method with a longer ' 'docstring.')) @@ -582,17 +588,17 @@ def testDotsOutput(self): def testLongOutput(self): classname = f'{__name__}.{self.Test.__qualname__}' self.assertEqual(self._run_test('testSuccess', 2), - f'testSuccess ({classname}) ... ok\n') + f'testSuccess ({classname}.testSuccess) ... ok\n') self.assertEqual(self._run_test('testSkip', 2), - f"testSkip ({classname}) ... skipped 'skip'\n") + f"testSkip ({classname}.testSkip) ... skipped 'skip'\n") self.assertEqual(self._run_test('testFail', 2), - f'testFail ({classname}) ... FAIL\n') + f'testFail ({classname}.testFail) ... FAIL\n') self.assertEqual(self._run_test('testError', 2), - f'testError ({classname}) ... ERROR\n') + f'testError ({classname}.testError) ... ERROR\n') self.assertEqual(self._run_test('testExpectedFailure', 2), - f'testExpectedFailure ({classname}) ... expected failure\n') + f'testExpectedFailure ({classname}.testExpectedFailure) ... expected failure\n') self.assertEqual(self._run_test('testUnexpectedSuccess', 2), - f'testUnexpectedSuccess ({classname}) ... unexpected success\n') + f'testUnexpectedSuccess ({classname}.testUnexpectedSuccess) ... unexpected success\n') def testDotsOutputSubTestSuccess(self): self.assertEqual(self._run_test('testSubTestSuccess', 1), '.') @@ -600,7 +606,7 @@ def testDotsOutputSubTestSuccess(self): def testLongOutputSubTestSuccess(self): classname = f'{__name__}.{self.Test.__qualname__}' self.assertEqual(self._run_test('testSubTestSuccess', 2), - f'testSubTestSuccess ({classname}) ... ok\n') + f'testSubTestSuccess ({classname}.testSubTestSuccess) ... ok\n') def testDotsOutputSubTestMixed(self): self.assertEqual(self._run_test('testSubTestMixed', 1), 'sFE') @@ -608,10 +614,10 @@ def testDotsOutputSubTestMixed(self): def testLongOutputSubTestMixed(self): classname = f'{__name__}.{self.Test.__qualname__}' self.assertEqual(self._run_test('testSubTestMixed', 2), - f'testSubTestMixed ({classname}) ... \n' - f" testSubTestMixed ({classname}) [skip] (b=2) ... skipped 'skip'\n" - f' testSubTestMixed ({classname}) [fail] (c=3) ... FAIL\n' - f' testSubTestMixed ({classname}) [error] (d=4) ... ERROR\n') + f'testSubTestMixed ({classname}.testSubTestMixed) ... \n' + f" testSubTestMixed ({classname}.testSubTestMixed) [skip] (b=2) ... skipped 'skip'\n" + f' testSubTestMixed ({classname}.testSubTestMixed) [fail] (c=3) ... FAIL\n' + f' testSubTestMixed ({classname}.testSubTestMixed) [error] (d=4) ... ERROR\n') def testDotsOutputTearDownFail(self): out = self._run_test('testSuccess', 1, AssertionError('fail')) @@ -627,19 +633,19 @@ def testLongOutputTearDownFail(self): classname = f'{__name__}.{self.Test.__qualname__}' out = self._run_test('testSuccess', 2, AssertionError('fail')) self.assertEqual(out, - f'testSuccess ({classname}) ... FAIL\n') + f'testSuccess ({classname}.testSuccess) ... FAIL\n') out = self._run_test('testError', 2, AssertionError('fail')) self.assertEqual(out, - f'testError ({classname}) ... ERROR\n' - f'testError ({classname}) ... FAIL\n') + f'testError ({classname}.testError) ... ERROR\n' + f'testError ({classname}.testError) ... FAIL\n') out = self._run_test('testFail', 2, Exception('error')) self.assertEqual(out, - f'testFail ({classname}) ... FAIL\n' - f'testFail ({classname}) ... ERROR\n') + f'testFail ({classname}.testFail) ... FAIL\n' + f'testFail ({classname}.testFail) ... ERROR\n') out = self._run_test('testSkip', 2, AssertionError('fail')) self.assertEqual(out, - f"testSkip ({classname}) ... skipped 'skip'\n" - f'testSkip ({classname}) ... FAIL\n') + f"testSkip ({classname}.testSkip) ... skipped 'skip'\n" + f'testSkip ({classname}.testSkip) ... FAIL\n') classDict = dict(unittest.TestResult.__dict__) @@ -852,7 +858,7 @@ def test_foo(self): expected_out = '\nStdout:\nset up\n' self.assertEqual(stdout.getvalue(), expected_out) self.assertEqual(len(result.errors), 1) - description = f'test_foo ({strclass(Foo)})' + description = f'test_foo ({strclass(Foo)}.test_foo)' test_case, formatted_exc = result.errors[0] self.assertEqual(str(test_case), description) self.assertIn('ZeroDivisionError: division by zero', formatted_exc) @@ -874,7 +880,7 @@ def test_foo(self): expected_out = '\nStdout:\ntear down\n' self.assertEqual(stdout.getvalue(), expected_out) self.assertEqual(len(result.errors), 1) - description = f'test_foo ({strclass(Foo)})' + description = f'test_foo ({strclass(Foo)}.test_foo)' test_case, formatted_exc = result.errors[0] self.assertEqual(str(test_case), description) self.assertIn('ZeroDivisionError: division by zero', formatted_exc) @@ -897,7 +903,7 @@ def test_foo(self): expected_out = '\nStdout:\nset up\ndo cleanup2\ndo cleanup1\n' self.assertEqual(stdout.getvalue(), expected_out) self.assertEqual(len(result.errors), 2) - description = f'test_foo ({strclass(Foo)})' + description = f'test_foo ({strclass(Foo)}.test_foo)' test_case, formatted_exc = result.errors[0] self.assertEqual(str(test_case), description) self.assertIn('ValueError: bad cleanup2', formatted_exc) @@ -928,7 +934,7 @@ def test_foo(self): expected_out = '\nStdout:\nset up\ndo cleanup2\ndo cleanup1\n' self.assertEqual(stdout.getvalue(), expected_out) self.assertEqual(len(result.errors), 3) - description = f'test_foo ({strclass(Foo)})' + description = f'test_foo ({strclass(Foo)}.test_foo)' test_case, formatted_exc = result.errors[0] self.assertEqual(str(test_case), description) self.assertIn('ZeroDivisionError: division by zero', formatted_exc) @@ -971,7 +977,7 @@ def test_foo(self): expected_out = '\nStdout:\nset up\ntear down\ndo cleanup2\ndo cleanup1\n' self.assertEqual(stdout.getvalue(), expected_out) self.assertEqual(len(result.errors), 3) - description = f'test_foo ({strclass(Foo)})' + description = f'test_foo ({strclass(Foo)}.test_foo)' test_case, formatted_exc = result.errors[0] self.assertEqual(str(test_case), description) self.assertIn('ZeroDivisionError: division by zero', formatted_exc) diff --git a/Misc/ACKS b/Misc/ACKS index efa2474c3cfdb..72e2cfe13775a 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -516,6 +516,7 @@ Daniel Evers evilzero Winston Ewert Greg Ewing +Sam Ezeh Martijn Faassen Clovis Fabricio Andreas Faerber diff --git a/Misc/NEWS.d/next/Library/2022-03-27-10-41-24.bpo-14265.OBMlAi.rst b/Misc/NEWS.d/next/Library/2022-03-27-10-41-24.bpo-14265.OBMlAi.rst new file mode 100644 index 0000000000000..308ce36c6ba50 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-27-10-41-24.bpo-14265.OBMlAi.rst @@ -0,0 +1 @@ +Adds the fully qualified test name to unittest output From webhook-mailer at python.org Tue Mar 29 15:11:06 2022 From: webhook-mailer at python.org (ned-deily) Date: Tue, 29 Mar 2022 19:11:06 -0000 Subject: [Python-checkins] bpo-47138: Ensure Windows docs build uses the same pinned version as other platforms (GH-32182) Message-ID: https://github.com/python/cpython/commit/d97497bf1cc6abd4a9a67d8da4f00cf13b3af4b3 commit: d97497bf1cc6abd4a9a67d8da4f00cf13b3af4b3 branch: 3.7 author: Steve Dower committer: ned-deily date: 2022-03-29T15:10:57-04:00 summary: bpo-47138: Ensure Windows docs build uses the same pinned version as other platforms (GH-32182) files: M Doc/make.bat diff --git a/Doc/make.bat b/Doc/make.bat index 63e0bd7236475..f081b4d35a205 100644 --- a/Doc/make.bat +++ b/Doc/make.bat @@ -13,7 +13,7 @@ if not defined SPHINXBUILD ( %PYTHON% -c "import sphinx" > nul 2> nul if errorlevel 1 ( echo Installing sphinx with %PYTHON% - %PYTHON% -m pip install sphinx==2.2.0 + %PYTHON% -m pip install sphinx==2.3.1 blurb docutils==0.17.1 Jinja2==3.0.3 if errorlevel 1 exit /B ) set SPHINXBUILD=%PYTHON% -c "import sphinx.cmd.build, sys; sys.exit(sphinx.cmd.build.main())" From webhook-mailer at python.org Tue Mar 29 17:21:58 2022 From: webhook-mailer at python.org (JelleZijlstra) Date: Tue, 29 Mar 2022 21:21:58 -0000 Subject: [Python-checkins] bpo-42340: Document issues around KeyboardInterrupt (GH-23255) Message-ID: https://github.com/python/cpython/commit/d0906c90fcfbc4cfb9bb963eaa6bb152dd543b56 commit: d0906c90fcfbc4cfb9bb963eaa6bb152dd543b56 branch: main author: benfogle committer: JelleZijlstra date: 2022-03-29T14:21:36-07:00 summary: bpo-42340: Document issues around KeyboardInterrupt (GH-23255) Update documentation to note that in some circumstances, KeyboardInterrupt may cause code to enter an inconsistent state. Also document sample workaround to avoid KeyboardInterrupt, if needed. files: A Misc/NEWS.d/next/Documentation/2020-11-12-21-26-31.bpo-42340.apumUL.rst M Doc/library/exceptions.rst M Doc/library/signal.rst diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst index d0b2e62c34c96..9e001c8dcd757 100644 --- a/Doc/library/exceptions.rst +++ b/Doc/library/exceptions.rst @@ -254,6 +254,15 @@ The following exceptions are the exceptions that are usually raised. accidentally caught by code that catches :exc:`Exception` and thus prevent the interpreter from exiting. + .. note:: + + Catching a :exc:`KeyboardInterrupt` requires special consideration. + Because it can be raised at unpredictable points, it may, in some + circumstances, leave the running program in an inconsistent state. It is + generally best to allow :exc:`KeyboardInterrupt` to end the program as + quickly as possible or avoid raising it entirely. (See + :ref:`handlers-and-exceptions`.) + .. exception:: MemoryError diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst index abc30362da9e2..c276b52ca4d20 100644 --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -46,6 +46,9 @@ This has consequences: arbitrary amount of time, regardless of any signals received. The Python signal handlers will be called when the calculation finishes. +* If the handler raises an exception, it will be raised "out of thin air" in + the main thread. See the :ref:`note below ` for a + discussion. .. _signals-and-threads: @@ -712,3 +715,70 @@ Do not set :const:`SIGPIPE`'s disposition to :const:`SIG_DFL` in order to avoid :exc:`BrokenPipeError`. Doing that would cause your program to exit unexpectedly also whenever any socket connection is interrupted while your program is still writing to it. + +.. _handlers-and-exceptions: + +Note on Signal Handlers and Exceptions +-------------------------------------- + +If a signal handler raises an exception, the exception will be propagated to +the main thread and may be raised after any :term:`bytecode` instruction. Most +notably, a :exc:`KeyboardInterrupt` may appear at any point during execution. +Most Python code, including the standard library, cannot be made robust against +this, and so a :exc:`KeyboardInterrupt` (or any other exception resulting from +a signal handler) may on rare occasions put the program in an unexpected state. + +To illustrate this issue, consider the following code:: + + class SpamContext: + def __init__(self): + self.lock = threading.Lock() + + def __enter__(self): + # If KeyboardInterrupt occurs here, everything is fine + self.lock.acquire() + # If KeyboardInterrupt occcurs here, __exit__ will not be called + ... + # KeyboardInterrupt could occur just before the function returns + + def __exit__(self, exc_type, exc_val, exc_tb): + ... + self.lock.release() + +For many programs, especially those that merely want to exit on +:exc:`KeyboardInterrupt`, this is not a problem, but applications that are +complex or require high reliability should avoid raising exceptions from signal +handlers. They should also avoid catching :exc:`KeyboardInterrupt` as a means +of gracefully shutting down. Instead, they should install their own +:const:`SIGINT` handler. Below is an example of an HTTP server that avoids +:exc:`KeyboardInterrupt`:: + + import signal + import socket + from selectors import DefaultSelector, EVENT_READ + from http.server import HTTPServer, SimpleHTTPRequestHandler + + interrupt_read, interrupt_write = socket.socketpair() + + def handler(signum, frame): + print('Signal handler called with signal', signum) + interrupt_write.send(b'\0') + signal.signal(signal.SIGINT, handler) + + def serve_forever(httpd): + sel = DefaultSelector() + sel.register(interrupt_read, EVENT_READ) + sel.register(httpd, EVENT_READ) + + while True: + for key, _ in sel.select(): + if key.fileobj == interrupt_read: + interrupt_read.recv(1) + return + if key.fileobj == httpd: + httpd.handle_request() + + print("Serving on port 8000") + httpd = HTTPServer(('', 8000), SimpleHTTPRequestHandler) + serve_forever(httpd) + print("Shutdown...") diff --git a/Misc/NEWS.d/next/Documentation/2020-11-12-21-26-31.bpo-42340.apumUL.rst b/Misc/NEWS.d/next/Documentation/2020-11-12-21-26-31.bpo-42340.apumUL.rst new file mode 100644 index 0000000000000..aa6857497383c --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-11-12-21-26-31.bpo-42340.apumUL.rst @@ -0,0 +1,3 @@ +Document that in some circumstances :exc:`KeyboardInterrupt` may cause the +code to enter an inconsistent state. Provided a sample workaround to avoid +it if needed. From webhook-mailer at python.org Tue Mar 29 17:22:00 2022 From: webhook-mailer at python.org (asvetlov) Date: Tue, 29 Mar 2022 21:22:00 -0000 Subject: [Python-checkins] Update glossary.rst (GH-32093) Message-ID: https://github.com/python/cpython/commit/654bd2152d82b83d7dc037d6d83d60855e3041b7 commit: 654bd2152d82b83d7dc037d6d83d60855e3041b7 branch: main author: G?ry Ogam committer: asvetlov date: 2022-03-30T00:21:56+03:00 summary: Update glossary.rst (GH-32093) files: M Doc/glossary.rst diff --git a/Doc/glossary.rst b/Doc/glossary.rst index f0f33d577374b..258a06f721703 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -628,7 +628,7 @@ Glossary and :class:`tuple`) and some non-sequence types like :class:`dict`, :term:`file objects `, and objects of any classes you define with an :meth:`__iter__` method or with a :meth:`__getitem__` method - that implements :term:`Sequence ` semantics. + that implements :term:`sequence` semantics. Iterables can be used in a :keyword:`for` loop and in many other places where a sequence is @@ -680,9 +680,8 @@ Glossary :meth:`str.lower` method can serve as a key function for case insensitive sorts. Alternatively, a key function can be built from a :keyword:`lambda` expression such as ``lambda r: (r[0], r[2])``. Also, - the :mod:`operator` module provides three key function constructors: - :func:`~operator.attrgetter`, :func:`~operator.itemgetter`, and - :func:`~operator.methodcaller`. See the :ref:`Sorting HOW TO + :func:`operator.attrgetter`, :func:`operator.itemgetter`, and + :func:`operator.methodcaller` are three key function constructors. See the :ref:`Sorting HOW TO ` for examples of how to create and use key functions. keyword argument @@ -743,8 +742,8 @@ Glossary mapping A container object that supports arbitrary key lookups and implements the - methods specified in the :class:`~collections.abc.Mapping` or - :class:`~collections.abc.MutableMapping` + methods specified in the :class:`collections.abc.Mapping` or + :class:`collections.abc.MutableMapping` :ref:`abstract base classes `. Examples include :class:`dict`, :class:`collections.defaultdict`, :class:`collections.OrderedDict` and :class:`collections.Counter`. @@ -1049,8 +1048,8 @@ Glossary The number of references to an object. When the reference count of an object drops to zero, it is deallocated. Reference counting is generally not visible to Python code, but it is a key element of the - :term:`CPython` implementation. The :mod:`sys` module defines a - :func:`~sys.getrefcount` function that programmers can call to return the + :term:`CPython` implementation. Programmers can call the + :func:`sys.getrefcount` function to return the reference count for a particular object. regular package From webhook-mailer at python.org Tue Mar 29 17:26:37 2022 From: webhook-mailer at python.org (gpshead) Date: Tue, 29 Mar 2022 21:26:37 -0000 Subject: [Python-checkins] bpo-33178: Add BigEndianUnion, LittleEndianUnion classes to ctypes (GH-25480) Message-ID: https://github.com/python/cpython/commit/dc2d8404a3ab6288ce112c71da8c65c34cd3087e commit: dc2d8404a3ab6288ce112c71da8c65c34cd3087e branch: main author: Dave Goncalves committer: gpshead date: 2022-03-29T14:26:27-07:00 summary: bpo-33178: Add BigEndianUnion, LittleEndianUnion classes to ctypes (GH-25480) * bpo-33178: Add BigEndianUnion, LittleEndianUnion classes to ctypes * GH-25480: remove trailing whitespace in ctypes doc * GH-25480: add news entry blurb * GH-25480: corrected formatting error in news blurb * GH-25480: simplified, corrected formatting in news blurb * GH-25480: remove trailing whitespace in news blurb * GH-25480: fixed class markup in news blurb * GH-25480: fixed unsupported type tests and naming per review comments * GH-25480: fixed whitepace errors * condensed base class selection for unsupported byte order tests * added versionadded tags for new EndianUnion classes files: A Misc/NEWS.d/next/Library/2021-04-20-16-48-07.bpo-33178.kSnWwb.rst M Doc/library/ctypes.rst M Lib/ctypes/__init__.py M Lib/ctypes/_endian.py M Lib/ctypes/test/test_byteswap.py diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index dca4c74bab771..6cca569a3f1c8 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -2390,6 +2390,18 @@ Structured data types Abstract base class for unions in native byte order. +.. class:: BigEndianUnion(*args, **kw) + + Abstract base class for unions in *big endian* byte order. + + .. versionadded:: 3.11 + +.. class:: LittleEndianUnion(*args, **kw) + + Abstract base class for unions in *little endian* byte order. + + .. versionadded:: 3.11 + .. class:: BigEndianStructure(*args, **kw) Abstract base class for structures in *big endian* byte order. @@ -2399,8 +2411,8 @@ Structured data types Abstract base class for structures in *little endian* byte order. -Structures with non-native byte order cannot contain pointer type fields, or any -other data types containing pointer type fields. +Structures and unions with non-native byte order cannot contain pointer type +fields, or any other data types containing pointer type fields. .. class:: Structure(*args, **kw) diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py index ab4d31b0acb00..26135ad96296a 100644 --- a/Lib/ctypes/__init__.py +++ b/Lib/ctypes/__init__.py @@ -548,6 +548,7 @@ def DllCanUnloadNow(): return ccom.DllCanUnloadNow() from ctypes._endian import BigEndianStructure, LittleEndianStructure +from ctypes._endian import BigEndianUnion, LittleEndianUnion # Fill in specifically-sized types c_int8 = c_byte diff --git a/Lib/ctypes/_endian.py b/Lib/ctypes/_endian.py index 37444bd6a7dd6..34dee64b1a65a 100644 --- a/Lib/ctypes/_endian.py +++ b/Lib/ctypes/_endian.py @@ -20,7 +20,7 @@ def _other_endian(typ): return typ raise TypeError("This type does not support other endian: %s" % typ) -class _swapped_meta(type(Structure)): +class _swapped_meta: def __setattr__(self, attrname, value): if attrname == "_fields_": fields = [] @@ -31,6 +31,8 @@ def __setattr__(self, attrname, value): fields.append((name, _other_endian(typ)) + rest) value = fields super().__setattr__(attrname, value) +class _swapped_struct_meta(_swapped_meta, type(Structure)): pass +class _swapped_union_meta(_swapped_meta, type(Union)): pass ################################################################ @@ -43,19 +45,34 @@ def __setattr__(self, attrname, value): LittleEndianStructure = Structure - class BigEndianStructure(Structure, metaclass=_swapped_meta): + class BigEndianStructure(Structure, metaclass=_swapped_struct_meta): """Structure with big endian byte order""" __slots__ = () _swappedbytes_ = None + LittleEndianUnion = Union + + class BigEndianUnion(Union, metaclass=_swapped_union_meta): + """Union with big endian byte order""" + __slots__ = () + _swappedbytes_ = None + elif sys.byteorder == "big": _OTHER_ENDIAN = "__ctype_le__" BigEndianStructure = Structure - class LittleEndianStructure(Structure, metaclass=_swapped_meta): + + class LittleEndianStructure(Structure, metaclass=_swapped_struct_meta): """Structure with little endian byte order""" __slots__ = () _swappedbytes_ = None + BigEndianUnion = Union + + class LittleEndianUnion(Union, metaclass=_swapped_union_meta): + """Union with little endian byte order""" + __slots__ = () + _swappedbytes_ = None + else: raise RuntimeError("Invalid byteorder") diff --git a/Lib/ctypes/test/test_byteswap.py b/Lib/ctypes/test/test_byteswap.py index 01c97e83ca7af..7e98559dfbccb 100644 --- a/Lib/ctypes/test/test_byteswap.py +++ b/Lib/ctypes/test/test_byteswap.py @@ -170,40 +170,34 @@ def test_endian_other(self): self.assertIs(c_char.__ctype_le__, c_char) self.assertIs(c_char.__ctype_be__, c_char) - def test_struct_fields_1(self): - if sys.byteorder == "little": - base = BigEndianStructure - else: - base = LittleEndianStructure - - class T(base): - pass - _fields_ = [("a", c_ubyte), - ("b", c_byte), - ("c", c_short), - ("d", c_ushort), - ("e", c_int), - ("f", c_uint), - ("g", c_long), - ("h", c_ulong), - ("i", c_longlong), - ("k", c_ulonglong), - ("l", c_float), - ("m", c_double), - ("n", c_char), - - ("b1", c_byte, 3), - ("b2", c_byte, 3), - ("b3", c_byte, 2), - ("a", c_int * 3 * 3 * 3)] - T._fields_ = _fields_ + def test_struct_fields_unsupported_byte_order(self): + + fields = [ + ("a", c_ubyte), + ("b", c_byte), + ("c", c_short), + ("d", c_ushort), + ("e", c_int), + ("f", c_uint), + ("g", c_long), + ("h", c_ulong), + ("i", c_longlong), + ("k", c_ulonglong), + ("l", c_float), + ("m", c_double), + ("n", c_char), + ("b1", c_byte, 3), + ("b2", c_byte, 3), + ("b3", c_byte, 2), + ("a", c_int * 3 * 3 * 3) + ] # these fields do not support different byte order: for typ in c_wchar, c_void_p, POINTER(c_int): - _fields_.append(("x", typ)) - class T(base): - pass - self.assertRaises(TypeError, setattr, T, "_fields_", [("x", typ)]) + with self.assertRaises(TypeError): + class T(BigEndianStructure if sys.byteorder == "little" else LittleEndianStructure): + _fields_ = fields + [("x", typ)] + def test_struct_struct(self): # nested structures with different byteorders @@ -233,7 +227,7 @@ class TestStructure(parent): self.assertEqual(s.point.x, 1) self.assertEqual(s.point.y, 2) - def test_struct_fields_2(self): + def test_struct_field_alignment(self): # standard packing in struct uses no alignment. # So, we have to align using pad bytes. # @@ -267,7 +261,6 @@ def test_unaligned_nonnative_struct_fields(self): class S(base): _pack_ = 1 _fields_ = [("b", c_byte), - ("h", c_short), ("_1", c_byte), @@ -311,5 +304,61 @@ class S(Structure): s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14) self.assertEqual(bin(s1), bin(s2)) + def test_union_fields_unsupported_byte_order(self): + + fields = [ + ("a", c_ubyte), + ("b", c_byte), + ("c", c_short), + ("d", c_ushort), + ("e", c_int), + ("f", c_uint), + ("g", c_long), + ("h", c_ulong), + ("i", c_longlong), + ("k", c_ulonglong), + ("l", c_float), + ("m", c_double), + ("n", c_char), + ("b1", c_byte, 3), + ("b2", c_byte, 3), + ("b3", c_byte, 2), + ("a", c_int * 3 * 3 * 3) + ] + + # these fields do not support different byte order: + for typ in c_wchar, c_void_p, POINTER(c_int): + with self.assertRaises(TypeError): + class T(BigEndianUnion if sys.byteorder == "little" else LittleEndianUnion): + _fields_ = fields + [("x", typ)] + + def test_union_struct(self): + # nested structures in unions with different byteorders + + # create nested structures in unions with given byteorders and set memory to data + + for nested, data in ( + (BigEndianStructure, b'\0\0\0\1\0\0\0\2'), + (LittleEndianStructure, b'\1\0\0\0\2\0\0\0'), + ): + for parent in ( + BigEndianUnion, + LittleEndianUnion, + Union, + ): + class NestedStructure(nested): + _fields_ = [("x", c_uint32), + ("y", c_uint32)] + + class TestUnion(parent): + _fields_ = [("point", NestedStructure)] + + self.assertEqual(len(data), sizeof(TestUnion)) + ptr = POINTER(TestUnion) + s = cast(data, ptr)[0] + del ctypes._pointer_type_cache[TestUnion] + self.assertEqual(s.point.x, 1) + self.assertEqual(s.point.y, 2) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2021-04-20-16-48-07.bpo-33178.kSnWwb.rst b/Misc/NEWS.d/next/Library/2021-04-20-16-48-07.bpo-33178.kSnWwb.rst new file mode 100644 index 0000000000000..3646e4a707d6a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-04-20-16-48-07.bpo-33178.kSnWwb.rst @@ -0,0 +1 @@ +Added :class:`ctypes.BigEndianUnion` and :class:`ctypes.LittleEndianUnion` classes, as originally documented in the library docs but not yet implemented. From webhook-mailer at python.org Tue Mar 29 17:34:08 2022 From: webhook-mailer at python.org (asvetlov) Date: Tue, 29 Mar 2022 21:34:08 -0000 Subject: [Python-checkins] asyncio.Task: rename internal nested variable to don't hide another declaration from outer scope (GH-32181) Message-ID: https://github.com/python/cpython/commit/a5ba445322f723e04a3e901365512360a99c54d4 commit: a5ba445322f723e04a3e901365512360a99c54d4 branch: main author: Andrew Svetlov committer: asvetlov date: 2022-03-30T00:33:51+03:00 summary: asyncio.Task: rename internal nested variable to don't hide another declaration from outer scope (GH-32181) files: M Modules/_asynciomodule.c diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 5b8555e74b375..632a4465c224a 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -2707,22 +2707,22 @@ task_step_impl(TaskObj *task, PyObject *exc) /* The error is StopIteration and that means that the underlying coroutine has resolved */ - PyObject *res; + PyObject *tmp; if (task->task_must_cancel) { // Task is cancelled right before coro stops. task->task_must_cancel = 0; - res = future_cancel((FutureObj*)task, task->task_cancel_msg); + tmp = future_cancel((FutureObj*)task, task->task_cancel_msg); } else { - res = future_set_result((FutureObj*)task, result); + tmp = future_set_result((FutureObj*)task, result); } Py_DECREF(result); - if (res == NULL) { + if (tmp == NULL) { return NULL; } - Py_DECREF(res); + Py_DECREF(tmp); Py_RETURN_NONE; } @@ -2786,7 +2786,7 @@ task_step_impl(TaskObj *task, PyObject *exc) /* Check if `result` is FutureObj or TaskObj (and not a subclass) */ if (Future_CheckExact(result) || Task_CheckExact(result)) { PyObject *wrapper; - PyObject *res; + PyObject *tmp; FutureObj *fut = (FutureObj*)result; /* Check if `result` future is attached to a different loop */ @@ -2805,13 +2805,13 @@ task_step_impl(TaskObj *task, PyObject *exc) if (wrapper == NULL) { goto fail; } - res = future_add_done_callback( + tmp = future_add_done_callback( (FutureObj*)result, wrapper, task->task_context); Py_DECREF(wrapper); - if (res == NULL) { + if (tmp == NULL) { goto fail; } - Py_DECREF(res); + Py_DECREF(tmp); /* task._fut_waiter = result */ task->task_fut_waiter = result; /* no incref is necessary */ @@ -2853,7 +2853,7 @@ task_step_impl(TaskObj *task, PyObject *exc) if (o != NULL && o != Py_None) { /* `result` is a Future-compatible object */ PyObject *wrapper; - PyObject *res; + PyObject *tmp; int blocking = PyObject_IsTrue(o); Py_DECREF(o); @@ -2897,13 +2897,13 @@ task_step_impl(TaskObj *task, PyObject *exc) PyObject *stack[2]; stack[0] = wrapper; stack[1] = (PyObject *)task->task_context; - res = PyObject_Vectorcall(add_cb, stack, 1, context_kwname); + tmp = PyObject_Vectorcall(add_cb, stack, 1, context_kwname); Py_DECREF(add_cb); Py_DECREF(wrapper); - if (res == NULL) { + if (tmp == NULL) { goto fail; } - Py_DECREF(res); + Py_DECREF(tmp); /* task._fut_waiter = result */ task->task_fut_waiter = result; /* no incref is necessary */ From webhook-mailer at python.org Tue Mar 29 17:45:52 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 29 Mar 2022 21:45:52 -0000 Subject: [Python-checkins] bpo-42340: Document issues around KeyboardInterrupt (GH-23255) Message-ID: https://github.com/python/cpython/commit/66cde7c51a871a86cf8667adf4bd1d03e9b98eb1 commit: 66cde7c51a871a86cf8667adf4bd1d03e9b98eb1 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-29T14:45:47-07:00 summary: bpo-42340: Document issues around KeyboardInterrupt (GH-23255) Update documentation to note that in some circumstances, KeyboardInterrupt may cause code to enter an inconsistent state. Also document sample workaround to avoid KeyboardInterrupt, if needed. (cherry picked from commit d0906c90fcfbc4cfb9bb963eaa6bb152dd543b56) Co-authored-by: benfogle files: A Misc/NEWS.d/next/Documentation/2020-11-12-21-26-31.bpo-42340.apumUL.rst M Doc/library/exceptions.rst M Doc/library/signal.rst diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst index 2f97bb8131d78..50a3ff3452c99 100644 --- a/Doc/library/exceptions.rst +++ b/Doc/library/exceptions.rst @@ -246,6 +246,15 @@ The following exceptions are the exceptions that are usually raised. accidentally caught by code that catches :exc:`Exception` and thus prevent the interpreter from exiting. + .. note:: + + Catching a :exc:`KeyboardInterrupt` requires special consideration. + Because it can be raised at unpredictable points, it may, in some + circumstances, leave the running program in an inconsistent state. It is + generally best to allow :exc:`KeyboardInterrupt` to end the program as + quickly as possible or avoid raising it entirely. (See + :ref:`handlers-and-exceptions`.) + .. exception:: MemoryError diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst index 84a569d03eb29..11bdfc8e82831 100644 --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -46,6 +46,9 @@ This has consequences: arbitrary amount of time, regardless of any signals received. The Python signal handlers will be called when the calculation finishes. +* If the handler raises an exception, it will be raised "out of thin air" in + the main thread. See the :ref:`note below ` for a + discussion. .. _signals-and-threads: @@ -677,3 +680,70 @@ Do not set :const:`SIGPIPE`'s disposition to :const:`SIG_DFL` in order to avoid :exc:`BrokenPipeError`. Doing that would cause your program to exit unexpectedly also whenever any socket connection is interrupted while your program is still writing to it. + +.. _handlers-and-exceptions: + +Note on Signal Handlers and Exceptions +-------------------------------------- + +If a signal handler raises an exception, the exception will be propagated to +the main thread and may be raised after any :term:`bytecode` instruction. Most +notably, a :exc:`KeyboardInterrupt` may appear at any point during execution. +Most Python code, including the standard library, cannot be made robust against +this, and so a :exc:`KeyboardInterrupt` (or any other exception resulting from +a signal handler) may on rare occasions put the program in an unexpected state. + +To illustrate this issue, consider the following code:: + + class SpamContext: + def __init__(self): + self.lock = threading.Lock() + + def __enter__(self): + # If KeyboardInterrupt occurs here, everything is fine + self.lock.acquire() + # If KeyboardInterrupt occcurs here, __exit__ will not be called + ... + # KeyboardInterrupt could occur just before the function returns + + def __exit__(self, exc_type, exc_val, exc_tb): + ... + self.lock.release() + +For many programs, especially those that merely want to exit on +:exc:`KeyboardInterrupt`, this is not a problem, but applications that are +complex or require high reliability should avoid raising exceptions from signal +handlers. They should also avoid catching :exc:`KeyboardInterrupt` as a means +of gracefully shutting down. Instead, they should install their own +:const:`SIGINT` handler. Below is an example of an HTTP server that avoids +:exc:`KeyboardInterrupt`:: + + import signal + import socket + from selectors import DefaultSelector, EVENT_READ + from http.server import HTTPServer, SimpleHTTPRequestHandler + + interrupt_read, interrupt_write = socket.socketpair() + + def handler(signum, frame): + print('Signal handler called with signal', signum) + interrupt_write.send(b'\0') + signal.signal(signal.SIGINT, handler) + + def serve_forever(httpd): + sel = DefaultSelector() + sel.register(interrupt_read, EVENT_READ) + sel.register(httpd, EVENT_READ) + + while True: + for key, _ in sel.select(): + if key.fileobj == interrupt_read: + interrupt_read.recv(1) + return + if key.fileobj == httpd: + httpd.handle_request() + + print("Serving on port 8000") + httpd = HTTPServer(('', 8000), SimpleHTTPRequestHandler) + serve_forever(httpd) + print("Shutdown...") diff --git a/Misc/NEWS.d/next/Documentation/2020-11-12-21-26-31.bpo-42340.apumUL.rst b/Misc/NEWS.d/next/Documentation/2020-11-12-21-26-31.bpo-42340.apumUL.rst new file mode 100644 index 0000000000000..aa6857497383c --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-11-12-21-26-31.bpo-42340.apumUL.rst @@ -0,0 +1,3 @@ +Document that in some circumstances :exc:`KeyboardInterrupt` may cause the +code to enter an inconsistent state. Provided a sample workaround to avoid +it if needed. From webhook-mailer at python.org Tue Mar 29 17:48:15 2022 From: webhook-mailer at python.org (miss-islington) Date: Tue, 29 Mar 2022 21:48:15 -0000 Subject: [Python-checkins] bpo-42340: Document issues around KeyboardInterrupt (GH-23255) Message-ID: https://github.com/python/cpython/commit/c26af2bc531eb114c378cdad81935f6e838a7ee0 commit: c26af2bc531eb114c378cdad81935f6e838a7ee0 branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-29T14:48:10-07:00 summary: bpo-42340: Document issues around KeyboardInterrupt (GH-23255) Update documentation to note that in some circumstances, KeyboardInterrupt may cause code to enter an inconsistent state. Also document sample workaround to avoid KeyboardInterrupt, if needed. (cherry picked from commit d0906c90fcfbc4cfb9bb963eaa6bb152dd543b56) Co-authored-by: benfogle files: A Misc/NEWS.d/next/Documentation/2020-11-12-21-26-31.bpo-42340.apumUL.rst M Doc/library/exceptions.rst M Doc/library/signal.rst diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst index c4945679476a4..688eeb31b2ab0 100644 --- a/Doc/library/exceptions.rst +++ b/Doc/library/exceptions.rst @@ -234,6 +234,15 @@ The following exceptions are the exceptions that are usually raised. accidentally caught by code that catches :exc:`Exception` and thus prevent the interpreter from exiting. + .. note:: + + Catching a :exc:`KeyboardInterrupt` requires special consideration. + Because it can be raised at unpredictable points, it may, in some + circumstances, leave the running program in an inconsistent state. It is + generally best to allow :exc:`KeyboardInterrupt` to end the program as + quickly as possible or avoid raising it entirely. (See + :ref:`handlers-and-exceptions`.) + .. exception:: MemoryError diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst index e1daeff48ad8f..faea9d42a3fbd 100644 --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -46,6 +46,9 @@ This has consequences: arbitrary amount of time, regardless of any signals received. The Python signal handlers will be called when the calculation finishes. +* If the handler raises an exception, it will be raised "out of thin air" in + the main thread. See the :ref:`note below ` for a + discussion. .. _signals-and-threads: @@ -677,3 +680,70 @@ Do not set :const:`SIGPIPE`'s disposition to :const:`SIG_DFL` in order to avoid :exc:`BrokenPipeError`. Doing that would cause your program to exit unexpectedly also whenever any socket connection is interrupted while your program is still writing to it. + +.. _handlers-and-exceptions: + +Note on Signal Handlers and Exceptions +-------------------------------------- + +If a signal handler raises an exception, the exception will be propagated to +the main thread and may be raised after any :term:`bytecode` instruction. Most +notably, a :exc:`KeyboardInterrupt` may appear at any point during execution. +Most Python code, including the standard library, cannot be made robust against +this, and so a :exc:`KeyboardInterrupt` (or any other exception resulting from +a signal handler) may on rare occasions put the program in an unexpected state. + +To illustrate this issue, consider the following code:: + + class SpamContext: + def __init__(self): + self.lock = threading.Lock() + + def __enter__(self): + # If KeyboardInterrupt occurs here, everything is fine + self.lock.acquire() + # If KeyboardInterrupt occcurs here, __exit__ will not be called + ... + # KeyboardInterrupt could occur just before the function returns + + def __exit__(self, exc_type, exc_val, exc_tb): + ... + self.lock.release() + +For many programs, especially those that merely want to exit on +:exc:`KeyboardInterrupt`, this is not a problem, but applications that are +complex or require high reliability should avoid raising exceptions from signal +handlers. They should also avoid catching :exc:`KeyboardInterrupt` as a means +of gracefully shutting down. Instead, they should install their own +:const:`SIGINT` handler. Below is an example of an HTTP server that avoids +:exc:`KeyboardInterrupt`:: + + import signal + import socket + from selectors import DefaultSelector, EVENT_READ + from http.server import HTTPServer, SimpleHTTPRequestHandler + + interrupt_read, interrupt_write = socket.socketpair() + + def handler(signum, frame): + print('Signal handler called with signal', signum) + interrupt_write.send(b'\0') + signal.signal(signal.SIGINT, handler) + + def serve_forever(httpd): + sel = DefaultSelector() + sel.register(interrupt_read, EVENT_READ) + sel.register(httpd, EVENT_READ) + + while True: + for key, _ in sel.select(): + if key.fileobj == interrupt_read: + interrupt_read.recv(1) + return + if key.fileobj == httpd: + httpd.handle_request() + + print("Serving on port 8000") + httpd = HTTPServer(('', 8000), SimpleHTTPRequestHandler) + serve_forever(httpd) + print("Shutdown...") diff --git a/Misc/NEWS.d/next/Documentation/2020-11-12-21-26-31.bpo-42340.apumUL.rst b/Misc/NEWS.d/next/Documentation/2020-11-12-21-26-31.bpo-42340.apumUL.rst new file mode 100644 index 0000000000000..aa6857497383c --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-11-12-21-26-31.bpo-42340.apumUL.rst @@ -0,0 +1,3 @@ +Document that in some circumstances :exc:`KeyboardInterrupt` may cause the +code to enter an inconsistent state. Provided a sample workaround to avoid +it if needed. From webhook-mailer at python.org Tue Mar 29 18:07:24 2022 From: webhook-mailer at python.org (iritkatriel) Date: Tue, 29 Mar 2022 22:07:24 -0000 Subject: [Python-checkins] bpo-26120: do not exclude __future__ import in pydoc of the __future__ module itself (GH-32180) Message-ID: https://github.com/python/cpython/commit/63f32fae79e16e6dc71777bd3fcb623b2c3ff742 commit: 63f32fae79e16e6dc71777bd3fcb623b2c3ff742 branch: main author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com> date: 2022-03-29T23:07:15+01:00 summary: bpo-26120: do not exclude __future__ import in pydoc of the __future__ module itself (GH-32180) files: M Lib/pydoc.py M Lib/test/test_pydoc.py diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 7ae390852fa01..18b476ee660dc 100755 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -292,7 +292,7 @@ def visiblename(name, all=None, obj=None): if name.startswith('_') and hasattr(obj, '_fields'): return True # Ignore __future__ imports. - if name in _future_feature_names: + if obj is not __future__ and name in _future_feature_names: if isinstance(getattr(obj, name, None), __future__._Feature): return False if all is not None: diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py index e2dab1207172d..9c900c3e8ee0a 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -850,6 +850,23 @@ class B(A) for expected_line in expected_lines: self.assertIn(expected_line, as_text) + def test__future__imports(self): + # __future__ features are excluded from module help, + # except when it's the __future__ module itself + import __future__ + future_text, _ = get_pydoc_text(__future__) + future_html, _ = get_pydoc_html(__future__) + pydoc_mod_text, _ = get_pydoc_text(pydoc_mod) + pydoc_mod_html, _ = get_pydoc_html(pydoc_mod) + + for feature in __future__.all_feature_names: + txt = f"{feature} = _Feature" + html = f"{feature} = _Feature" + self.assertIn(txt, future_text) + self.assertIn(html, future_html) + self.assertNotIn(txt, pydoc_mod_text) + self.assertNotIn(html, pydoc_mod_html) + class PydocImportTest(PydocBaseTest): From webhook-mailer at python.org Wed Mar 30 02:35:36 2022 From: webhook-mailer at python.org (tiran) Date: Wed, 30 Mar 2022 06:35:36 -0000 Subject: [Python-checkins] bpo-46864: Suppress even more ob_shash deprecation warnings (GH-32176) Message-ID: https://github.com/python/cpython/commit/d8f530fe329c6bd9ad6e1a9db9aa32b465c2d67f commit: d8f530fe329c6bd9ad6e1a9db9aa32b465c2d67f branch: main author: Christian Heimes committer: tiran date: 2022-03-30T08:35:15+02:00 summary: bpo-46864: Suppress even more ob_shash deprecation warnings (GH-32176) files: M Python/pylifecycle.c diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 0754c1ac3bf40..273f6d62b2a20 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -95,11 +95,16 @@ __attribute__(( #endif +/* Suppress deprecation warning for PyBytesObject.ob_shash */ +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS _PyRuntimeState _PyRuntime #if defined(__linux__) && (defined(__GNUC__) || defined(__clang__)) __attribute__ ((section (".PyRuntime"))) #endif = _PyRuntimeState_INIT; +_Py_COMP_DIAG_POP + static int runtime_initialized = 0; PyStatus From webhook-mailer at python.org Wed Mar 30 07:00:34 2022 From: webhook-mailer at python.org (pablogsal) Date: Wed, 30 Mar 2022 11:00:34 -0000 Subject: [Python-checkins] bpo-47126: Update to canonical PEP URLs specified by PEP 676 (GH-32124) Message-ID: https://github.com/python/cpython/commit/6881ea936e277b1733bee581c4e59e3a5d53bb29 commit: 6881ea936e277b1733bee581c4e59e3a5d53bb29 branch: main author: Hugo van Kemenade committer: pablogsal date: 2022-03-30T12:00:27+01:00 summary: bpo-47126: Update to canonical PEP URLs specified by PEP 676 (GH-32124) files: A Misc/NEWS.d/next/Documentation/2022-03-26-12-20-16.bpo-47126.p6_Ovm.rst M Doc/c-api/code.rst M Doc/conf.py M Doc/distutils/sourcedist.rst M Doc/faq/general.rst M Doc/library/ast.rst M Doc/library/functools.rst M Doc/library/sqlite3.rst M Doc/requirements.txt M Doc/tools/templates/indexsidebar.html M Doc/whatsnew/2.0.rst M Doc/whatsnew/2.7.rst M Doc/whatsnew/3.4.rst M Doc/whatsnew/3.7.rst M Lib/dataclasses.py M Lib/distutils/command/build_ext.py M Lib/pydoc.py M Lib/secrets.py M Lib/test/test_docxmlrpc.py M Lib/weakref.py M Lib/xmlrpc/server.py M Parser/tokenizer.c M README.rst M Tools/scripts/stable_abi.py diff --git a/Doc/c-api/code.rst b/Doc/c-api/code.rst index 2b0cdf4324340..840b8426dbbdc 100644 --- a/Doc/c-api/code.rst +++ b/Doc/c-api/code.rst @@ -58,7 +58,7 @@ bound into a function. If you just need the line number of a frame, use :c:func:`PyFrame_GetLineNumber` instead. For efficiently iterating over the line numbers in a code object, use `the API described in PEP 626 - `_. + `_. .. c:function:: int PyCode_Addr2Location(PyObject *co, int byte_offset, int *start_line, int *start_column, int *end_line, int *end_column) diff --git a/Doc/conf.py b/Doc/conf.py index cbf201a314eec..1aadd961b6ef0 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -218,9 +218,7 @@ # ---------------------------- # Ignore certain URLs. -linkcheck_ignore = [r'https://bugs.python.org/(issue)?\d+', - # Ignore PEPs for now, they all have permanent redirects. - r'http://www.python.org/dev/peps/pep-\d+'] +linkcheck_ignore = [r'https://bugs.python.org/(issue)?\d+'] # Options for extensions diff --git a/Doc/distutils/sourcedist.rst b/Doc/distutils/sourcedist.rst index 7b1e22f824e8c..b55d01157f3ee 100644 --- a/Doc/distutils/sourcedist.rst +++ b/Doc/distutils/sourcedist.rst @@ -62,7 +62,7 @@ Notes: requires the :program:`compress` program. Notice that this format is now pending for deprecation and will be removed in the future versions of Python. (5) - deprecated by `PEP 527 `_; + deprecated by `PEP 527 `_; `PyPI `_ only accepts ``.zip`` and ``.tar.gz`` files. When using any ``tar`` format (``gztar``, ``bztar``, ``xztar``, ``ztar`` or diff --git a/Doc/faq/general.rst b/Doc/faq/general.rst index 7723114bcc18d..99534c2ebf6e1 100644 --- a/Doc/faq/general.rst +++ b/Doc/faq/general.rst @@ -310,7 +310,7 @@ The latest stable releases can always be found on the `Python download page `_. There are two production-ready versions of Python: 2.x and 3.x. The recommended version is 3.x, which is supported by most widely used libraries. Although 2.x is still widely used, `it is not -maintained anymore `_. +maintained anymore `_. How many people are using Python? --------------------------------- @@ -345,7 +345,7 @@ include Google, Yahoo, and Lucasfilm Ltd. What new developments are expected for Python in the future? ------------------------------------------------------------ -See https://www.python.org/dev/peps/ for the Python Enhancement Proposals +See https://peps.python.org/ for the Python Enhancement Proposals (PEPs). PEPs are design documents describing a suggested new feature for Python, providing a concise technical specification and a rationale. Look for a PEP titled "Python X.Y Release Schedule", where X.Y is a version that hasn't been diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index 6486ed4f21696..b10aa7cd50d17 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -1826,7 +1826,7 @@ Function and class definitions * ``bases`` is a list of nodes for explicitly specified base classes. * ``keywords`` is a list of :class:`keyword` nodes, principally for 'metaclass'. Other keywords will be passed to the metaclass, as per `PEP-3115 - `_. + `_. * ``starargs`` and ``kwargs`` are each a single node, as in a function call. starargs will be expanded to join the list of base classes, and kwargs will be passed to the metaclass. diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst index c78818bfab1a5..e23946a0a45e7 100644 --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@ -208,7 +208,7 @@ The :mod:`functools` module defines the following functions: @lru_cache(maxsize=32) def get_pep(num): 'Retrieve text of a Python Enhancement Proposal' - resource = 'https://www.python.org/dev/peps/pep-%04d/' % num + resource = 'https://peps.python.org/pep-%04d/' % num try: with urllib.request.urlopen(resource) as s: return s.read() diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index a1a7e1bd49e8e..e70d038e61d82 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -191,7 +191,7 @@ Module functions and constants | | | | connections and cursors | +------------------+-----------------+----------------------+-------------------------------+ - .. _threadsafety: https://www.python.org/dev/peps/pep-0249/#threadsafety + .. _threadsafety: https://peps.python.org/pep-0249/#threadsafety .. _SQLITE_THREADSAFE: https://sqlite.org/compile.html#threadsafe .. versionchanged:: 3.11 diff --git a/Doc/requirements.txt b/Doc/requirements.txt index 3b28495d4b4d0..f8a7f9db144c2 100644 --- a/Doc/requirements.txt +++ b/Doc/requirements.txt @@ -3,7 +3,7 @@ # Sphinx version is pinned so that new versions that introduce new warnings # won't suddenly cause build failures. Updating the version is fine as long # as no warnings are raised by doing so. -sphinx==4.2.0 +sphinx==4.5.0 blurb diff --git a/Doc/tools/templates/indexsidebar.html b/Doc/tools/templates/indexsidebar.html index f7bf6d8e49117..5986204256f4b 100644 --- a/Doc/tools/templates/indexsidebar.html +++ b/Doc/tools/templates/indexsidebar.html @@ -10,7 +10,7 @@

{% trans %}Docs by version{% endtrans %}

{% trans %}Other resources{% endtrans %}

    {# XXX: many of these should probably be merged in the main docs #} -
  • {% trans %}PEP Index{% endtrans %}
  • +
  • {% trans %}PEP Index{% endtrans %}
  • {% trans %}Beginner's Guide{% endtrans %}
  • {% trans %}Book List{% endtrans %}
  • {% trans %}Audio/Visual Talks{% endtrans %}
  • diff --git a/Doc/whatsnew/2.0.rst b/Doc/whatsnew/2.0.rst index 0e1cf1fd0ce46..325def51c274e 100644 --- a/Doc/whatsnew/2.0.rst +++ b/Doc/whatsnew/2.0.rst @@ -130,7 +130,7 @@ Guidelines": Read the rest of :pep:`1` for the details of the PEP editorial process, style, and format. PEPs are kept in the Python CVS tree on SourceForge, though they're not part of the Python 2.0 distribution, and are also available in HTML form from -https://www.python.org/dev/peps/. As of September 2000, there are 25 PEPS, ranging +https://peps.python.org/. As of September 2000, there are 25 PEPS, ranging from :pep:`201`, "Lockstep Iteration", to PEP 225, "Elementwise/Objectwise Operators". diff --git a/Doc/whatsnew/2.7.rst b/Doc/whatsnew/2.7.rst index abb65222ddd3d..999f148fa6b79 100644 --- a/Doc/whatsnew/2.7.rst +++ b/Doc/whatsnew/2.7.rst @@ -2681,7 +2681,7 @@ these commands by default, as long as, when invoked, they provide clear and simple directions on how to install them on that platform (usually using the system package manager). -__ https://www.python.org/dev/peps/pep-0477/#disabling-ensurepip-by-downstream-distributors +__ https://peps.python.org/pep-0477/#disabling-ensurepip-by-downstream-distributors Documentation Changes diff --git a/Doc/whatsnew/3.4.rst b/Doc/whatsnew/3.4.rst index 0405f2ba19346..f4ff143224196 100644 --- a/Doc/whatsnew/3.4.rst +++ b/Doc/whatsnew/3.4.rst @@ -220,7 +220,7 @@ these commands by default, as long as, when invoked, they provide clear and simple directions on how to install them on that platform (usually using the system package manager). -__ https://www.python.org/dev/peps/pep-0453/#recommendations-for-downstream-distributors +__ https://peps.python.org/pep-0453/#recommendations-for-downstream-distributors .. note:: diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index 5ce637a6c12c1..49246be57639d 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -353,7 +353,7 @@ module: The new functions return the number of nanoseconds as an integer value. -`Measurements `_ +`Measurements `_ show that on Linux and Windows the resolution of :func:`time.time_ns` is approximately 3 times better than that of :func:`time.time`. diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index 6be7c7b5de917..1acb7128f1a0c 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -298,7 +298,7 @@ def __repr__(self): # This is used to support the PEP 487 __set_name__ protocol in the # case where we're using a field that contains a descriptor as a # default value. For details on __set_name__, see - # https://www.python.org/dev/peps/pep-0487/#implementation-details. + # https://peps.python.org/pep-0487/#implementation-details. # # Note that in _process_class, this Field object is overwritten # with the default value, so the end result is a descriptor that diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py index 1a9bd1200f823..f287b349984ff 100644 --- a/Lib/distutils/command/build_ext.py +++ b/Lib/distutils/command/build_ext.py @@ -692,7 +692,7 @@ def get_export_symbols(self, ext): suffix = '_' + ext.name.split('.')[-1] try: # Unicode module name support as defined in PEP-489 - # https://www.python.org/dev/peps/pep-0489/#export-hook-name + # https://peps.python.org/pep-0489/#export-hook-name suffix.encode('ascii') except UnicodeEncodeError: suffix = 'U' + suffix.encode('punycode').replace(b'-', b'_').decode('ascii') diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 18b476ee660dc..12c2bb450e4f5 100755 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -701,10 +701,10 @@ def markup(self, text, escape=None, funcs={}, classes={}, methods={}): url = escape(all).replace('"', '"') results.append('%s' % (url, url)) elif rfc: - url = 'http://www.rfc-editor.org/rfc/rfc%d.txt' % int(rfc) + url = 'https://www.rfc-editor.org/rfc/rfc%d.txt' % int(rfc) results.append('%s' % (url, escape(all))) elif pep: - url = 'https://www.python.org/dev/peps/pep-%04d/' % int(pep) + url = 'https://peps.python.org/pep-%04d/' % int(pep) results.append('%s' % (url, escape(all))) elif selfdot: # Create a link for methods like 'self.method(...)' diff --git a/Lib/secrets.py b/Lib/secrets.py index a546efbdd4204..900381a89f53e 100644 --- a/Lib/secrets.py +++ b/Lib/secrets.py @@ -2,7 +2,7 @@ managing secrets such as account authentication, tokens, and similar. See PEP 506 for more information. -https://www.python.org/dev/peps/pep-0506/ +https://peps.python.org/pep-0506/ """ diff --git a/Lib/test/test_docxmlrpc.py b/Lib/test/test_docxmlrpc.py index 89d80091850f5..2ad422079b7f2 100644 --- a/Lib/test/test_docxmlrpc.py +++ b/Lib/test/test_docxmlrpc.py @@ -146,9 +146,9 @@ def test_autolinking(self): self.assertIn( (b'
    add(x, y)
    ' b'Add two instances together. This ' - b'follows ' + b'follows ' b'PEP008, but has nothing
    \nto do ' - b'with ' + b'with ' b'RFC1952. Case should matter: pEp008 ' b'and rFC1952.  Things
    \nthat start ' b'with http and ftp should be ' diff --git a/Lib/weakref.py b/Lib/weakref.py index 994ea8aa37de5..42aba654de549 100644 --- a/Lib/weakref.py +++ b/Lib/weakref.py @@ -2,7 +2,7 @@ This module is an implementation of PEP 205: -https://www.python.org/dev/peps/pep-0205/ +https://peps.python.org/pep-0205/ """ # Naming convention: Variables named "wr" are weak reference objects; diff --git a/Lib/xmlrpc/server.py b/Lib/xmlrpc/server.py index 4228a8535bfba..0c4b558045a9f 100644 --- a/Lib/xmlrpc/server.py +++ b/Lib/xmlrpc/server.py @@ -731,10 +731,10 @@ def markup(self, text, escape=None, funcs={}, classes={}, methods={}): url = escape(all).replace('"', '"') results.append('%s' % (url, url)) elif rfc: - url = 'http://www.rfc-editor.org/rfc/rfc%d.txt' % int(rfc) + url = 'https://www.rfc-editor.org/rfc/rfc%d.txt' % int(rfc) results.append('%s' % (url, escape(all))) elif pep: - url = 'https://www.python.org/dev/peps/pep-%04d/' % int(pep) + url = 'https://peps.python.org/pep-%04d/' % int(pep) results.append('%s' % (url, escape(all))) elif text[end:end+1] == '(': results.append(self.namelink(name, methods, funcs, classes)) diff --git a/Misc/NEWS.d/next/Documentation/2022-03-26-12-20-16.bpo-47126.p6_Ovm.rst b/Misc/NEWS.d/next/Documentation/2022-03-26-12-20-16.bpo-47126.p6_Ovm.rst new file mode 100644 index 0000000000000..4cbd0154eac4e --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-03-26-12-20-16.bpo-47126.p6_Ovm.rst @@ -0,0 +1 @@ +Update PEP URLs to :pep:`676`'s new canonical form. diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c index 0941bcaaecc62..13116d052ea59 100644 --- a/Parser/tokenizer.c +++ b/Parser/tokenizer.c @@ -523,7 +523,7 @@ ensure_utf8(char *line, struct tok_state *tok) "Non-UTF-8 code starting with '\\x%.2x' " "in file %U on line %i, " "but no encoding declared; " - "see https://python.org/dev/peps/pep-0263/ for details", + "see https://peps.python.org/pep-0263/ for details", badchar, tok->filename, tok->lineno + 1); return 0; } diff --git a/README.rst b/README.rst index 2b1bfadcccfa0..d5cf8205c6b88 100644 --- a/README.rst +++ b/README.rst @@ -228,7 +228,7 @@ If you have a proposal to change Python, you may want to send an email to the `comp.lang.python`_ or `python-ideas`_ mailing lists for initial feedback. A Python Enhancement Proposal (PEP) may be submitted if your idea gains ground. All current PEPs, as well as guidelines for submitting a new PEP, are listed at -`python.org/dev/peps/ `_. +`peps.python.org `_. .. _python-ideas: https://mail.python.org/mailman/listinfo/python-ideas/ .. _comp.lang.python: https://mail.python.org/mailman/listinfo/python-list diff --git a/Tools/scripts/stable_abi.py b/Tools/scripts/stable_abi.py index 04b1f78e00adb..2d951788d12c4 100755 --- a/Tools/scripts/stable_abi.py +++ b/Tools/scripts/stable_abi.py @@ -656,7 +656,7 @@ def main(): And in PEP 384: - https://www.python.org/dev/peps/pep-0384/ + https://peps.python.org/pep-0384/ """) From webhook-mailer at python.org Wed Mar 30 07:10:25 2022 From: webhook-mailer at python.org (pablogsal) Date: Wed, 30 Mar 2022 11:10:25 -0000 Subject: [Python-checkins] bpo-34861: Make cumtime the default sorting key for cProfile (GH-31929) Message-ID: https://github.com/python/cpython/commit/75eee1d57eb28283a8682a660d9949afc89fd010 commit: 75eee1d57eb28283a8682a660d9949afc89fd010 branch: main author: Dani?l van Noord <13665637+DanielNoord at users.noreply.github.com> committer: pablogsal date: 2022-03-30T12:10:10+01:00 summary: bpo-34861: Make cumtime the default sorting key for cProfile (GH-31929) files: A Misc/NEWS.d/next/Library/2022-03-16-08-49-12.bpo-34861.p8ugVg.rst M Doc/library/profile.rst M Lib/cProfile.py diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index cf324a57e79fd..5278d1a58802e 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -66,22 +66,23 @@ your system.) The above action would run :func:`re.compile` and print profile results like the following:: - 197 function calls (192 primitive calls) in 0.002 seconds + 214 function calls (207 primitive calls) in 0.002 seconds - Ordered by: standard name + Ordered by: cumulative time ncalls tottime percall cumtime percall filename:lineno(function) + 1 0.000 0.000 0.002 0.002 {built-in method builtins.exec} 1 0.000 0.000 0.001 0.001 :1() - 1 0.000 0.000 0.001 0.001 re.py:212(compile) - 1 0.000 0.000 0.001 0.001 re.py:268(_compile) - 1 0.000 0.000 0.000 0.000 sre_compile.py:172(_compile_charset) - 1 0.000 0.000 0.000 0.000 sre_compile.py:201(_optimize_charset) - 4 0.000 0.000 0.000 0.000 sre_compile.py:25(_identityfunction) - 3/1 0.000 0.000 0.000 0.000 sre_compile.py:33(_compile) - -The first line indicates that 197 calls were monitored. Of those calls, 192 + 1 0.000 0.000 0.001 0.001 re.py:250(compile) + 1 0.000 0.000 0.001 0.001 re.py:289(_compile) + 1 0.000 0.000 0.000 0.000 sre_compile.py:759(compile) + 1 0.000 0.000 0.000 0.000 sre_parse.py:937(parse) + 1 0.000 0.000 0.000 0.000 sre_compile.py:598(_code) + 1 0.000 0.000 0.000 0.000 sre_parse.py:435(_parse_sub) + +The first line indicates that 214 calls were monitored. Of those calls, 207 were :dfn:`primitive`, meaning that the call was not induced via recursion. The -next line: ``Ordered by: standard name``, indicates that the text string in the +next line: ``Ordered by: cumulative name``, indicates that the text string in the far right column was used to sort the output. The column headings include: ncalls diff --git a/Lib/cProfile.py b/Lib/cProfile.py index 22a7d0aade855..9fc9788302084 100755 --- a/Lib/cProfile.py +++ b/Lib/cProfile.py @@ -140,7 +140,7 @@ def main(): help="Save stats to ", default=None) parser.add_option('-s', '--sort', dest="sort", help="Sort order when printing to stdout, based on pstats.Stats class", - default=-1, + default=2, choices=sorted(pstats.Stats.sort_arg_dict_default)) parser.add_option('-m', dest="module", action="store_true", help="Profile a library module", default=False) diff --git a/Misc/NEWS.d/next/Library/2022-03-16-08-49-12.bpo-34861.p8ugVg.rst b/Misc/NEWS.d/next/Library/2022-03-16-08-49-12.bpo-34861.p8ugVg.rst new file mode 100644 index 0000000000000..0277ffbf5508d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-16-08-49-12.bpo-34861.p8ugVg.rst @@ -0,0 +1 @@ +Made cumtime the default sorting key for cProfile From webhook-mailer at python.org Wed Mar 30 08:11:53 2022 From: webhook-mailer at python.org (markshannon) Date: Wed, 30 Mar 2022 12:11:53 -0000 Subject: [Python-checkins] Merge deoptimization blocks in interpreter (GH-32155) Message-ID: https://github.com/python/cpython/commit/04acfa94bb383cce973739478a7b58ab20ab47f4 commit: 04acfa94bb383cce973739478a7b58ab20ab47f4 branch: main author: Mark Shannon committer: markshannon date: 2022-03-30T13:11:33+01:00 summary: Merge deoptimization blocks in interpreter (GH-32155) files: M Include/internal/pycore_code.h M Python/ceval.c M Python/specialize.c diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index 0f6613b6c1e3d..8c868bcd5b5cb 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -110,6 +110,8 @@ _PyCode_Warmup(PyCodeObject *code) } } +extern uint8_t _PyOpcode_Adaptive[256]; + extern Py_ssize_t _Py_QuickenedCount; // Borrowed references to common callables: diff --git a/Python/ceval.c b/Python/ceval.c index 4b9d33404bb78..a7b377724bb54 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1431,7 +1431,7 @@ eval_frame_handle_pending(PyThreadState *tstate) #define JUMP_TO_INSTRUCTION(op) goto PREDICT_ID(op) -#define DEOPT_IF(cond, instname) if (cond) { goto instname ## _miss; } +#define DEOPT_IF(cond, instname) if (cond) { goto miss; } #define GLOBALS() frame->f_globals @@ -2551,18 +2551,18 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } Py_DECREF(v); if (gen_status == PYGEN_ERROR) { - assert (retval == NULL); + assert(retval == NULL); goto error; } if (gen_status == PYGEN_RETURN) { - assert (retval != NULL); + assert(retval != NULL); Py_DECREF(receiver); SET_TOP(retval); JUMPBY(oparg); DISPATCH(); } - assert (gen_status == PYGEN_NEXT); - assert (retval != NULL); + assert(gen_status == PYGEN_NEXT); + assert(retval != NULL); PUSH(retval); DISPATCH(); } @@ -4595,7 +4595,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } TARGET(CALL) { - PREDICTED(CALL); int is_meth; call_function: is_meth = is_method(stack_pointer, oparg); @@ -5524,34 +5523,25 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int /* Specialization misses */ -#define MISS_WITH_INLINE_CACHE(opname) \ -opname ## _miss: \ - { \ - STAT_INC(opcode, miss); \ - STAT_INC(opname, miss); \ - /* The counter is always the first cache entry: */ \ - _Py_CODEUNIT *counter = (_Py_CODEUNIT *)next_instr; \ - *counter -= 1; \ - if (*counter == 0) { \ - _Py_SET_OPCODE(next_instr[-1], opname ## _ADAPTIVE); \ - STAT_INC(opname, deopt); \ - *counter = ADAPTIVE_CACHE_BACKOFF; \ - } \ - JUMP_TO_INSTRUCTION(opname); \ +miss: + { + STAT_INC(opcode, miss); + opcode = _PyOpcode_Deopt[opcode]; + STAT_INC(opcode, miss); + /* The counter is always the first cache entry: */ + _Py_CODEUNIT *counter = (_Py_CODEUNIT *)next_instr; + *counter -= 1; + if (*counter == 0) { + int adaptive_opcode = _PyOpcode_Adaptive[opcode]; + assert(adaptive_opcode); + _Py_SET_OPCODE(next_instr[-1], adaptive_opcode); + STAT_INC(opcode, deopt); + *counter = ADAPTIVE_CACHE_BACKOFF; + } + next_instr--; + DISPATCH_GOTO(); } -MISS_WITH_INLINE_CACHE(LOAD_ATTR) -MISS_WITH_INLINE_CACHE(STORE_ATTR) -MISS_WITH_INLINE_CACHE(LOAD_GLOBAL) -MISS_WITH_INLINE_CACHE(LOAD_METHOD) -MISS_WITH_INLINE_CACHE(PRECALL) -MISS_WITH_INLINE_CACHE(CALL) -MISS_WITH_INLINE_CACHE(BINARY_OP) -MISS_WITH_INLINE_CACHE(COMPARE_OP) -MISS_WITH_INLINE_CACHE(BINARY_SUBSCR) -MISS_WITH_INLINE_CACHE(UNPACK_SEQUENCE) -MISS_WITH_INLINE_CACHE(STORE_SUBSCR) - binary_subscr_dict_error: { PyObject *sub = POP(); @@ -6717,7 +6707,7 @@ call_trace(Py_tracefunc func, PyObject *obj, int old_what = tstate->tracing_what; tstate->tracing_what = what; PyThreadState_EnterTracing(tstate); - assert (frame->f_lasti >= 0); + assert(frame->f_lasti >= 0); initialize_trace_info(&tstate->trace_info, frame); f->f_lineno = _PyCode_CheckLineNumber(frame->f_lasti*sizeof(_Py_CODEUNIT), &tstate->trace_info.bounds); result = func(obj, f, what, arg); diff --git a/Python/specialize.c b/Python/specialize.c index 5839d7629466d..244318a609e66 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -17,7 +17,7 @@ /* Map from opcode to adaptive opcode. Values of zero are ignored. */ -static uint8_t adaptive_opcodes[256] = { +uint8_t _PyOpcode_Adaptive[256] = { [LOAD_ATTR] = LOAD_ATTR_ADAPTIVE, [LOAD_GLOBAL] = LOAD_GLOBAL_ADAPTIVE, [LOAD_METHOD] = LOAD_METHOD_ADAPTIVE, @@ -143,7 +143,7 @@ print_spec_stats(FILE *out, OpcodeStats *stats) * even though we don't specialize them yet. */ fprintf(out, "opcode[%d].specializable : 1\n", FOR_ITER); for (int i = 0; i < 256; i++) { - if (adaptive_opcodes[i]) { + if (_PyOpcode_Adaptive[i]) { fprintf(out, "opcode[%d].specializable : 1\n", i); } PRINT_STAT(i, specialization.success); @@ -259,7 +259,7 @@ _PyCode_Quicken(PyCodeObject *code) _Py_CODEUNIT *instructions = _PyCode_CODE(code); for (int i = 0; i < Py_SIZE(code); i++) { int opcode = _Py_OPCODE(instructions[i]); - uint8_t adaptive_opcode = adaptive_opcodes[opcode]; + uint8_t adaptive_opcode = _PyOpcode_Adaptive[opcode]; if (adaptive_opcode) { _Py_SET_OPCODE(instructions[i], adaptive_opcode); // Make sure the adaptive counter is zero: From webhook-mailer at python.org Wed Mar 30 08:15:14 2022 From: webhook-mailer at python.org (asvetlov) Date: Wed, 30 Mar 2022 12:15:14 -0000 Subject: [Python-checkins] bpo-39622: Interrupt the main asyncio task on Ctrl+C (GH-32105) Message-ID: https://github.com/python/cpython/commit/f08a191882f75bb79d42a49039892105b2212fb9 commit: f08a191882f75bb79d42a49039892105b2212fb9 branch: main author: Andrew Svetlov committer: asvetlov date: 2022-03-30T15:15:06+03:00 summary: bpo-39622: Interrupt the main asyncio task on Ctrl+C (GH-32105) Co-authored-by: Kumar Aditya <59607654+kumaraditya303 at users.noreply.github.com> files: A Misc/NEWS.d/next/Library/2022-03-25-01-27-25.bpo-39622.ieBIMp.rst M Doc/library/asyncio-runner.rst M Lib/asyncio/runners.py M Lib/test/test_asyncio/test_runners.py diff --git a/Doc/library/asyncio-runner.rst b/Doc/library/asyncio-runner.rst index 31becf192ada3..a526b459f7474 100644 --- a/Doc/library/asyncio-runner.rst +++ b/Doc/library/asyncio-runner.rst @@ -119,3 +119,30 @@ Runner context manager Embedded *loop* and *context* are created at the :keyword:`with` body entering or the first call of :meth:`run` or :meth:`get_loop`. + + +Handling Keyboard Interruption +============================== + +.. versionadded:: 3.11 + +When :const:`signal.SIGINT` is raised by :kbd:`Ctrl-C`, :exc:`KeyboardInterrupt` +exception is raised in the main thread by default. However this doesn't work with +:mod:`asyncio` because it can interrupt asyncio internals and can hang the program from +exiting. + +To mitigate this issue, :mod:`asyncio` handles :const:`signal.SIGINT` as follows: + +1. :meth:`asyncio.Runner.run` installs a custom :const:`signal.SIGINT` handler before + any user code is executed and removes it when exiting from the function. +2. The :class:`~asyncio.Runner` creates the main task for the passed coroutine for its + execution. +3. When :const:`signal.SIGINT` is raised by :kbd:`Ctrl-C`, the custom signal handler + cancels the main task by calling :meth:`asyncio.Task.cancel` which raises + :exc:`asyncio.CancelledError` inside the the main task. This causes the Python stack + to unwind, ``try/except`` and ``try/finally`` blocks can be used for resource + cleanup. After the main task is cancelled, :meth:`asyncio.Runner.run` raises + :exc:`KeyboardInterrupt`. +4. A user could write a tight loop which cannot be interrupted by + :meth:`asyncio.Task.cancel`, in which case the second following :kbd:`Ctrl-C` + immediately raises the :exc:`KeyboardInterrupt` without cancelling the main task. diff --git a/Lib/asyncio/runners.py b/Lib/asyncio/runners.py index 768a403a85bee..2bb9ca331fd68 100644 --- a/Lib/asyncio/runners.py +++ b/Lib/asyncio/runners.py @@ -2,8 +2,13 @@ import contextvars import enum +import functools +import threading +import signal +import sys from . import coroutines from . import events +from . import exceptions from . import tasks @@ -47,6 +52,7 @@ def __init__(self, *, debug=None, loop_factory=None): self._loop_factory = loop_factory self._loop = None self._context = None + self._interrupt_count = 0 def __enter__(self): self._lazy_init() @@ -89,7 +95,28 @@ def run(self, coro, *, context=None): if context is None: context = self._context task = self._loop.create_task(coro, context=context) - return self._loop.run_until_complete(task) + + if (threading.current_thread() is threading.main_thread() + and signal.getsignal(signal.SIGINT) is signal.default_int_handler + ): + sigint_handler = functools.partial(self._on_sigint, main_task=task) + signal.signal(signal.SIGINT, sigint_handler) + else: + sigint_handler = None + + self._interrupt_count = 0 + try: + return self._loop.run_until_complete(task) + except exceptions.CancelledError: + if self._interrupt_count > 0 and task.uncancel() == 0: + raise KeyboardInterrupt() + else: + raise # CancelledError + finally: + if (sigint_handler is not None + and signal.getsignal(signal.SIGINT) is sigint_handler + ): + signal.signal(signal.SIGINT, signal.default_int_handler) def _lazy_init(self): if self._state is _State.CLOSED: @@ -105,6 +132,14 @@ def _lazy_init(self): self._context = contextvars.copy_context() self._state = _State.INITIALIZED + def _on_sigint(self, signum, frame, main_task): + self._interrupt_count += 1 + if self._interrupt_count == 1 and not main_task.done(): + main_task.cancel() + # wakeup loop if it is blocked by select() with long timeout + self._loop.call_soon_threadsafe(lambda: None) + return + raise KeyboardInterrupt() def run(main, *, debug=None): diff --git a/Lib/test/test_asyncio/test_runners.py b/Lib/test/test_asyncio/test_runners.py index 94f26797b3309..42aa07a0e089d 100644 --- a/Lib/test/test_asyncio/test_runners.py +++ b/Lib/test/test_asyncio/test_runners.py @@ -1,7 +1,9 @@ +import _thread import asyncio import contextvars import gc import re +import threading import unittest from unittest import mock @@ -12,6 +14,10 @@ def tearDownModule(): asyncio.set_event_loop_policy(None) +def interrupt_self(): + _thread.interrupt_main() + + class TestPolicy(asyncio.AbstractEventLoopPolicy): def __init__(self, loop_factory): @@ -298,7 +304,7 @@ async def get_context(): self.assertEqual(2, runner.run(get_context()).get(cvar)) - def test_recursine_run(self): + def test_recursive_run(self): async def g(): pass @@ -318,6 +324,57 @@ async def f(): ): runner.run(f()) + def test_interrupt_call_soon(self): + # The only case when task is not suspended by waiting a future + # or another task + assert threading.current_thread() is threading.main_thread() + + async def coro(): + with self.assertRaises(asyncio.CancelledError): + while True: + await asyncio.sleep(0) + raise asyncio.CancelledError() + + with asyncio.Runner() as runner: + runner.get_loop().call_later(0.1, interrupt_self) + with self.assertRaises(KeyboardInterrupt): + runner.run(coro()) + + def test_interrupt_wait(self): + # interrupting when waiting a future cancels both future and main task + assert threading.current_thread() is threading.main_thread() + + async def coro(fut): + with self.assertRaises(asyncio.CancelledError): + await fut + raise asyncio.CancelledError() + + with asyncio.Runner() as runner: + fut = runner.get_loop().create_future() + runner.get_loop().call_later(0.1, interrupt_self) + + with self.assertRaises(KeyboardInterrupt): + runner.run(coro(fut)) + + self.assertTrue(fut.cancelled()) + + def test_interrupt_cancelled_task(self): + # interrupting cancelled main task doesn't raise KeyboardInterrupt + assert threading.current_thread() is threading.main_thread() + + async def subtask(task): + await asyncio.sleep(0) + task.cancel() + interrupt_self() + + async def coro(): + asyncio.create_task(subtask(asyncio.current_task())) + await asyncio.sleep(10) + + with asyncio.Runner() as runner: + with self.assertRaises(asyncio.CancelledError): + runner.run(coro()) + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2022-03-25-01-27-25.bpo-39622.ieBIMp.rst b/Misc/NEWS.d/next/Library/2022-03-25-01-27-25.bpo-39622.ieBIMp.rst new file mode 100644 index 0000000000000..25c6aa3703ad2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-25-01-27-25.bpo-39622.ieBIMp.rst @@ -0,0 +1 @@ +Handle Ctrl+C in asyncio programs to interrupt the main task. From webhook-mailer at python.org Wed Mar 30 08:28:41 2022 From: webhook-mailer at python.org (asvetlov) Date: Wed, 30 Mar 2022 12:28:41 -0000 Subject: [Python-checkins] Replace with_traceback() with exception chaining and reraising (GH-32074) Message-ID: https://github.com/python/cpython/commit/a03a09e068435f47d02649dda93988dc44ffaaf1 commit: a03a09e068435f47d02649dda93988dc44ffaaf1 branch: main author: Oleg Iarygin committer: asvetlov date: 2022-03-30T15:28:20+03:00 summary: Replace with_traceback() with exception chaining and reraising (GH-32074) files: A Misc/NEWS.d/next/Library/2022-03-23-13-55-41.bpo-47099.P6quRP.rst A Misc/NEWS.d/next/Library/2022-03-23-14-16-38.bpo-47099.2raait.rst M Lib/test/support/socket_helper.py M Lib/urllib/parse.py M Lib/urllib/request.py M Lib/wsgiref/handlers.py diff --git a/Lib/test/support/socket_helper.py b/Lib/test/support/socket_helper.py index b51677383ebc5..0ee7a5d69a1b3 100644 --- a/Lib/test/support/socket_helper.py +++ b/Lib/test/support/socket_helper.py @@ -256,7 +256,7 @@ def filter_error(err): err = a[0] # The error can also be wrapped as args[1]: # except socket.error as msg: - # raise OSError('socket error', msg).with_traceback(sys.exc_info()[2]) + # raise OSError('socket error', msg) from msg elif len(a) >= 2 and isinstance(a[1], OSError): err = a[1] else: diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py index 67ba308c409a2..d70a6943f0a73 100644 --- a/Lib/urllib/parse.py +++ b/Lib/urllib/parse.py @@ -940,10 +940,9 @@ def urlencode(query, doseq=False, safe='', encoding=None, errors=None, # but that's a minor nit. Since the original implementation # allowed empty dicts that type of behavior probably should be # preserved for consistency - except TypeError: - ty, va, tb = sys.exc_info() + except TypeError as err: raise TypeError("not a valid non-string sequence " - "or mapping object").with_traceback(tb) + "or mapping object") from err l = [] if not doseq: diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index 02f96265a8900..84997f268c930 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -1579,8 +1579,7 @@ def ftp_open(self, req): headers = email.message_from_string(headers) return addinfourl(fp, headers, req.full_url) except ftplib.all_errors as exp: - exc = URLError('ftp error: %r' % exp) - raise exc.with_traceback(sys.exc_info()[2]) + raise URLError(f'ftp error: {exp}') from exp def connect_ftp(self, user, passwd, host, port, dirs, timeout): return ftpwrapper(user, passwd, host, port, dirs, timeout, @@ -1791,7 +1790,7 @@ def open(self, fullurl, data=None): except (HTTPError, URLError): raise except OSError as msg: - raise OSError('socket error', msg).with_traceback(sys.exc_info()[2]) + raise OSError('socket error', msg) from msg def open_unknown(self, fullurl, data=None): """Overridable interface to open unknown URL type.""" @@ -2093,7 +2092,7 @@ def open_ftp(self, url): headers = email.message_from_string(headers) return addinfourl(fp, headers, "ftp:" + url) except ftperrors() as exp: - raise URLError('ftp error %r' % exp).with_traceback(sys.exc_info()[2]) + raise URLError(f'ftp error: {exp}') from exp def open_data(self, url, data=None): """Use "data" URL.""" @@ -2443,8 +2442,7 @@ def retrfile(self, file, type): conn, retrlen = self.ftp.ntransfercmd(cmd) except ftplib.error_perm as reason: if str(reason)[:3] != '550': - raise URLError('ftp error: %r' % reason).with_traceback( - sys.exc_info()[2]) + raise URLError(f'ftp error: {reason}') from reason if not conn: # Set transfer mode to ASCII! self.ftp.voidcmd('TYPE A') diff --git a/Lib/wsgiref/handlers.py b/Lib/wsgiref/handlers.py index 31360e58785ac..6623b700537cf 100644 --- a/Lib/wsgiref/handlers.py +++ b/Lib/wsgiref/handlers.py @@ -228,8 +228,7 @@ def start_response(self, status, headers,exc_info=None): if exc_info: try: if self.headers_sent: - # Re-raise original exception if headers sent - raise exc_info[0](exc_info[1]).with_traceback(exc_info[2]) + raise finally: exc_info = None # avoid dangling circular ref elif self.headers is not None: diff --git a/Misc/NEWS.d/next/Library/2022-03-23-13-55-41.bpo-47099.P6quRP.rst b/Misc/NEWS.d/next/Library/2022-03-23-13-55-41.bpo-47099.P6quRP.rst new file mode 100644 index 0000000000000..fa2c87e941e8b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-23-13-55-41.bpo-47099.P6quRP.rst @@ -0,0 +1,3 @@ +Exception chaining is changed from +:func:`Exception.with_traceback`/:func:`sys.exc_info` to :pep:`3134`. +Patch by Oleg Iarygin. diff --git a/Misc/NEWS.d/next/Library/2022-03-23-14-16-38.bpo-47099.2raait.rst b/Misc/NEWS.d/next/Library/2022-03-23-14-16-38.bpo-47099.2raait.rst new file mode 100644 index 0000000000000..785e53c123f91 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-23-14-16-38.bpo-47099.2raait.rst @@ -0,0 +1,5 @@ +All :exc:`URLError` exception messages raised in +:class:`urllib.request.URLopener` now contain a colon between ``ftp error`` +and the rest of the message. Previously, +:func:`~urllib.request.URLopener.open_ftp` missed the colon. Patch by Oleg +Iarygin. From webhook-mailer at python.org Wed Mar 30 13:32:00 2022 From: webhook-mailer at python.org (zooba) Date: Wed, 30 Mar 2022 17:32:00 -0000 Subject: [Python-checkins] bpo-46775: OSError should call winerror_to_errno unconditionally on Windows (GH-32179) Message-ID: https://github.com/python/cpython/commit/d0c67ea0645b7ad37b867c167882a346a24de641 commit: d0c67ea0645b7ad37b867c167882a346a24de641 branch: main author: Dong-hee Na committer: zooba date: 2022-03-30T18:31:33+01:00 summary: bpo-46775: OSError should call winerror_to_errno unconditionally on Windows (GH-32179) files: A Misc/NEWS.d/next/Core and Builtins/2022-03-30-02-36-25.bpo-46775.e3Oxqf.rst M Objects/exceptions.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-30-02-36-25.bpo-46775.e3Oxqf.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-30-02-36-25.bpo-46775.e3Oxqf.rst new file mode 100644 index 0000000000000..da56ecd89367b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-30-02-36-25.bpo-46775.e3Oxqf.rst @@ -0,0 +1,3 @@ +Some Windows system error codes(>= 10000) are now mapped into +the correct errno and may now raise a subclass of :exc:`OSError`. +Patch by Dong-hee Na. diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 9dbbd40f1de1c..df10a3c2416e3 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -1634,14 +1634,7 @@ oserror_parse_args(PyObject **p_args, winerrcode = PyLong_AsLong(*winerror); if (winerrcode == -1 && PyErr_Occurred()) return -1; - /* Set errno to the corresponding POSIX errno (overriding - first argument). Windows Socket error codes (>= 10000) - have the same value as their POSIX counterparts. - */ - if (winerrcode < 10000) - errcode = winerror_to_errno(winerrcode); - else - errcode = winerrcode; + errcode = winerror_to_errno(winerrcode); *myerrno = PyLong_FromLong(errcode); if (!*myerrno) return -1; From webhook-mailer at python.org Wed Mar 30 14:34:38 2022 From: webhook-mailer at python.org (brettcannon) Date: Wed, 30 Mar 2022 18:34:38 -0000 Subject: [Python-checkins] Add CODEOWNERS entry for pathlib (GH-32202) Message-ID: https://github.com/python/cpython/commit/795c00b91cbc208969302e9e16a269c2049af3e9 commit: 795c00b91cbc208969302e9e16a269c2049af3e9 branch: main author: Brett Cannon committer: brettcannon date: 2022-03-30T11:34:29-07:00 summary: Add CODEOWNERS entry for pathlib (GH-32202) files: M .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 33a3ebb3a3870..62ee6f89cda67 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -146,3 +146,6 @@ Lib/ast.py @isidentical # macOS /Mac/ @python/macos-team **/*osx_support* @python/macos-team + +# pathlib +**/*pathlib* @brettcannon From webhook-mailer at python.org Wed Mar 30 15:28:53 2022 From: webhook-mailer at python.org (miss-islington) Date: Wed, 30 Mar 2022 19:28:53 -0000 Subject: [Python-checkins] bpo-47162: Add call trampoline to mitigate bad fpcasts on Emscripten (GH-32189) Message-ID: https://github.com/python/cpython/commit/581c4434de62d9d36392f10e65866c081fb18d71 commit: 581c4434de62d9d36392f10e65866c081fb18d71 branch: main author: Christian Heimes committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-30T12:28:33-07:00 summary: bpo-47162: Add call trampoline to mitigate bad fpcasts on Emscripten (GH-32189) files: A Misc/NEWS.d/next/Core and Builtins/2022-03-30-13-13-25.bpo-47162.yDJMUm.rst M Include/internal/pycore_object.h M Objects/call.c M Objects/descrobject.c M Objects/methodobject.c M Python/import.c M Python/importdl.c M Python/importdl.h diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 06671b5057afa..177b06e2dd4f7 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -242,6 +242,33 @@ extern PyObject* _PyType_GetSubclasses(PyTypeObject *); PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, PyObject *); +/* C function call trampolines to mitigate bad function pointer casts. + * + * Typical native ABIs ignore additional arguments or fill in missing + * values with 0/NULL in function pointer cast. Compilers do not show + * warnings when a function pointer is explicitly casted to an + * incompatible type. + * + * Bad fpcasts are an issue in WebAssembly. WASM's indirect_call has strict + * function signature checks. Argument count, types, and return type must + * match. + * + * Third party code unintentionally rely on problematic fpcasts. The call + * trampoline mitigates common occurences of bad fpcasts on Emscripten. + */ +#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE) +#define _PyCFunction_TrampolineCall(meth, self, args) \ + _PyCFunctionWithKeywords_TrampolineCall( \ + (*(PyCFunctionWithKeywords)(void(*)(void))meth), self, args, NULL) +extern PyObject* _PyCFunctionWithKeywords_TrampolineCall( + PyCFunctionWithKeywords meth, PyObject *, PyObject *, PyObject *); +#else +#define _PyCFunction_TrampolineCall(meth, self, args) \ + (meth)((self), (args)) +#define _PyCFunctionWithKeywords_TrampolineCall(meth, self, args, kw) \ + (meth)((self), (args), (kw)) +#endif // __EMSCRIPTEN__ && PY_CALL_TRAMPOLINE + #ifdef __cplusplus } #endif diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-30-13-13-25.bpo-47162.yDJMUm.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-30-13-13-25.bpo-47162.yDJMUm.rst new file mode 100644 index 0000000000000..7ecbfb37cd17b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-30-13-13-25.bpo-47162.yDJMUm.rst @@ -0,0 +1,4 @@ +WebAssembly cannot deal with bad function pointer casts (different count +or types of arguments). Python can now use call trampolines to mitigate +the problem. Define :c:macro:`PY_CALL_TRAMPOLINE` to enable call +trampolines. diff --git a/Objects/call.c b/Objects/call.c index cf8fa1eeffe1c..448476223adc0 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -211,7 +211,8 @@ _PyObject_MakeTpCall(PyThreadState *tstate, PyObject *callable, PyObject *result = NULL; if (_Py_EnterRecursiveCall(tstate, " while calling a Python object") == 0) { - result = call(callable, argstuple, kwdict); + result = _PyCFunctionWithKeywords_TrampolineCall( + (PyCFunctionWithKeywords)call, callable, argstuple, kwdict); _Py_LeaveRecursiveCall(tstate); } diff --git a/Objects/descrobject.c b/Objects/descrobject.c index e255d4ae5f86f..7cbfe8d9c1940 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -13,6 +13,25 @@ class property "propertyobject *" "&PyProperty_Type" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=556352653fd4c02e]*/ +// see pycore_object.h +#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE) +#include +EM_JS(PyObject*, descr_set_trampoline_call, (setter set, PyObject *obj, PyObject *value, void *closure), { + return wasmTable.get(set)(obj, value, closure); +}); + +EM_JS(PyObject*, descr_get_trampoline_call, (getter get, PyObject *obj, void *closure), { + return wasmTable.get(get)(obj, closure); +}); +#else +#define descr_set_trampoline_call(set, obj, value, closure) \ + (set)((obj), (value), (closure)) + +#define descr_get_trampoline_call(get, obj, closure) \ + (get)((obj), (closure)) + +#endif // __EMSCRIPTEN__ && PY_CALL_TRAMPOLINE + static void descr_dealloc(PyDescrObject *descr) { @@ -180,7 +199,8 @@ getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type) return NULL; } if (descr->d_getset->get != NULL) - return descr->d_getset->get(obj, descr->d_getset->closure); + return descr_get_trampoline_call( + descr->d_getset->get, obj, descr->d_getset->closure); PyErr_Format(PyExc_AttributeError, "attribute '%V' of '%.100s' objects is not readable", descr_name((PyDescrObject *)descr), "?", @@ -232,8 +252,9 @@ getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value) return -1; } if (descr->d_getset->set != NULL) { - return descr->d_getset->set(obj, value, - descr->d_getset->closure); + return descr_set_trampoline_call( + descr->d_getset->set, obj, value, + descr->d_getset->closure); } PyErr_Format(PyExc_AttributeError, "attribute '%V' of '%.100s' objects is not writable", @@ -306,7 +327,8 @@ method_vectorcall_VARARGS( Py_DECREF(argstuple); return NULL; } - PyObject *result = meth(args[0], argstuple); + PyObject *result = _PyCFunction_TrampolineCall( + meth, args[0], argstuple); Py_DECREF(argstuple); _Py_LeaveRecursiveCall(tstate); return result; @@ -339,7 +361,8 @@ method_vectorcall_VARARGS_KEYWORDS( if (meth == NULL) { goto exit; } - result = meth(args[0], argstuple, kwdict); + result = _PyCFunctionWithKeywords_TrampolineCall( + meth, args[0], argstuple, kwdict); _Py_LeaveRecursiveCall(tstate); exit: Py_DECREF(argstuple); @@ -427,7 +450,7 @@ method_vectorcall_NOARGS( if (meth == NULL) { return NULL; } - PyObject *result = meth(args[0], NULL); + PyObject *result = _PyCFunction_TrampolineCall(meth, args[0], NULL); _Py_LeaveRecursiveCall(tstate); return result; } @@ -455,7 +478,7 @@ method_vectorcall_O( if (meth == NULL) { return NULL; } - PyObject *result = meth(args[0], args[1]); + PyObject *result = _PyCFunction_TrampolineCall(meth, args[0], args[1]); _Py_LeaveRecursiveCall(tstate); return result; } diff --git a/Objects/methodobject.c b/Objects/methodobject.c index 93fac22ec437c..8bcb1e0fadb8c 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -483,7 +483,8 @@ cfunction_vectorcall_NOARGS( if (meth == NULL) { return NULL; } - PyObject *result = meth(PyCFunction_GET_SELF(func), NULL); + PyObject *result = _PyCFunction_TrampolineCall( + meth, PyCFunction_GET_SELF(func), NULL); _Py_LeaveRecursiveCall(tstate); return result; } @@ -510,7 +511,8 @@ cfunction_vectorcall_O( if (meth == NULL) { return NULL; } - PyObject *result = meth(PyCFunction_GET_SELF(func), args[0]); + PyObject *result = _PyCFunction_TrampolineCall( + meth, PyCFunction_GET_SELF(func), args[0]); _Py_LeaveRecursiveCall(tstate); return result; } @@ -537,7 +539,9 @@ cfunction_call(PyObject *func, PyObject *args, PyObject *kwargs) PyObject *result; if (flags & METH_KEYWORDS) { - result = (*(PyCFunctionWithKeywords)(void(*)(void))meth)(self, args, kwargs); + result = _PyCFunctionWithKeywords_TrampolineCall( + (*(PyCFunctionWithKeywords)(void(*)(void))meth), + self, args, kwargs); } else { if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) { @@ -546,7 +550,15 @@ cfunction_call(PyObject *func, PyObject *args, PyObject *kwargs) ((PyCFunctionObject*)func)->m_ml->ml_name); return NULL; } - result = meth(self, args); + result = _PyCFunction_TrampolineCall(meth, self, args); } return _Py_CheckFunctionResult(tstate, func, result, NULL); } + +#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE) +#include + +EM_JS(PyObject*, _PyCFunctionWithKeywords_TrampolineCall, (PyCFunctionWithKeywords func, PyObject *self, PyObject *args, PyObject *kw), { + return wasmTable.get(func)(self, args, kw); +}); +#endif diff --git a/Python/import.c b/Python/import.c index 982ec8cfe631a..4b6d6d16821a9 100644 --- a/Python/import.c +++ b/Python/import.c @@ -527,7 +527,7 @@ import_find_extension(PyThreadState *tstate, PyObject *name, else { if (def->m_base.m_init == NULL) return NULL; - mod = def->m_base.m_init(); + mod = _PyImport_InitFunc_TrampolineCall(def->m_base.m_init); if (mod == NULL) return NULL; if (PyObject_SetItem(modules, name, mod) == -1) { @@ -958,6 +958,13 @@ PyImport_GetImporter(PyObject *path) return get_path_importer(tstate, path_importer_cache, path_hooks, path); } +#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE) +#include +EM_JS(PyObject*, _PyImport_InitFunc_TrampolineCall, (PyModInitFunction func), { + return wasmTable.get(func)(); +}); +#endif // __EMSCRIPTEN__ && PY_CALL_TRAMPOLINE + static PyObject* create_builtin(PyThreadState *tstate, PyObject *name, PyObject *spec) { @@ -973,8 +980,7 @@ create_builtin(PyThreadState *tstate, PyObject *name, PyObject *spec) /* Cannot re-init internal module ("sys" or "builtins") */ return PyImport_AddModuleObject(name); } - - mod = (*p->initfunc)(); + mod = _PyImport_InitFunc_TrampolineCall(*p->initfunc); if (mod == NULL) { return NULL; } diff --git a/Python/importdl.c b/Python/importdl.c index f66c6013d2c98..870ae2730071b 100644 --- a/Python/importdl.c +++ b/Python/importdl.c @@ -102,7 +102,7 @@ _PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp) const char *oldcontext; dl_funcptr exportfunc; PyModuleDef *def; - PyObject *(*p0)(void); + PyModInitFunction p0; name_unicode = PyObject_GetAttrString(spec, "name"); if (name_unicode == NULL) { @@ -157,7 +157,7 @@ _PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp) goto error; } - p0 = (PyObject *(*)(void))exportfunc; + p0 = (PyModInitFunction)exportfunc; /* Package context is needed for single-phase init */ oldcontext = _Py_PackageContext; @@ -166,7 +166,7 @@ _PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp) _Py_PackageContext = oldcontext; goto error; } - m = p0(); + m = _PyImport_InitFunc_TrampolineCall(p0); _Py_PackageContext = oldcontext; if (m == NULL) { diff --git a/Python/importdl.h b/Python/importdl.h index 9847652b1f1b3..26d18b626df05 100644 --- a/Python/importdl.h +++ b/Python/importdl.h @@ -10,6 +10,14 @@ extern const char *_PyImport_DynLoadFiletab[]; extern PyObject *_PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *); +typedef PyObject *(*PyModInitFunction)(void); + +#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE) +extern PyObject *_PyImport_InitFunc_TrampolineCall(PyModInitFunction func); +#else +#define _PyImport_InitFunc_TrampolineCall(func) (func)() +#endif + /* Max length of module suffix searched for -- accommodates "module.slb" */ #define MAXSUFFIXSIZE 12 From webhook-mailer at python.org Wed Mar 30 16:20:53 2022 From: webhook-mailer at python.org (zooba) Date: Wed, 30 Mar 2022 20:20:53 -0000 Subject: [Python-checkins] bpo-47171: Enable installing the py.exe launcher on Windows ARM64 (GH-32203) Message-ID: https://github.com/python/cpython/commit/2ab609dd614045f3b112ede0b0883339de784f2a commit: 2ab609dd614045f3b112ede0b0883339de784f2a branch: main author: Steve Dower committer: zooba date: 2022-03-30T21:20:38+01:00 summary: bpo-47171: Enable installing the py.exe launcher on Windows ARM64 (GH-32203) files: A Misc/NEWS.d/next/Windows/2022-03-30-19-55-00.bpo-47171.MbqCWn.rst M Tools/msi/bundle/Default.ARM64.xsl M Tools/msi/bundle/bundle.wxs M Tools/msi/exe/exe.wixproj diff --git a/Misc/NEWS.d/next/Windows/2022-03-30-19-55-00.bpo-47171.MbqCWn.rst b/Misc/NEWS.d/next/Windows/2022-03-30-19-55-00.bpo-47171.MbqCWn.rst new file mode 100644 index 0000000000000..d9f1795f1e1f7 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-03-30-19-55-00.bpo-47171.MbqCWn.rst @@ -0,0 +1 @@ +Enables installing the :file:`py.exe` launcher on Windows ARM64. diff --git a/Tools/msi/bundle/Default.ARM64.xsl b/Tools/msi/bundle/Default.ARM64.xsl index f63da4e7274cb..b28b3f264adbc 100644 --- a/Tools/msi/bundle/Default.ARM64.xsl +++ b/Tools/msi/bundle/Default.ARM64.xsl @@ -10,6 +10,10 @@ + \ No newline at end of file diff --git a/Tools/msi/bundle/bundle.wxs b/Tools/msi/bundle/bundle.wxs index ac4b7a6d75308..19e67faf887bc 100644 --- a/Tools/msi/bundle/bundle.wxs +++ b/Tools/msi/bundle/bundle.wxs @@ -56,9 +56,7 @@ - - - + @@ -76,17 +74,12 @@ - - - - - @@ -115,9 +108,7 @@ - - diff --git a/Tools/msi/exe/exe.wixproj b/Tools/msi/exe/exe.wixproj index be44f442f7c9d..592c8d2f65ae6 100644 --- a/Tools/msi/exe/exe.wixproj +++ b/Tools/msi/exe/exe.wixproj @@ -32,18 +32,9 @@ - - - - - - - - @(HostPython) - $(HostPython.Remove($(HostPython.IndexOf(';')))) - - - + + + From webhook-mailer at python.org Wed Mar 30 17:18:48 2022 From: webhook-mailer at python.org (zooba) Date: Wed, 30 Mar 2022 21:18:48 -0000 Subject: [Python-checkins] bpo-46566: Make test_launcher more robust to a variety of installs (GH-32204) Message-ID: https://github.com/python/cpython/commit/f3d5715492195fd2532fc1a5d73be07923cdf2e1 commit: f3d5715492195fd2532fc1a5d73be07923cdf2e1 branch: main author: Steve Dower committer: zooba date: 2022-03-30T22:18:40+01:00 summary: bpo-46566: Make test_launcher more robust to a variety of installs (GH-32204) files: M Lib/test/test_launcher.py diff --git a/Lib/test/test_launcher.py b/Lib/test/test_launcher.py index 2fb5aae628a67..52b1cfa212b88 100644 --- a/Lib/test/test_launcher.py +++ b/Lib/test/test_launcher.py @@ -151,6 +151,30 @@ def find_py(cls): py_exe = Path(p) / PY_EXE if py_exe.is_file(): break + else: + py_exe = None + + # Test launch and check version, to exclude installs of older + # releases when running outside of a source tree + if py_exe: + try: + with subprocess.Popen( + [py_exe, "-h"], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + encoding="ascii", + errors="ignore", + ) as p: + p.stdin.close() + version = next(p.stdout).splitlines()[0].rpartition(" ")[2] + p.stdout.read() + p.wait(10) + if not sys.version.startswith(version): + py_exe = None + except OSError: + py_exe = None + if not py_exe: raise unittest.SkipTest( "cannot locate '{}' for test".format(PY_EXE) @@ -162,6 +186,7 @@ def run_py(self, args, env=None, allow_fail=False, expect_returncode=0): self.py_exe = self.find_py() env = {**os.environ, **(env or {}), "PYLAUNCHER_DEBUG": "1", "PYLAUNCHER_DRYRUN": "1"} + env.pop("VIRTUAL_ENV", None) with subprocess.Popen( [self.py_exe, *args], env=env, @@ -216,7 +241,7 @@ def setUpClass(cls): if support.verbose: p = subprocess.check_output("reg query HKCU\\Software\\Python /s") - print(p.decode('mbcs')) + #print(p.decode('mbcs')) @classmethod @@ -251,9 +276,9 @@ def test_list(self): found = {} expect = {} for line in data["stdout"].splitlines(): - m = re.match(r"\s*(.+?)\s+(.+)$", line) + m = re.match(r"\s*(.+?)\s+?(\*\s+)?(.+)$", line) if m: - found[m.group(1)] = m.group(2) + found[m.group(1)] = m.group(3) for company in TEST_DATA: company_data = TEST_DATA[company] tags = [t for t in company_data if isinstance(company_data[t], dict)] @@ -276,9 +301,9 @@ def test_list_paths(self): found = {} expect = {} for line in data["stdout"].splitlines(): - m = re.match(r"\s*(.+?)\s+(.+)$", line) + m = re.match(r"\s*(.+?)\s+?(\*\s+)?(.+)$", line) if m: - found[m.group(1)] = m.group(2) + found[m.group(1)] = m.group(3) for company in TEST_DATA: company_data = TEST_DATA[company] tags = [t for t in company_data if isinstance(company_data[t], dict)] @@ -415,9 +440,10 @@ def test_install(self): # If winget is runnable, we should find it. Otherwise, we'll be trying # to open the Store. try: - subprocess.check_call(["winget.exe", "--version"]) + subprocess.check_call(["winget.exe", "--version"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) except FileNotFoundError: self.assertIn("ms-windows-store://", cmd) else: self.assertIn("winget.exe", cmd) + # Both command lines include the store ID self.assertIn("9PJPW5LDXLZ5", cmd) From webhook-mailer at python.org Wed Mar 30 21:24:15 2022 From: webhook-mailer at python.org (ericsnowcurrently) Date: Thu, 31 Mar 2022 01:24:15 -0000 Subject: [Python-checkins] bpo-47146: Avoid Using make Recursively (gh-32206) Message-ID: https://github.com/python/cpython/commit/db4dada5108dd49ebca23e4559a53630a2df8447 commit: db4dada5108dd49ebca23e4559a53630a2df8447 branch: main author: Eric Snow committer: ericsnowcurrently date: 2022-03-30T19:24:02-06:00 summary: bpo-47146: Avoid Using make Recursively (gh-32206) https://bugs.python.org/issue47146 files: M Makefile.pre.in M Tools/scripts/generate_global_objects.py diff --git a/Makefile.pre.in b/Makefile.pre.in index e6c6a6ba53a6d..8d335a7e139fc 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1136,10 +1136,7 @@ regen-frozen: Tools/scripts/freeze_modules.py $(FROZEN_FILES_IN) # Deepfreeze targets .PHONY: regen-deepfreeze -regen-deepfreeze: - @# Possibly generate globals first, to make sure _bootstrap_python builds. - $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_global_objects.py - $(MAKE) $(DEEPFREEZE_OBJS) +regen-deepfreeze: $(DEEPFREEZE_OBJS) DEEPFREEZE_DEPS=$(srcdir)/Tools/scripts/deepfreeze.py $(FREEZE_MODULE_DEPS) $(FROZEN_FILES_OUT) @@ -1180,13 +1177,25 @@ regen-importlib: regen-frozen ############################################################################ # Global objects -.PHONY: regen-global-objects -regen-global-objects: regen-deepfreeze - @# We already ran in once, before deepfreezing, to make sure - @# _bootstrap_python builds. Now we run it again to catch any - @# remaining globals, including those added by deepfreeze. +GLOBAL_OBJECTS_TARGETS = \ + $(srcdir)/Include/internal/pycore_global_objects.h \ + $(srcdir)/Include/internal/pycore_global_strings.h + +# The global objects will get regenerated as soon these files +# are required, including as a prerequisite for regen-deepfreeze. +$(GLOBAL_OBJECTS_TARGETS): generate-global-objects + +.PHONY: generate-global-objects +generate-global-objects: $(srcdir)/Tools/scripts/generate_global_objects.py $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_global_objects.py +.PHONY: generate-global-objects-after-deepfreeze +generate-global-objects-after-deepfreeze: regen-deepfreeze $(srcdir)/Tools/scripts/generate_global_objects.py + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_global_objects.py + +.PHONY: regen-global-objects +regen-global-objects: regen-deepfreeze generate-global-objects-after-deepfreeze + ############################################################################ # ABI diff --git a/Tools/scripts/generate_global_objects.py b/Tools/scripts/generate_global_objects.py index f7653604e822b..826f4c4c83aec 100644 --- a/Tools/scripts/generate_global_objects.py +++ b/Tools/scripts/generate_global_objects.py @@ -115,7 +115,12 @@ def iter_global_strings(): id_regex = re.compile(r'\b_Py_ID\((\w+)\)') str_regex = re.compile(r'\b_Py_DECLARE_STR\((\w+), "(.*?)"\)') for filename in iter_files(): - with open(filename, encoding='utf-8') as infile: + try: + infile = open(filename, encoding='utf-8') + except FileNotFoundError: + # The file must have been a temporary file. + continue + with infile: for lno, line in enumerate(infile, 1): for m in id_regex.finditer(line): identifier, = m.groups() From webhook-mailer at python.org Wed Mar 30 21:48:45 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 31 Mar 2022 01:48:45 -0000 Subject: [Python-checkins] bpo-46775: OSError should call winerror_to_errno unconditionally on Windows (GH-32179) Message-ID: https://github.com/python/cpython/commit/1f2ec4cef1804cda9d2df99a318373b2982919e9 commit: 1f2ec4cef1804cda9d2df99a318373b2982919e9 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-30T18:48:31-07:00 summary: bpo-46775: OSError should call winerror_to_errno unconditionally on Windows (GH-32179) (cherry picked from commit d0c67ea0645b7ad37b867c167882a346a24de641) Co-authored-by: Dong-hee Na files: A Misc/NEWS.d/next/Core and Builtins/2022-03-30-02-36-25.bpo-46775.e3Oxqf.rst M Objects/exceptions.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-30-02-36-25.bpo-46775.e3Oxqf.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-30-02-36-25.bpo-46775.e3Oxqf.rst new file mode 100644 index 0000000000000..da56ecd89367b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-30-02-36-25.bpo-46775.e3Oxqf.rst @@ -0,0 +1,3 @@ +Some Windows system error codes(>= 10000) are now mapped into +the correct errno and may now raise a subclass of :exc:`OSError`. +Patch by Dong-hee Na. diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 6537a7ccd1e3c..9639b4436a078 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -847,14 +847,7 @@ oserror_parse_args(PyObject **p_args, winerrcode = PyLong_AsLong(*winerror); if (winerrcode == -1 && PyErr_Occurred()) return -1; - /* Set errno to the corresponding POSIX errno (overriding - first argument). Windows Socket error codes (>= 10000) - have the same value as their POSIX counterparts. - */ - if (winerrcode < 10000) - errcode = winerror_to_errno(winerrcode); - else - errcode = winerrcode; + errcode = winerror_to_errno(winerrcode); *myerrno = PyLong_FromLong(errcode); if (!*myerrno) return -1; From webhook-mailer at python.org Wed Mar 30 21:49:48 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 31 Mar 2022 01:49:48 -0000 Subject: [Python-checkins] bpo-46775: OSError should call winerror_to_errno unconditionally on Windows (GH-32179) Message-ID: https://github.com/python/cpython/commit/d04a21344ae69c66f5a6df69ee6fa6988a69b89d commit: d04a21344ae69c66f5a6df69ee6fa6988a69b89d branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-30T18:49:40-07:00 summary: bpo-46775: OSError should call winerror_to_errno unconditionally on Windows (GH-32179) (cherry picked from commit d0c67ea0645b7ad37b867c167882a346a24de641) Co-authored-by: Dong-hee Na files: A Misc/NEWS.d/next/Core and Builtins/2022-03-30-02-36-25.bpo-46775.e3Oxqf.rst M Objects/exceptions.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-30-02-36-25.bpo-46775.e3Oxqf.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-30-02-36-25.bpo-46775.e3Oxqf.rst new file mode 100644 index 0000000000000..da56ecd89367b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-30-02-36-25.bpo-46775.e3Oxqf.rst @@ -0,0 +1,3 @@ +Some Windows system error codes(>= 10000) are now mapped into +the correct errno and may now raise a subclass of :exc:`OSError`. +Patch by Dong-hee Na. diff --git a/Objects/exceptions.c b/Objects/exceptions.c index e67ecfab858fb..57ddbb0012134 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -844,14 +844,7 @@ oserror_parse_args(PyObject **p_args, winerrcode = PyLong_AsLong(*winerror); if (winerrcode == -1 && PyErr_Occurred()) return -1; - /* Set errno to the corresponding POSIX errno (overriding - first argument). Windows Socket error codes (>= 10000) - have the same value as their POSIX counterparts. - */ - if (winerrcode < 10000) - errcode = winerror_to_errno(winerrcode); - else - errcode = winerrcode; + errcode = winerror_to_errno(winerrcode); *myerrno = PyLong_FromLong(errcode); if (!*myerrno) return -1; From webhook-mailer at python.org Thu Mar 31 03:59:32 2022 From: webhook-mailer at python.org (vstinner) Date: Thu, 31 Mar 2022 07:59:32 -0000 Subject: [Python-checkins] bpo-47164: Add _PyASCIIObject_CAST() macro (GH-32191) Message-ID: https://github.com/python/cpython/commit/c14d7e4b816134b8e93ece4066a86d229631ce96 commit: c14d7e4b816134b8e93ece4066a86d229631ce96 branch: main author: Victor Stinner committer: vstinner date: 2022-03-31T09:59:27+02:00 summary: bpo-47164: Add _PyASCIIObject_CAST() macro (GH-32191) Add macros to cast objects to PyASCIIObject*, PyCompactUnicodeObject* and PyUnicodeObject*: _PyASCIIObject_CAST(), _PyCompactUnicodeObject_CAST() and _PyUnicodeObject_CAST(). Using these new macros make the code more readable and check their argument with: assert(PyUnicode_Check(op)). Remove redundant assert(PyUnicode_Check(op)) in macros using directly or indirectly these new CAST macros. Replacing existing casts with these macros. files: M Include/cpython/unicodeobject.h M Include/unicodeobject.h M Modules/_collectionsmodule.c M Objects/dictobject.c M Objects/setobject.c M Objects/typeobject.c M Objects/unicodeobject.c M Python/traceback.c diff --git a/Include/cpython/unicodeobject.h b/Include/cpython/unicodeobject.h index 77a171b86bff4..69e4abfb5c442 100644 --- a/Include/cpython/unicodeobject.h +++ b/Include/cpython/unicodeobject.h @@ -234,6 +234,15 @@ PyAPI_FUNC(int) _PyUnicode_CheckConsistency( PyObject *op, int check_content); + +#define _PyASCIIObject_CAST(op) \ + (assert(PyUnicode_Check(op)), (PyASCIIObject*)(op)) +#define _PyCompactUnicodeObject_CAST(op) \ + (assert(PyUnicode_Check(op)), (PyCompactUnicodeObject*)(op)) +#define _PyUnicodeObject_CAST(op) \ + (assert(PyUnicode_Check(op)), (PyUnicodeObject*)(op)) + + /* Fast access macros */ /* Returns the deprecated Py_UNICODE representation's size in code units @@ -243,11 +252,10 @@ PyAPI_FUNC(int) _PyUnicode_CheckConsistency( /* Py_DEPRECATED(3.3) */ #define PyUnicode_GET_SIZE(op) \ - (assert(PyUnicode_Check(op)), \ - (((PyASCIIObject *)(op))->wstr) ? \ + (_PyASCIIObject_CAST(op)->wstr ? \ PyUnicode_WSTR_LENGTH(op) : \ ((void)PyUnicode_AsUnicode(_PyObject_CAST(op)),\ - assert(((PyASCIIObject *)(op))->wstr), \ + assert(_PyASCIIObject_CAST(op)->wstr), \ PyUnicode_WSTR_LENGTH(op))) /* Py_DEPRECATED(3.3) */ @@ -261,9 +269,8 @@ PyAPI_FUNC(int) _PyUnicode_CheckConsistency( /* Py_DEPRECATED(3.3) */ #define PyUnicode_AS_UNICODE(op) \ - (assert(PyUnicode_Check(op)), \ - (((PyASCIIObject *)(op))->wstr) ? (((PyASCIIObject *)(op))->wstr) : \ - PyUnicode_AsUnicode(_PyObject_CAST(op))) + (_PyASCIIObject_CAST(op)->wstr ? _PyASCIIObject_CAST(op)->wstr : \ + PyUnicode_AsUnicode(_PyObject_CAST(op))) /* Py_DEPRECATED(3.3) */ #define PyUnicode_AS_DATA(op) \ @@ -281,25 +288,24 @@ PyAPI_FUNC(int) _PyUnicode_CheckConsistency( /* Use only if you know it's a string */ #define PyUnicode_CHECK_INTERNED(op) \ - (((PyASCIIObject *)(op))->state.interned) + (_PyASCIIObject_CAST(op)->state.interned) /* Return true if the string contains only ASCII characters, or 0 if not. The string may be compact (PyUnicode_IS_COMPACT_ASCII) or not, but must be ready. */ #define PyUnicode_IS_ASCII(op) \ - (assert(PyUnicode_Check(op)), \ - assert(PyUnicode_IS_READY(op)), \ - ((PyASCIIObject*)op)->state.ascii) + (assert(PyUnicode_IS_READY(op)), \ + _PyASCIIObject_CAST(op)->state.ascii) /* Return true if the string is compact or 0 if not. No type checks or Ready calls are performed. */ #define PyUnicode_IS_COMPACT(op) \ - (((PyASCIIObject*)(op))->state.compact) + (_PyASCIIObject_CAST(op)->state.compact) /* Return true if the string is a compact ASCII string (use PyASCIIObject structure), or 0 if not. No type checks or Ready calls are performed. */ #define PyUnicode_IS_COMPACT_ASCII(op) \ - (((PyASCIIObject*)op)->state.ascii && PyUnicode_IS_COMPACT(op)) + (_PyASCIIObject_CAST(op)->state.ascii && PyUnicode_IS_COMPACT(op)) enum PyUnicode_Kind { /* String contains only wstr byte characters. This is only possible @@ -323,23 +329,21 @@ enum PyUnicode_Kind { /* Return one of the PyUnicode_*_KIND values defined above. */ #define PyUnicode_KIND(op) \ - (assert(PyUnicode_Check(op)), \ - assert(PyUnicode_IS_READY(op)), \ - ((PyASCIIObject *)(op))->state.kind) + (assert(PyUnicode_IS_READY(op)), \ + _PyASCIIObject_CAST(op)->state.kind) /* Return a void pointer to the raw unicode buffer. */ #define _PyUnicode_COMPACT_DATA(op) \ - (PyUnicode_IS_ASCII(op) ? \ - ((void*)((PyASCIIObject*)(op) + 1)) : \ - ((void*)((PyCompactUnicodeObject*)(op) + 1))) + (PyUnicode_IS_ASCII(op) ? \ + ((void*)(_PyASCIIObject_CAST(op) + 1)) : \ + ((void*)(_PyCompactUnicodeObject_CAST(op) + 1))) #define _PyUnicode_NONCOMPACT_DATA(op) \ - (assert(((PyUnicodeObject*)(op))->data.any), \ - ((((PyUnicodeObject *)(op))->data.any))) + (assert(_PyUnicodeObject_CAST(op)->data.any), \ + (_PyUnicodeObject_CAST(op)->data.any)) #define PyUnicode_DATA(op) \ - (assert(PyUnicode_Check(op)), \ - PyUnicode_IS_COMPACT(op) ? _PyUnicode_COMPACT_DATA(op) : \ + (PyUnicode_IS_COMPACT(op) ? _PyUnicode_COMPACT_DATA(op) : \ _PyUnicode_NONCOMPACT_DATA(op)) /* In the access macros below, "kind" may be evaluated more than once. @@ -386,8 +390,7 @@ enum PyUnicode_Kind { PyUnicode_READ_CHAR, for multiple consecutive reads callers should cache kind and use PyUnicode_READ instead. */ #define PyUnicode_READ_CHAR(unicode, index) \ - (assert(PyUnicode_Check(unicode)), \ - assert(PyUnicode_IS_READY(unicode)), \ + (assert(PyUnicode_IS_READY(unicode)), \ (Py_UCS4) \ (PyUnicode_KIND((unicode)) == PyUnicode_1BYTE_KIND ? \ ((const Py_UCS1 *)(PyUnicode_DATA((unicode))))[(index)] : \ @@ -401,23 +404,21 @@ enum PyUnicode_Kind { the string has it's canonical representation set before calling this macro. Call PyUnicode_(FAST_)Ready to ensure that. */ #define PyUnicode_GET_LENGTH(op) \ - (assert(PyUnicode_Check(op)), \ - assert(PyUnicode_IS_READY(op)), \ - ((PyASCIIObject *)(op))->length) + (assert(PyUnicode_IS_READY(op)), \ + _PyASCIIObject_CAST(op)->length) /* Fast check to determine whether an object is ready. Equivalent to - PyUnicode_IS_COMPACT(op) || ((PyUnicodeObject*)(op))->data.any */ + PyUnicode_IS_COMPACT(op) || _PyUnicodeObject_CAST(op)->data.any */ -#define PyUnicode_IS_READY(op) (((PyASCIIObject*)op)->state.ready) +#define PyUnicode_IS_READY(op) (_PyASCIIObject_CAST(op)->state.ready) /* PyUnicode_READY() does less work than _PyUnicode_Ready() in the best case. If the canonical representation is not yet set, it will still call _PyUnicode_Ready(). Returns 0 on success and -1 on errors. */ #define PyUnicode_READY(op) \ - (assert(PyUnicode_Check(op)), \ - (PyUnicode_IS_READY(op) ? \ + ((PyUnicode_IS_READY(op) ? \ 0 : _PyUnicode_Ready(_PyObject_CAST(op)))) /* Return a maximum character value which is suitable for creating another @@ -436,8 +437,8 @@ enum PyUnicode_Kind { Py_DEPRECATED(3.3) static inline Py_ssize_t PyUnicode_WSTR_LENGTH(PyObject *op) { return PyUnicode_IS_COMPACT_ASCII(op) ? - ((PyASCIIObject*)op)->length : - ((PyCompactUnicodeObject*)op)->wstr_length; + _PyASCIIObject_CAST(op)->length : + _PyCompactUnicodeObject_CAST(op)->wstr_length; } #define PyUnicode_WSTR_LENGTH(op) PyUnicode_WSTR_LENGTH(_PyObject_CAST(op)) diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index 6426c5d06b445..1d2f54608544e 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -112,7 +112,7 @@ PyAPI_DATA(PyTypeObject) PyUnicode_Type; PyAPI_DATA(PyTypeObject) PyUnicodeIter_Type; #define PyUnicode_Check(op) \ - PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS) + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS) #define PyUnicode_CheckExact(op) Py_IS_TYPE(op, &PyUnicode_Type) /* --- Constants ---------------------------------------------------------- */ diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index e7bd8bc15122f..b47f977731758 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -2352,7 +2352,7 @@ _collections__count_elements_impl(PyObject *module, PyObject *mapping, break; if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) + (hash = _PyASCIIObject_CAST(key)->hash) == -1) { hash = PyObject_Hash(key); if (hash == -1) diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 635a738985c01..88addfda8f239 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -286,7 +286,7 @@ static inline Py_hash_t unicode_get_hash(PyObject *o) { assert(PyUnicode_CheckExact(o)); - return ((PyASCIIObject*)o)->hash; + return _PyASCIIObject_CAST(o)->hash; } /* Print summary info about the state of the optimized allocator */ diff --git a/Objects/setobject.c b/Objects/setobject.c index c65b7d5d21115..022ae8e7f9392 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -346,7 +346,7 @@ set_add_key(PySetObject *so, PyObject *key) Py_hash_t hash; if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) { + (hash = _PyASCIIObject_CAST(key)->hash) == -1) { hash = PyObject_Hash(key); if (hash == -1) return -1; @@ -360,7 +360,7 @@ set_contains_key(PySetObject *so, PyObject *key) Py_hash_t hash; if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) { + (hash = _PyASCIIObject_CAST(key)->hash) == -1) { hash = PyObject_Hash(key); if (hash == -1) return -1; @@ -374,7 +374,7 @@ set_discard_key(PySetObject *so, PyObject *key) Py_hash_t hash; if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) { + (hash = _PyASCIIObject_CAST(key)->hash) == -1) { hash = PyObject_Hash(key); if (hash == -1) return -1; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 4bed3ef49289a..5de8c3d2ece43 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3759,7 +3759,7 @@ find_name_in_mro(PyTypeObject *type, PyObject *name, int *error) { Py_hash_t hash; if (!PyUnicode_CheckExact(name) || - (hash = ((PyASCIIObject *) name)->hash) == -1) + (hash = _PyASCIIObject_CAST(name)->hash) == -1) { hash = PyObject_Hash(name); if (hash == -1) { @@ -3853,7 +3853,7 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name) struct type_cache_entry *entry = &cache->hashtable[h]; entry->version = type->tp_version_tag; entry->value = res; /* borrowed */ - assert(((PyASCIIObject *)(name))->hash != -1); + assert(_PyASCIIObject_CAST(name)->hash != -1); #if MCACHE_STATS if (entry->name != Py_None && entry->name != name) { cache->collisions++; @@ -8951,7 +8951,7 @@ super_init_without_args(_PyInterpreterFrame *cframe, PyCodeObject *co, if (cframe->f_lasti >= 0) { // MAKE_CELL and COPY_FREE_VARS have no quickened forms, so no need // to use _PyOpcode_Deopt here: - assert(_Py_OPCODE(_PyCode_CODE(co)[0]) == MAKE_CELL || + assert(_Py_OPCODE(_PyCode_CODE(co)[0]) == MAKE_CELL || _Py_OPCODE(_PyCode_CODE(co)[0]) == COPY_FREE_VARS); assert(PyCell_Check(firstarg)); firstarg = PyCell_GET(firstarg); diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 72f9245afb79a..5a1d2c0630167 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -113,46 +113,46 @@ extern "C" { #endif #define _PyUnicode_UTF8(op) \ - (((PyCompactUnicodeObject*)(op))->utf8) + (_PyCompactUnicodeObject_CAST(op)->utf8) #define PyUnicode_UTF8(op) \ (assert(_PyUnicode_CHECK(op)), \ assert(PyUnicode_IS_READY(op)), \ PyUnicode_IS_COMPACT_ASCII(op) ? \ - ((char*)((PyASCIIObject*)(op) + 1)) : \ + ((char*)(_PyASCIIObject_CAST(op) + 1)) : \ _PyUnicode_UTF8(op)) #define _PyUnicode_UTF8_LENGTH(op) \ - (((PyCompactUnicodeObject*)(op))->utf8_length) + (_PyCompactUnicodeObject_CAST(op)->utf8_length) #define PyUnicode_UTF8_LENGTH(op) \ (assert(_PyUnicode_CHECK(op)), \ assert(PyUnicode_IS_READY(op)), \ PyUnicode_IS_COMPACT_ASCII(op) ? \ - ((PyASCIIObject*)(op))->length : \ + _PyASCIIObject_CAST(op)->length : \ _PyUnicode_UTF8_LENGTH(op)) #define _PyUnicode_WSTR(op) \ - (((PyASCIIObject*)(op))->wstr) + (_PyASCIIObject_CAST(op)->wstr) /* Don't use deprecated macro of unicodeobject.h */ #undef PyUnicode_WSTR_LENGTH #define PyUnicode_WSTR_LENGTH(op) \ - (PyUnicode_IS_COMPACT_ASCII(op) ? \ - ((PyASCIIObject*)op)->length : \ - ((PyCompactUnicodeObject*)op)->wstr_length) + (PyUnicode_IS_COMPACT_ASCII(op) ? \ + _PyASCIIObject_CAST(op)->length : \ + _PyCompactUnicodeObject_CAST(op)->wstr_length) #define _PyUnicode_WSTR_LENGTH(op) \ - (((PyCompactUnicodeObject*)(op))->wstr_length) + (_PyCompactUnicodeObject_CAST(op)->wstr_length) #define _PyUnicode_LENGTH(op) \ - (((PyASCIIObject *)(op))->length) + (_PyASCIIObject_CAST(op)->length) #define _PyUnicode_STATE(op) \ - (((PyASCIIObject *)(op))->state) + (_PyASCIIObject_CAST(op)->state) #define _PyUnicode_HASH(op) \ - (((PyASCIIObject *)(op))->hash) + (_PyASCIIObject_CAST(op)->hash) #define _PyUnicode_KIND(op) \ (assert(_PyUnicode_CHECK(op)), \ - ((PyASCIIObject *)(op))->state.kind) + _PyASCIIObject_CAST(op)->state.kind) #define _PyUnicode_GET_LENGTH(op) \ (assert(_PyUnicode_CHECK(op)), \ - ((PyASCIIObject *)(op))->length) + _PyASCIIObject_CAST(op)->length) #define _PyUnicode_DATA_ANY(op) \ - (((PyUnicodeObject*)(op))->data.any) + (_PyUnicodeObject_CAST(op)->data.any) #undef PyUnicode_READY #define PyUnicode_READY(op) \ @@ -190,7 +190,7 @@ extern "C" { buffer where the result characters are written to. */ #define _PyUnicode_CONVERT_BYTES(from_type, to_type, begin, end, to) \ do { \ - to_type *_to = (to_type *)(to); \ + to_type *_to = (to_type *)(to); \ const from_type *_iter = (const from_type *)(begin);\ const from_type *_end = (const from_type *)(end);\ Py_ssize_t n = (_end) - (_iter); \ @@ -509,21 +509,18 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content) #define CHECK(expr) \ do { if (!(expr)) { _PyObject_ASSERT_FAILED_MSG(op, Py_STRINGIFY(expr)); } } while (0) - PyASCIIObject *ascii; - unsigned int kind; - assert(op != NULL); CHECK(PyUnicode_Check(op)); - ascii = (PyASCIIObject *)op; - kind = ascii->state.kind; + PyASCIIObject *ascii = _PyASCIIObject_CAST(op); + unsigned int kind = ascii->state.kind; if (ascii->state.ascii == 1 && ascii->state.compact == 1) { CHECK(kind == PyUnicode_1BYTE_KIND); CHECK(ascii->state.ready == 1); } else { - PyCompactUnicodeObject *compact = (PyCompactUnicodeObject *)op; + PyCompactUnicodeObject *compact = _PyCompactUnicodeObject_CAST(op); void *data; if (ascii->state.compact == 1) { @@ -536,7 +533,7 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content) CHECK(compact->utf8 != data); } else { - PyUnicodeObject *unicode = (PyUnicodeObject *)op; + PyUnicodeObject *unicode = _PyUnicodeObject_CAST(op); data = unicode->data.any; if (kind == PyUnicode_WCHAR_KIND) { @@ -1330,8 +1327,8 @@ const void *_PyUnicode_data(void *unicode_raw) { printf("obj %p\n", (void*)unicode); printf("compact %d\n", PyUnicode_IS_COMPACT(unicode)); printf("compact ascii %d\n", PyUnicode_IS_COMPACT_ASCII(unicode)); - printf("ascii op %p\n", ((void*)((PyASCIIObject*)(unicode) + 1))); - printf("compact op %p\n", ((void*)((PyCompactUnicodeObject*)(unicode) + 1))); + printf("ascii op %p\n", (void*)(_PyASCIIObject_CAST(unicode) + 1)); + printf("compact op %p\n", (void*)(_PyCompactUnicodeObject_CAST(unicode) + 1)); printf("compact data %p\n", _PyUnicode_COMPACT_DATA(unicode)); return PyUnicode_DATA(unicode); } @@ -1339,9 +1336,9 @@ const void *_PyUnicode_data(void *unicode_raw) { void _PyUnicode_Dump(PyObject *op) { - PyASCIIObject *ascii = (PyASCIIObject *)op; - PyCompactUnicodeObject *compact = (PyCompactUnicodeObject *)op; - PyUnicodeObject *unicode = (PyUnicodeObject *)op; + PyASCIIObject *ascii = _PyASCIIObject_CAST(op); + PyCompactUnicodeObject *compact = _PyCompactUnicodeObject_CAST(op); + PyUnicodeObject *unicode = _PyUnicodeObject_CAST(op); const void *data; if (ascii->state.compact) @@ -1976,7 +1973,7 @@ unicode_is_singleton(PyObject *unicode) return 1; } - PyASCIIObject *ascii = (PyASCIIObject *)unicode; + PyASCIIObject *ascii = _PyASCIIObject_CAST(unicode); if (ascii->state.kind != PyUnicode_WCHAR_KIND && ascii->length == 1) { Py_UCS4 ch = PyUnicode_READ_CHAR(unicode, 0); if (ch < 256 && LATIN1(ch) == unicode) { @@ -16053,7 +16050,7 @@ _PyUnicode_FiniTypes(PyInterpreterState *interp) static void unicode_static_dealloc(PyObject *op) { - PyASCIIObject* ascii = (PyASCIIObject*)op; + PyASCIIObject *ascii = _PyASCIIObject_CAST(op); assert(ascii->state.compact); diff --git a/Python/traceback.c b/Python/traceback.c index 6a721cf909757..f5c1849101a21 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -1073,7 +1073,7 @@ _Py_DumpHexadecimal(int fd, uintptr_t value, Py_ssize_t width) void _Py_DumpASCII(int fd, PyObject *text) { - PyASCIIObject *ascii = (PyASCIIObject *)text; + PyASCIIObject *ascii = _PyASCIIObject_CAST(text); Py_ssize_t i, size; int truncated; int kind; @@ -1087,19 +1087,19 @@ _Py_DumpASCII(int fd, PyObject *text) size = ascii->length; kind = ascii->state.kind; if (kind == PyUnicode_WCHAR_KIND) { - wstr = ((PyASCIIObject *)text)->wstr; + wstr = ascii->wstr; if (wstr == NULL) return; - size = ((PyCompactUnicodeObject *)text)->wstr_length; + size = _PyCompactUnicodeObject_CAST(text)->wstr_length; } else if (ascii->state.compact) { if (ascii->state.ascii) - data = ((PyASCIIObject*)text) + 1; + data = ascii + 1; else - data = ((PyCompactUnicodeObject*)text) + 1; + data = _PyCompactUnicodeObject_CAST(text) + 1; } else { - data = ((PyUnicodeObject *)text)->data.any; + data = _PyUnicodeObject_CAST(text)->data.any; if (data == NULL) return; } From webhook-mailer at python.org Thu Mar 31 04:02:47 2022 From: webhook-mailer at python.org (vstinner) Date: Thu, 31 Mar 2022 08:02:47 -0000 Subject: [Python-checkins] bpo-47164: Add _PyCFunction_CAST() macro (GH-32192) Message-ID: https://github.com/python/cpython/commit/f0bc69485677ae8973685866ada0982976d3878f commit: f0bc69485677ae8973685866ada0982976d3878f branch: main author: Victor Stinner committer: vstinner date: 2022-03-31T10:02:34+02:00 summary: bpo-47164: Add _PyCFunction_CAST() macro (GH-32192) Use the macro in C files of the Python/ directory. files: M Doc/c-api/structures.rst M Include/methodobject.h M Python/_warnings.c M Python/bltinmodule.c M Python/context.c M Python/hamt.c M Python/sysmodule.c M Python/traceback.c diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index 49f2a614e3507..3270d7d8fba45 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -342,6 +342,9 @@ There are these calling conventions: hold a reference to the module or object instance. In all cases the second parameter will be ``NULL``. + The function must have 2 parameters. Since the second parameter is unused, + :c:macro:`Py_UNUSED` can be used to prevent a compiler warning. + .. data:: METH_O diff --git a/Include/methodobject.h b/Include/methodobject.h index 5d2e06c3e7cea..959e77512200c 100644 --- a/Include/methodobject.h +++ b/Include/methodobject.h @@ -26,6 +26,24 @@ typedef PyObject *(*_PyCFunctionFastWithKeywords) (PyObject *, typedef PyObject *(*PyCMethod)(PyObject *, PyTypeObject *, PyObject *const *, size_t, PyObject *); +// Cast an function to the PyCFunction type to use it with PyMethodDef. +// +// This macro can be used to prevent compiler warnings if the first parameter +// uses a different pointer type than PyObject* (ex: METH_VARARGS and METH_O +// calling conventions). +// +// The macro can also be used for METH_FASTCALL and METH_VARARGS|METH_KEYWORDS +// calling conventions to avoid compiler warnings because the function has more +// than 2 parameters. The macro first casts the function to the +// "void func(void)" type to prevent compiler warnings. +// +// If a function is declared with the METH_NOARGS calling convention, it must +// have 2 parameters. Since the second parameter is unused, Py_UNUSED() can be +// used to prevent a compiler warning. If the function has a single parameter, +// it triggers an undefined behavior when Python calls it with 2 parameters +// (bpo-33012). +#define _PyCFunction_CAST(func) ((PyCFunction)(void(*)(void))(func)) + PyAPI_FUNC(PyCFunction) PyCFunction_GetFunction(PyObject *); PyAPI_FUNC(PyObject *) PyCFunction_GetSelf(PyObject *); PyAPI_FUNC(int) PyCFunction_GetFlags(PyObject *); diff --git a/Python/_warnings.c b/Python/_warnings.c index be962e76cd801..942308b357e33 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -1078,7 +1078,7 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds) } static PyObject * -warnings_filters_mutated(PyObject *self, PyObject *args) +warnings_filters_mutated(PyObject *self, PyObject *Py_UNUSED(args)) { PyInterpreterState *interp = get_current_interp(); if (interp == NULL) { @@ -1353,9 +1353,9 @@ PyDoc_STRVAR(warn_explicit_doc, static PyMethodDef warnings_functions[] = { WARNINGS_WARN_METHODDEF - {"warn_explicit", (PyCFunction)(void(*)(void))warnings_warn_explicit, + {"warn_explicit", _PyCFunction_CAST(warnings_warn_explicit), METH_VARARGS | METH_KEYWORDS, warn_explicit_doc}, - {"_filters_mutated", (PyCFunction)warnings_filters_mutated, METH_NOARGS, + {"_filters_mutated", _PyCFunction_CAST(warnings_filters_mutated), METH_NOARGS, NULL}, /* XXX(brett.cannon): add showwarning? */ /* XXX(brett.cannon): Reasonable to add formatwarning? */ diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 332f4cbbd0dcc..9cfecc521d90c 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -613,7 +613,7 @@ filter_reduce(filterobject *lz, PyObject *Py_UNUSED(ignored)) PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); static PyMethodDef filter_methods[] = { - {"__reduce__", (PyCFunction)filter_reduce, METH_NOARGS, reduce_doc}, + {"__reduce__", _PyCFunction_CAST(filter_reduce), METH_NOARGS, reduce_doc}, {NULL, NULL} /* sentinel */ }; @@ -1354,7 +1354,7 @@ map_reduce(mapobject *lz, PyObject *Py_UNUSED(ignored)) } static PyMethodDef map_methods[] = { - {"__reduce__", (PyCFunction)map_reduce, METH_NOARGS, reduce_doc}, + {"__reduce__", _PyCFunction_CAST(map_reduce), METH_NOARGS, reduce_doc}, {NULL, NULL} /* sentinel */ }; @@ -2321,7 +2321,7 @@ PyDoc_STRVAR(builtin_sorted__doc__, "reverse flag can be set to request the result in descending order."); #define BUILTIN_SORTED_METHODDEF \ - {"sorted", (PyCFunction)(void(*)(void))builtin_sorted, METH_FASTCALL | METH_KEYWORDS, builtin_sorted__doc__}, + {"sorted", _PyCFunction_CAST(builtin_sorted), METH_FASTCALL | METH_KEYWORDS, builtin_sorted__doc__}, static PyObject * builtin_sorted(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -2839,8 +2839,8 @@ zip_setstate(zipobject *lz, PyObject *state) } static PyMethodDef zip_methods[] = { - {"__reduce__", (PyCFunction)zip_reduce, METH_NOARGS, reduce_doc}, - {"__setstate__", (PyCFunction)zip_setstate, METH_O, setstate_doc}, + {"__reduce__", _PyCFunction_CAST(zip_reduce), METH_NOARGS, reduce_doc}, + {"__setstate__", _PyCFunction_CAST(zip_setstate), METH_O, setstate_doc}, {NULL} /* sentinel */ }; @@ -2904,7 +2904,7 @@ PyTypeObject PyZip_Type = { static PyMethodDef builtin_methods[] = { - {"__build_class__", (PyCFunction)(void(*)(void))builtin___build_class__, + {"__build_class__", _PyCFunction_CAST(builtin___build_class__), METH_FASTCALL | METH_KEYWORDS, build_class_doc}, BUILTIN___IMPORT___METHODDEF BUILTIN_ABS_METHODDEF @@ -2912,17 +2912,17 @@ static PyMethodDef builtin_methods[] = { BUILTIN_ANY_METHODDEF BUILTIN_ASCII_METHODDEF BUILTIN_BIN_METHODDEF - {"breakpoint", (PyCFunction)(void(*)(void))builtin_breakpoint, METH_FASTCALL | METH_KEYWORDS, breakpoint_doc}, + {"breakpoint", _PyCFunction_CAST(builtin_breakpoint), METH_FASTCALL | METH_KEYWORDS, breakpoint_doc}, BUILTIN_CALLABLE_METHODDEF BUILTIN_CHR_METHODDEF BUILTIN_COMPILE_METHODDEF BUILTIN_DELATTR_METHODDEF - {"dir", builtin_dir, METH_VARARGS, dir_doc}, + {"dir", builtin_dir, METH_VARARGS, dir_doc}, BUILTIN_DIVMOD_METHODDEF BUILTIN_EVAL_METHODDEF BUILTIN_EXEC_METHODDEF BUILTIN_FORMAT_METHODDEF - {"getattr", (PyCFunction)(void(*)(void))builtin_getattr, METH_FASTCALL, getattr_doc}, + {"getattr", _PyCFunction_CAST(builtin_getattr), METH_FASTCALL, getattr_doc}, BUILTIN_GLOBALS_METHODDEF BUILTIN_HASATTR_METHODDEF BUILTIN_HASH_METHODDEF @@ -2931,13 +2931,13 @@ static PyMethodDef builtin_methods[] = { BUILTIN_INPUT_METHODDEF BUILTIN_ISINSTANCE_METHODDEF BUILTIN_ISSUBCLASS_METHODDEF - {"iter", (PyCFunction)(void(*)(void))builtin_iter, METH_FASTCALL, iter_doc}, + {"iter", _PyCFunction_CAST(builtin_iter), METH_FASTCALL, iter_doc}, BUILTIN_AITER_METHODDEF BUILTIN_LEN_METHODDEF BUILTIN_LOCALS_METHODDEF - {"max", (PyCFunction)(void(*)(void))builtin_max, METH_VARARGS | METH_KEYWORDS, max_doc}, - {"min", (PyCFunction)(void(*)(void))builtin_min, METH_VARARGS | METH_KEYWORDS, min_doc}, - {"next", (PyCFunction)(void(*)(void))builtin_next, METH_FASTCALL, next_doc}, + {"max", _PyCFunction_CAST(builtin_max), METH_VARARGS | METH_KEYWORDS, max_doc}, + {"min", _PyCFunction_CAST(builtin_min), METH_VARARGS | METH_KEYWORDS, min_doc}, + {"next", _PyCFunction_CAST(builtin_next), METH_FASTCALL, next_doc}, BUILTIN_ANEXT_METHODDEF BUILTIN_OCT_METHODDEF BUILTIN_ORD_METHODDEF diff --git a/Python/context.c b/Python/context.c index f3033d9b649af..a77cd14544edc 100644 --- a/Python/context.c +++ b/Python/context.c @@ -685,7 +685,7 @@ static PyMethodDef PyContext_methods[] = { _CONTEXTVARS_CONTEXT_KEYS_METHODDEF _CONTEXTVARS_CONTEXT_VALUES_METHODDEF _CONTEXTVARS_CONTEXT_COPY_METHODDEF - {"run", (PyCFunction)(void(*)(void))context_run, METH_FASTCALL | METH_KEYWORDS, NULL}, + {"run", _PyCFunction_CAST(context_run), METH_FASTCALL | METH_KEYWORDS, NULL}, {NULL, NULL} }; diff --git a/Python/hamt.c b/Python/hamt.c index cbfe4459d3ed0..c3cb4e6fda450 100644 --- a/Python/hamt.c +++ b/Python/hamt.c @@ -2845,14 +2845,14 @@ hamt_py_values(PyHamtObject *self, PyObject *args) } static PyObject * -hamt_py_keys(PyHamtObject *self, PyObject *args) +hamt_py_keys(PyHamtObject *self, PyObject *Py_UNUSED(args)) { return _PyHamt_NewIterKeys(self); } #ifdef Py_DEBUG static PyObject * -hamt_py_dump(PyHamtObject *self, PyObject *args) +hamt_py_dump(PyHamtObject *self, PyObject *Py_UNUSED(args)) { return hamt_dump(self); } @@ -2860,14 +2860,14 @@ hamt_py_dump(PyHamtObject *self, PyObject *args) static PyMethodDef PyHamt_methods[] = { - {"set", (PyCFunction)hamt_py_set, METH_VARARGS, NULL}, - {"get", (PyCFunction)hamt_py_get, METH_VARARGS, NULL}, - {"delete", (PyCFunction)hamt_py_delete, METH_O, NULL}, - {"items", (PyCFunction)hamt_py_items, METH_NOARGS, NULL}, - {"keys", (PyCFunction)hamt_py_keys, METH_NOARGS, NULL}, - {"values", (PyCFunction)hamt_py_values, METH_NOARGS, NULL}, + {"set", _PyCFunction_CAST(hamt_py_set), METH_VARARGS, NULL}, + {"get", _PyCFunction_CAST(hamt_py_get), METH_VARARGS, NULL}, + {"delete", _PyCFunction_CAST(hamt_py_delete), METH_O, NULL}, + {"items", _PyCFunction_CAST(hamt_py_items), METH_NOARGS, NULL}, + {"keys", _PyCFunction_CAST(hamt_py_keys), METH_NOARGS, NULL}, + {"values", _PyCFunction_CAST(hamt_py_values), METH_NOARGS, NULL}, #ifdef Py_DEBUG - {"__dump__", (PyCFunction)hamt_py_dump, METH_NOARGS, NULL}, + {"__dump__", _PyCFunction_CAST(hamt_py_dump), METH_NOARGS, NULL}, #endif {NULL, NULL} }; diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 6322af5f5ca81..5765e9ef6577c 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -1929,8 +1929,8 @@ sys_getandroidapilevel_impl(PyObject *module) static PyMethodDef sys_methods[] = { /* Might as well keep this in alphabetic order */ SYS_ADDAUDITHOOK_METHODDEF - {"audit", (PyCFunction)(void(*)(void))sys_audit, METH_FASTCALL, audit_doc }, - {"breakpointhook", (PyCFunction)(void(*)(void))sys_breakpointhook, + {"audit", _PyCFunction_CAST(sys_audit), METH_FASTCALL, audit_doc }, + {"breakpointhook", _PyCFunction_CAST(sys_breakpointhook), METH_FASTCALL | METH_KEYWORDS, breakpointhook_doc}, SYS__CLEAR_TYPE_CACHE_METHODDEF SYS__CURRENT_FRAMES_METHODDEF @@ -1944,18 +1944,18 @@ static PyMethodDef sys_methods[] = { SYS_GETDLOPENFLAGS_METHODDEF SYS_GETALLOCATEDBLOCKS_METHODDEF #ifdef Py_STATS - {"getdxp", _Py_GetDXProfile, METH_VARARGS}, + {"getdxp", _Py_GetDXProfile, METH_VARARGS}, #endif SYS_GETFILESYSTEMENCODING_METHODDEF SYS_GETFILESYSTEMENCODEERRORS_METHODDEF SYS__GETQUICKENEDCOUNT_METHODDEF #ifdef Py_TRACE_REFS - {"getobjects", _Py_GetObjects, METH_VARARGS}, + {"getobjects", _Py_GetObjects, METH_VARARGS}, #endif SYS_GETTOTALREFCOUNT_METHODDEF SYS_GETREFCOUNT_METHODDEF SYS_GETRECURSIONLIMIT_METHODDEF - {"getsizeof", (PyCFunction)(void(*)(void))sys_getsizeof, + {"getsizeof", _PyCFunction_CAST(sys_getsizeof), METH_VARARGS | METH_KEYWORDS, getsizeof_doc}, SYS__GETFRAME_METHODDEF SYS_GETWINDOWSVERSION_METHODDEF @@ -1966,21 +1966,21 @@ static PyMethodDef sys_methods[] = { SYS_SETSWITCHINTERVAL_METHODDEF SYS_GETSWITCHINTERVAL_METHODDEF SYS_SETDLOPENFLAGS_METHODDEF - {"setprofile", sys_setprofile, METH_O, setprofile_doc}, + {"setprofile", sys_setprofile, METH_O, setprofile_doc}, SYS_GETPROFILE_METHODDEF SYS_SETRECURSIONLIMIT_METHODDEF - {"settrace", sys_settrace, METH_O, settrace_doc}, + {"settrace", sys_settrace, METH_O, settrace_doc}, SYS_GETTRACE_METHODDEF SYS_CALL_TRACING_METHODDEF SYS__DEBUGMALLOCSTATS_METHODDEF SYS_SET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF SYS_GET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF - {"set_asyncgen_hooks", (PyCFunction)(void(*)(void))sys_set_asyncgen_hooks, + {"set_asyncgen_hooks", _PyCFunction_CAST(sys_set_asyncgen_hooks), METH_VARARGS | METH_KEYWORDS, set_asyncgen_hooks_doc}, SYS_GET_ASYNCGEN_HOOKS_METHODDEF SYS_GETANDROIDAPILEVEL_METHODDEF SYS_UNRAISABLEHOOK_METHODDEF - {NULL, NULL} /* sentinel */ + {NULL, NULL} // sentinel }; diff --git a/Python/traceback.c b/Python/traceback.c index f5c1849101a21..0d0eb954c232f 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -149,7 +149,7 @@ tb_next_set(PyTracebackObject *self, PyObject *new_next, void *Py_UNUSED(_)) static PyMethodDef tb_methods[] = { - {"__dir__", (PyCFunction)tb_dir, METH_NOARGS}, + {"__dir__", _PyCFunction_CAST(tb_dir), METH_NOARGS}, {NULL, NULL, 0, NULL}, }; From webhook-mailer at python.org Thu Mar 31 04:03:22 2022 From: webhook-mailer at python.org (vstinner) Date: Thu, 31 Mar 2022 08:03:22 -0000 Subject: [Python-checkins] bpo-47164: Add _PyCFunctionObject_CAST() macr (GH-32190) Message-ID: https://github.com/python/cpython/commit/7fc39a21cb85163a456eab91b52e5fe85e7f7e3e commit: 7fc39a21cb85163a456eab91b52e5fe85e7f7e3e branch: main author: Victor Stinner committer: vstinner date: 2022-03-31T10:03:13+02:00 summary: bpo-47164: Add _PyCFunctionObject_CAST() macr (GH-32190) Add _PyCFunctionObject_CAST() and _PyCMethodObject_CAST() macros to make macros casting their argument easier to read, but also to check the type of their input in debug mode: assert(PyCFunction_Check(func) and assert(PyCMethod_Check(func). Reformat also PyCFunction_XXX() macros for readability. files: M Include/cpython/methodobject.h diff --git a/Include/cpython/methodobject.h b/Include/cpython/methodobject.h index 7ecbfe3b5e2fe..46d177793fc4c 100644 --- a/Include/cpython/methodobject.h +++ b/Include/cpython/methodobject.h @@ -7,18 +7,23 @@ PyAPI_DATA(PyTypeObject) PyCMethod_Type; #define PyCMethod_CheckExact(op) Py_IS_TYPE(op, &PyCMethod_Type) #define PyCMethod_Check(op) PyObject_TypeCheck(op, &PyCMethod_Type) +#define _PyCFunctionObject_CAST(func) \ + (assert(PyCFunction_Check(func)), (PyCFunctionObject *)(func)) +#define _PyCMethodObject_CAST(func) \ + (assert(PyCMethod_Check(func)), (PyCMethodObject *)(func)) + /* Macros for direct access to these values. Type checks are *not* done, so use with care. */ #define PyCFunction_GET_FUNCTION(func) \ - (((PyCFunctionObject *)func) -> m_ml -> ml_meth) + (_PyCFunctionObject_CAST(func)->m_ml->ml_meth) #define PyCFunction_GET_SELF(func) \ - (((PyCFunctionObject *)func) -> m_ml -> ml_flags & METH_STATIC ? \ - NULL : ((PyCFunctionObject *)func) -> m_self) + (_PyCFunctionObject_CAST(func)->m_ml->ml_flags & METH_STATIC ? \ + NULL : _PyCFunctionObject_CAST(func)->m_self) #define PyCFunction_GET_FLAGS(func) \ - (((PyCFunctionObject *)func) -> m_ml -> ml_flags) + (_PyCFunctionObject_CAST(func)->m_ml->ml_flags) #define PyCFunction_GET_CLASS(func) \ - (((PyCFunctionObject *)func) -> m_ml -> ml_flags & METH_METHOD ? \ - ((PyCMethodObject *)func) -> mm_class : NULL) + (_PyCFunctionObject_CAST(func)->m_ml->ml_flags & METH_METHOD ? \ + _PyCMethodObject_CAST(func)->mm_class : NULL) typedef struct { PyObject_HEAD From webhook-mailer at python.org Thu Mar 31 06:19:20 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 31 Mar 2022 10:19:20 -0000 Subject: [Python-checkins] bpo-45847: Port _tkinter to PY_STDLIB_MOD (GH-31698) Message-ID: https://github.com/python/cpython/commit/b36d222110d0d6d84dc8e973ca87d976c2423f5d commit: b36d222110d0d6d84dc8e973ca87d976c2423f5d branch: main author: Erlend Egeberg Aasland committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-31T03:19:08-07:00 summary: bpo-45847: Port _tkinter to PY_STDLIB_MOD (GH-31698) - Remove ``--with-tclk-*`` options from `configure` - Use pkg-config to detect `_tkinter` dependencies (Tcl/Tk, X11) - Manual override via environment variables `TCLTK_CFLAGS` and `TCLTK_LIBS` files: M Doc/using/configure.rst M Doc/whatsnew/3.10.rst M Doc/whatsnew/3.11.rst M Doc/whatsnew/3.9.rst M Makefile.pre.in M Modules/Setup.stdlib.in M configure M configure.ac M pyconfig.h.in M setup.py diff --git a/Doc/using/configure.rst b/Doc/using/configure.rst index f1c156c042353..debbee7117f58 100644 --- a/Doc/using/configure.rst +++ b/Doc/using/configure.rst @@ -404,14 +404,6 @@ Libraries options .. versionadded:: 3.10 -.. cmdoption:: --with-tcltk-includes='-I...' - - Override search for Tcl and Tk include files. - -.. cmdoption:: --with-tcltk-libs='-L...' - - Override search for Tcl and Tk libraries. - .. cmdoption:: --with-libm=STRING Override ``libm`` math library to *STRING* (default is system-dependent). diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 905305be3176c..dd01c88d8ae66 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -2019,8 +2019,8 @@ Build Changes * The ``configure`` script now uses the ``pkg-config`` utility, if available, to detect the location of Tcl/Tk headers and libraries. As before, those - locations can be explicitly specified with the :option:`--with-tcltk-includes` - and :option:`--with-tcltk-libs` configuration options. + locations can be explicitly specified with the ``--with-tcltk-includes`` + and ``--with-tcltk-libs`` configuration options. (Contributed by Manolis Stamatogiannakis in :issue:`42603`.) * Add :option:`--with-openssl-rpath` option to ``configure`` script. The option diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 837d8c8cbd016..129e87ebafc2a 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -770,11 +770,17 @@ Build Changes * Build dependencies, compiler flags, and linker flags for most stdlib extension modules are now detected by :program:`configure`. libffi, libnsl, - libsqlite3, zlib, bzip2, liblzma, libcrypt, and uuid flags are detected by - ``pkg-config`` (when available). + libsqlite3, zlib, bzip2, liblzma, libcrypt, Tcl/Tk libs, and uuid flags + are detected by ``pkg-config`` (when available). (Contributed by Christian Heimes and Erlend Egeberg Aasland in :issue:`bpo-45847`, :issue:`45747`, and :issue:`45763`.) + .. note:: + Use the environment variables ``TCLTK_CFLAGS`` and ``TCLTK_LIBS`` to + manually specify the location of Tcl/Tk headers and libraries. + The :program:`configure` options ``--with-tcltk-includes`` and + ``--with-tcltk-libs`` have been removed. + * CPython now has experimental support for cross compiling to WebAssembly platform ``wasm32-emscripten``. The effort is inspired by previous work like Pyodide. diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index c7255b3d41765..6dee55e5a0e55 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -1249,7 +1249,7 @@ Build Changes of macOS. If a macOS SDK is explicitly configured, by using :option:`--enable-universalsdk` or ``-isysroot``, only the SDK itself is searched. The default behavior can still be overridden with - :option:`--with-tcltk-includes` and :option:`--with-tcltk-libs`. + ``--with-tcltk-includes`` and ``--with-tcltk-libs``. (Contributed by Ned Deily in :issue:`34956`.) * Python can now be built for Windows 10 ARM64. diff --git a/Makefile.pre.in b/Makefile.pre.in index 8d335a7e139fc..e784b43d0362d 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -302,10 +302,6 @@ _PYTHON_HOST_PLATFORM=@_PYTHON_HOST_PLATFORM@ BUILD_GNU_TYPE= @build@ HOST_GNU_TYPE= @host@ -# Tcl and Tk config info from --with-tcltk-includes and -libs options -TCLTK_INCLUDES= @TCLTK_INCLUDES@ -TCLTK_LIBS= @TCLTK_LIBS@ - # The task to run while instrumented when building the profile-opt target. # To speed up profile generation, we don't run the full unit test suite # by default. The default is "-m test --pgo". To run more tests, use @@ -736,10 +732,8 @@ sharedmods: $(BUILDPYTHON) pybuilddir.txt @LIBMPDEC_INTERNAL@ @LIBEXPAT_INTERNAL *) quiet="";; \ esac; \ echo "$(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ - _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \ $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build"; \ $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ - _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \ $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build diff --git a/Modules/Setup.stdlib.in b/Modules/Setup.stdlib.in index 73f041eb2fba9..22c0b147c1b89 100644 --- a/Modules/Setup.stdlib.in +++ b/Modules/Setup.stdlib.in @@ -150,12 +150,11 @@ # needs -lcrypt @MODULE__HASHLIB_TRUE at _hashlib _hashopenssl.c -# needs -ltk, -ltcl, and sometimes -lX11 -#@MODULE__TKINTER_TRUE at _tkinter _tkinter.c tkappinit.c - # Linux: -luuid, BSD/AIX: libc's uuid_create() @MODULE__UUID_TRUE at _uuid _uuidmodule.c + at MODULE__TKINTER_TRUE@_tkinter _tkinter.c tkappinit.c + ############################################################################ # macOS specific modules diff --git a/configure b/configure index 17f52996f4fd7..f261a86a28d1d 100755 --- a/configure +++ b/configure @@ -654,6 +654,8 @@ MODULE_BINASCII_FALSE MODULE_BINASCII_TRUE MODULE_ZLIB_FALSE MODULE_ZLIB_TRUE +MODULE__TKINTER_FALSE +MODULE__TKINTER_TRUE MODULE__UUID_FALSE MODULE__UUID_TRUE MODULE__SQLITE3_FALSE @@ -821,8 +823,10 @@ DFLAGS DTRACE GDBM_LIBS GDBM_CFLAGS +X11_LIBS +X11_CFLAGS TCLTK_LIBS -TCLTK_INCLUDES +TCLTK_CFLAGS LIBSQLITE3_LIBS LIBSQLITE3_CFLAGS LIBNSL_LIBS @@ -1032,8 +1036,6 @@ with_system_ffi with_system_libmpdec with_decimal_contextvar enable_loadable_sqlite_extensions -with_tcltk_includes -with_tcltk_libs with_dbmliborder enable_ipv6 with_doc_strings @@ -1077,6 +1079,10 @@ LIBNSL_CFLAGS LIBNSL_LIBS LIBSQLITE3_CFLAGS LIBSQLITE3_LIBS +TCLTK_CFLAGS +TCLTK_LIBS +X11_CFLAGS +X11_LIBS GDBM_CFLAGS GDBM_LIBS ZLIB_CFLAGS @@ -1801,10 +1807,6 @@ Optional Packages: --with-decimal-contextvar build _decimal module using a coroutine-local rather than a thread-local context (default is yes) - --with-tcltk-includes='-I...' - override search for Tcl and Tk include files - --with-tcltk-libs='-L...' - override search for Tcl and Tk libs --with-dbmliborder=db1:db2:... override order to check db backends for dbm; a valid value is a colon separated string with the backend @@ -1880,6 +1882,11 @@ Some influential environment variables: C compiler flags for LIBSQLITE3, overriding pkg-config LIBSQLITE3_LIBS linker flags for LIBSQLITE3, overriding pkg-config + TCLTK_CFLAGS + C compiler flags for TCLTK, overriding pkg-config + TCLTK_LIBS linker flags for TCLTK, overriding pkg-config + X11_CFLAGS C compiler flags for X11, overriding pkg-config + X11_LIBS linker flags for X11, overriding pkg-config GDBM_CFLAGS C compiler flags for gdbm GDBM_LIBS additional linker flags for gdbm ZLIB_CFLAGS C compiler flags for ZLIB, overriding pkg-config @@ -12334,50 +12341,280 @@ $as_echo "#define PY_SQLITE_ENABLE_LOAD_EXTENSION 1" >>confdefs.h fi -# Check for --with-tcltk-includes=path and --with-tcltk-libs=path +found_tcltk=no +for _QUERY in \ + "tcl >= 8.5.12 tk >= 8.5.12" \ + "tcl8.6 tk8.6" \ + "tcl86 tk86" \ + "tcl8.5 >= 8.5.12 tk8.5 >= 8.5.12" \ + "tcl85 >= 8.5.12 tk85 >= 8.5.12" \ +; do + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$_QUERY\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$_QUERY") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-tcltk-includes" >&5 -$as_echo_n "checking for --with-tcltk-includes... " >&6; } +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for TCLTK" >&5 +$as_echo_n "checking for TCLTK... " >&6; } -# Check whether --with-tcltk-includes was given. -if test "${with_tcltk_includes+set}" = set; then : - withval=$with_tcltk_includes; +if test -n "$TCLTK_CFLAGS"; then + pkg_cv_TCLTK_CFLAGS="$TCLTK_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$_QUERY\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$_QUERY") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_TCLTK_CFLAGS=`$PKG_CONFIG --cflags "$_QUERY" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else - with_tcltk_includes="default" + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$TCLTK_LIBS"; then + pkg_cv_TCLTK_LIBS="$TCLTK_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$_QUERY\""; } >&5 + ($PKG_CONFIG --exists --print-errors "$_QUERY") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_TCLTK_LIBS=`$PKG_CONFIG --libs "$_QUERY" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_tcltk_includes" >&5 -$as_echo "$with_tcltk_includes" >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-tcltk-libs" >&5 -$as_echo_n "checking for --with-tcltk-libs... " >&6; } -# Check whether --with-tcltk-libs was given. -if test "${with_tcltk_libs+set}" = set; then : - withval=$with_tcltk_libs; + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes else - with_tcltk_libs="default" + _pkg_short_errors_supported=no fi + if test $_pkg_short_errors_supported = yes; then + TCLTK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$_QUERY" 2>&1` + else + TCLTK_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$_QUERY" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$TCLTK_PKG_ERRORS" >&5 -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_tcltk_libs" >&5 -$as_echo "$with_tcltk_libs" >&6; } -if test "x$with_tcltk_includes" = xdefault || test "x$with_tcltk_libs" = xdefault -then - if test "x$with_tcltk_includes" != "x$with_tcltk_libs" - then - as_fn_error $? "use both --with-tcltk-includes='...' and --with-tcltk-libs='...' or neither" "$LINENO" 5 - fi - if test -n "$PKG_CONFIG" && "$PKG_CONFIG" --exists tcl tk; then - TCLTK_INCLUDES="`"$PKG_CONFIG" tcl tk --cflags-only-I 2>/dev/null`" - TCLTK_LIBS="`"$PKG_CONFIG" tcl tk --libs 2>/dev/null`" - else - TCLTK_INCLUDES="" - TCLTK_LIBS="" - fi + found_tcltk=no +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + found_tcltk=no +else + TCLTK_CFLAGS=$pkg_cv_TCLTK_CFLAGS + TCLTK_LIBS=$pkg_cv_TCLTK_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + found_tcltk=yes +fi + +fi + if test "x$found_tcltk" = xyes; then : + break +fi +done + +if test "x$found_tcltk" = xno; then : + + TCLTK_CFLAGS=${TCLTK_CFLAGS-""} + TCLTK_LIBS=${TCLTK_LIBS-""} + +fi + +case $ac_sys_system in #( + FreeBSD*) : + + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"x11\""; } >&5 + ($PKG_CONFIG --exists --print-errors "x11") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X11" >&5 +$as_echo_n "checking for X11... " >&6; } + +if test -n "$X11_CFLAGS"; then + pkg_cv_X11_CFLAGS="$X11_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"x11\""; } >&5 + ($PKG_CONFIG --exists --print-errors "x11") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_X11_CFLAGS=`$PKG_CONFIG --cflags "x11" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$X11_LIBS"; then + pkg_cv_X11_LIBS="$X11_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"x11\""; } >&5 + ($PKG_CONFIG --exists --print-errors "x11") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_X11_LIBS=`$PKG_CONFIG --libs "x11" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else - TCLTK_INCLUDES="$with_tcltk_includes" - TCLTK_LIBS="$with_tcltk_libs" + pkg_failed=yes fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + X11_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "x11" 2>&1` + else + X11_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "x11" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$X11_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (x11) were not met: + +$X11_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables X11_CFLAGS +and X11_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables X11_CFLAGS +and X11_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see . +See \`config.log' for more details" "$LINENO" 5; } +else + X11_CFLAGS=$pkg_cv_X11_CFLAGS + X11_LIBS=$pkg_cv_X11_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + + TCLTK_CFLAGS="$TCLTK_CFLAGS $X11_CFLAGS" + TCLTK_LIBS="$TCLTK_LIBS $X11_LIBS" + +fi + +fi + + ;; #( + *) : + ;; +esac + +save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$TCLTK_CFLAGS $CFLAGS" + LIBS="$TCLTK_LIBS $LDFLAGS" + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + #include + #include + #if defined(TK_HEX_VERSION) + # if TK_HEX_VERSION < 0x0805020c + # error "Tk older than 8.5.12 not supported" + # endif + #endif + #if (TCL_MAJOR_VERSION < 8) || \ + ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 5)) || \ + ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION == 5) && (TCL_RELEASE_SERIAL < 12)) + # error "Tcl older than 8.5.12 not supported" + #endif + #if (TK_MAJOR_VERSION < 8) || \ + ((TK_MAJOR_VERSION == 8) && (TK_MINOR_VERSION < 5)) || \ + ((TK_MAJOR_VERSION == 8) && (TK_MINOR_VERSION == 5) && (TK_RELEASE_SERIAL < 12)) + # error "Tk older than 8.5.12 not supported" + #endif + +int +main () +{ + + void *x1 = Tcl_Init; + void *x2 = Tk_Init; + + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + have_tcltk=yes + as_fn_append TCLTK_CFLAGS " -Wno-strict-prototypes -DWITH_APPINIT=1" + +else + + have_tcltk=no + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + @@ -18312,36 +18549,6 @@ _ACEOF fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for UCS-4 tcl" >&5 -$as_echo_n "checking for UCS-4 tcl... " >&6; } -have_ucs4_tcl=no -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#if TCL_UTF_MAX != 6 -# error "NOT UCS4_TCL" -#endif -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - -$as_echo "#define HAVE_UCS4_TCL 1" >>confdefs.h - - have_ucs4_tcl=yes - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_ucs4_tcl" >&5 -$as_echo "$have_ucs4_tcl" >&6; } - # check whether wchar_t is signed or not if test "$wchar_h" = yes then @@ -23224,6 +23431,40 @@ fi $as_echo "$py_cv_module__uuid" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _tkinter" >&5 +$as_echo_n "checking for stdlib extension module _tkinter... " >&6; } + if test "$py_cv_module__tkinter" != "n/a"; then : + + if true; then : + if test "$have_tcltk" = "yes"; then : + py_cv_module__tkinter=yes +else + py_cv_module__tkinter=missing +fi +else + py_cv_module__tkinter=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__TKINTER=$py_cv_module__tkinter$as_nl" + if test "x$py_cv_module__tkinter" = xyes; then : + + as_fn_append MODULE_BLOCK "MODULE__TKINTER_CFLAGS=$TCLTK_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__TKINTER_LDFLAGS=$TCLTK_LIBS$as_nl" + +fi + if test "$py_cv_module__tkinter" = yes; then + MODULE__TKINTER_TRUE= + MODULE__TKINTER_FALSE='#' +else + MODULE__TKINTER_TRUE='#' + MODULE__TKINTER_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__tkinter" >&5 +$as_echo "$py_cv_module__tkinter" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module zlib" >&5 $as_echo_n "checking for stdlib extension module zlib... " >&6; } @@ -24084,6 +24325,10 @@ if test -z "${MODULE__UUID_TRUE}" && test -z "${MODULE__UUID_FALSE}"; then as_fn_error $? "conditional \"MODULE__UUID\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${MODULE__TKINTER_TRUE}" && test -z "${MODULE__TKINTER_FALSE}"; then + as_fn_error $? "conditional \"MODULE__TKINTER\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MODULE_ZLIB_TRUE}" && test -z "${MODULE_ZLIB_FALSE}"; then as_fn_error $? "conditional \"MODULE_ZLIB\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/configure.ac b/configure.ac index 566ff80aed3c7..7e8203ba85d1b 100644 --- a/configure.ac +++ b/configure.ac @@ -3546,38 +3546,77 @@ AS_VAR_IF([enable_loadable_sqlite_extensions], [yes], [ [Define to 1 to build the sqlite module with loadable extensions support.]) ]) -# Check for --with-tcltk-includes=path and --with-tcltk-libs=path -AC_SUBST(TCLTK_INCLUDES) -AC_SUBST(TCLTK_LIBS) -AC_MSG_CHECKING(for --with-tcltk-includes) -AC_ARG_WITH(tcltk-includes, - AS_HELP_STRING([--with-tcltk-includes='-I...'], [override search for Tcl and Tk include files]), - [], - [with_tcltk_includes="default"]) -AC_MSG_RESULT($with_tcltk_includes) -AC_MSG_CHECKING(for --with-tcltk-libs) -AC_ARG_WITH(tcltk-libs, - AS_HELP_STRING([--with-tcltk-libs='-L...'], [override search for Tcl and Tk libs]), - [], - [with_tcltk_libs="default"]) -AC_MSG_RESULT($with_tcltk_libs) -if test "x$with_tcltk_includes" = xdefault || test "x$with_tcltk_libs" = xdefault -then - if test "x$with_tcltk_includes" != "x$with_tcltk_libs" - then - AC_MSG_ERROR([use both --with-tcltk-includes='...' and --with-tcltk-libs='...' or neither]) - fi - if test -n "$PKG_CONFIG" && "$PKG_CONFIG" --exists tcl tk; then - TCLTK_INCLUDES="`"$PKG_CONFIG" tcl tk --cflags-only-I 2>/dev/null`" - TCLTK_LIBS="`"$PKG_CONFIG" tcl tk --libs 2>/dev/null`" - else - TCLTK_INCLUDES="" - TCLTK_LIBS="" - fi -else - TCLTK_INCLUDES="$with_tcltk_includes" - TCLTK_LIBS="$with_tcltk_libs" -fi +dnl +dnl Detect Tcl/Tk. Use pkg-config if available. +dnl +found_tcltk=no +for _QUERY in \ + "tcl >= 8.5.12 tk >= 8.5.12" \ + "tcl8.6 tk8.6" \ + "tcl86 tk86" \ + "tcl8.5 >= 8.5.12 tk8.5 >= 8.5.12" \ + "tcl85 >= 8.5.12 tk85 >= 8.5.12" \ +; do + PKG_CHECK_EXISTS([$_QUERY], [ + PKG_CHECK_MODULES([TCLTK], [$_QUERY], [found_tcltk=yes], [found_tcltk=no]) + ]) + AS_VAR_IF([found_tcltk], [yes], [break]) +done + +AS_VAR_IF([found_tcltk], [no], [ + TCLTK_CFLAGS=${TCLTK_CFLAGS-""} + TCLTK_LIBS=${TCLTK_LIBS-""} +]) + +dnl FreeBSD has an X11 dependency which is not implicitly resolved. +AS_CASE([$ac_sys_system], + [FreeBSD*], [ + PKG_CHECK_EXISTS([x11], [ + PKG_CHECK_MODULES([X11], [x11], [ + TCLTK_CFLAGS="$TCLTK_CFLAGS $X11_CFLAGS" + TCLTK_LIBS="$TCLTK_LIBS $X11_LIBS" + ]) + ]) + ] +) + +WITH_SAVE_ENV([ + CPPFLAGS="$TCLTK_CFLAGS $CFLAGS" + LIBS="$TCLTK_LIBS $LDFLAGS" + + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([ + #include + #include + #if defined(TK_HEX_VERSION) + # if TK_HEX_VERSION < 0x0805020c + # error "Tk older than 8.5.12 not supported" + # endif + #endif + #if (TCL_MAJOR_VERSION < 8) || \ + ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 5)) || \ + ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION == 5) && (TCL_RELEASE_SERIAL < 12)) + # error "Tcl older than 8.5.12 not supported" + #endif + #if (TK_MAJOR_VERSION < 8) || \ + ((TK_MAJOR_VERSION == 8) && (TK_MINOR_VERSION < 5)) || \ + ((TK_MAJOR_VERSION == 8) && (TK_MINOR_VERSION == 5) && (TK_RELEASE_SERIAL < 12)) + # error "Tk older than 8.5.12 not supported" + #endif + ], [ + void *x1 = Tcl_Init; + void *x2 = Tk_Init; + ]) + ], [ + have_tcltk=yes + dnl The X11/xlib.h file bundled in the Tk sources can cause function + dnl prototype warnings from the compiler. Since we cannot easily fix + dnl that, suppress the warnings here instead. + AS_VAR_APPEND([TCLTK_CFLAGS], [" -Wno-strict-prototypes -DWITH_APPINIT=1"]) + ], [ + have_tcltk=no + ]) +]) dnl check for _gdbmmodule dependencies dnl NOTE: gdbm does not provide a pkgconf file. @@ -5204,18 +5243,6 @@ then AC_CHECK_SIZEOF(wchar_t, 4, [#include ]) fi -AC_MSG_CHECKING(for UCS-4 tcl) -have_ucs4_tcl=no -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -#include -#if TCL_UTF_MAX != 6 -# error "NOT UCS4_TCL" -#endif]], [[]])],[ - AC_DEFINE(HAVE_UCS4_TCL, 1, [Define this if you have tcl and TCL_UTF_MAX==6]) - have_ucs4_tcl=yes -],[]) -AC_MSG_RESULT($have_ucs4_tcl) - # check whether wchar_t is signed or not if test "$wchar_h" = yes then @@ -6704,6 +6731,8 @@ dnl PY_STDLIB_MOD([_tkinter], [], [], [], []) PY_STDLIB_MOD([_uuid], [], [test "$have_uuid" = "yes"], [$LIBUUID_CFLAGS], [$LIBUUID_LIBS]) +PY_STDLIB_MOD([_tkinter], [], + [test "$have_tcltk" = "yes"], [$TCLTK_CFLAGS], [$TCLTK_LIBS]) dnl compression libs PY_STDLIB_MOD([zlib], [], [test "$have_zlib" = yes], diff --git a/pyconfig.h.in b/pyconfig.h.in index ba77a27333d0c..3d2020c896934 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -1357,9 +1357,6 @@ `tzname'. */ #undef HAVE_TZNAME -/* Define this if you have tcl and TCL_UTF_MAX==6 */ -#undef HAVE_UCS4_TCL - /* Define to 1 if you have the `umask' function. */ #undef HAVE_UMASK diff --git a/setup.py b/setup.py index 070ae9822bd5e..a1a24ce1551bd 100644 --- a/setup.py +++ b/setup.py @@ -213,28 +213,6 @@ def macosx_sdk_root(): return MACOS_SDK_ROOT -def macosx_sdk_specified(): - """Returns true if an SDK was explicitly configured. - - True if an SDK was selected at configure time, either by specifying - --enable-universalsdk=(something other than no or /) or by adding a - -isysroot option to CFLAGS. In some cases, like when making - decisions about macOS Tk framework paths, we need to be able to - know whether the user explicitly asked to build with an SDK versus - the implicit use of an SDK when header files are no longer - installed on a running system by the Command Line Tools. - """ - global MACOS_SDK_SPECIFIED - - # If already called, return cached result. - if MACOS_SDK_SPECIFIED: - return MACOS_SDK_SPECIFIED - - # Find the sdk root and set MACOS_SDK_SPECIFIED - macosx_sdk_root() - return MACOS_SDK_SPECIFIED - - def is_macosx_sdk_path(path): """ Returns True if 'path' can be located in a macOS SDK @@ -292,59 +270,6 @@ def find_file(filename, std_dirs, paths): return None -def find_library_file(compiler, libname, std_dirs, paths): - result = compiler.find_library_file(std_dirs + paths, libname) - if result is None: - return None - - if MACOS: - sysroot = macosx_sdk_root() - - # Check whether the found file is in one of the standard directories - dirname = os.path.dirname(result) - for p in std_dirs: - # Ensure path doesn't end with path separator - p = p.rstrip(os.sep) - - if MACOS and is_macosx_sdk_path(p): - # Note that, as of Xcode 7, Apple SDKs may contain textual stub - # libraries with .tbd extensions rather than the normal .dylib - # shared libraries installed in /. The Apple compiler tool - # chain handles this transparently but it can cause problems - # for programs that are being built with an SDK and searching - # for specific libraries. Distutils find_library_file() now - # knows to also search for and return .tbd files. But callers - # of find_library_file need to keep in mind that the base filename - # of the returned SDK library file might have a different extension - # from that of the library file installed on the running system, - # for example: - # /Applications/Xcode.app/Contents/Developer/Platforms/ - # MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/ - # usr/lib/libedit.tbd - # vs - # /usr/lib/libedit.dylib - if os.path.join(sysroot, p[1:]) == dirname: - return [ ] - - if p == dirname: - return [ ] - - # Otherwise, it must have been in one of the additional directories, - # so we have to figure out which one. - for p in paths: - # Ensure path doesn't end with path separator - p = p.rstrip(os.sep) - - if MACOS and is_macosx_sdk_path(p): - if os.path.join(sysroot, p[1:]) == dirname: - return [ p ] - - if p == dirname: - return [p] - else: - assert False, "Internal error: Path not found in std_dirs or paths" - - def validate_tzpath(): base_tzpath = sysconfig.get_config_var('TZPATH') if not base_tzpath: @@ -1433,8 +1358,7 @@ def detect_modules(self): self.detect_decimal() self.detect_ctypes() self.detect_multiprocessing() - if not self.detect_tkinter(): - self.missing.append('_tkinter') + self.detect_tkinter() self.detect_uuid() # Uncomment the next line if you want to play with xxmodule.c @@ -1443,309 +1367,8 @@ def detect_modules(self): self.addext(Extension('xxlimited', ['xxlimited.c'])) self.addext(Extension('xxlimited_35', ['xxlimited_35.c'])) - def detect_tkinter_fromenv(self): - # Build _tkinter using the Tcl/Tk locations specified by - # the _TCLTK_INCLUDES and _TCLTK_LIBS environment variables. - # This method is meant to be invoked by detect_tkinter(). - # - # The variables can be set via one of the following ways. - # - # - Automatically, at configuration time, by using pkg-config. - # The tool is called by the configure script. - # Additional pkg-config configuration paths can be set via the - # PKG_CONFIG_PATH environment variable. - # - # PKG_CONFIG_PATH=".../lib/pkgconfig" ./configure ... - # - # - Explicitly, at configuration time by setting both - # --with-tcltk-includes and --with-tcltk-libs. - # - # ./configure ... \ - # --with-tcltk-includes="-I/path/to/tclincludes \ - # -I/path/to/tkincludes" - # --with-tcltk-libs="-L/path/to/tcllibs -ltclm.n \ - # -L/path/to/tklibs -ltkm.n" - # - # - Explicitly, at compile time, by passing TCLTK_INCLUDES and - # TCLTK_LIBS to the make target. - # This will override any configuration-time option. - # - # make TCLTK_INCLUDES="..." TCLTK_LIBS="..." - # - # This can be useful for building and testing tkinter with multiple - # versions of Tcl/Tk. Note that a build of Tk depends on a particular - # build of Tcl so you need to specify both arguments and use care when - # overriding. - - # The _TCLTK variables are created in the Makefile sharedmods target. - tcltk_includes = os.environ.get('_TCLTK_INCLUDES') - tcltk_libs = os.environ.get('_TCLTK_LIBS') - if not (tcltk_includes and tcltk_libs): - # Resume default configuration search. - return False - - extra_compile_args = tcltk_includes.split() - extra_link_args = tcltk_libs.split() - self.add(Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'], - define_macros=[('WITH_APPINIT', 1)], - extra_compile_args = extra_compile_args, - extra_link_args = extra_link_args)) - return True - - def detect_tkinter_darwin(self): - # Build default _tkinter on macOS using Tcl and Tk frameworks. - # This method is meant to be invoked by detect_tkinter(). - # - # The macOS native Tk (AKA Aqua Tk) and Tcl are most commonly - # built and installed as macOS framework bundles. However, - # for several reasons, we cannot take full advantage of the - # Apple-supplied compiler chain's -framework options here. - # Instead, we need to find and pass to the compiler the - # absolute paths of the Tcl and Tk headers files we want to use - # and the absolute path to the directory containing the Tcl - # and Tk frameworks for linking. - # - # We want to handle here two common use cases on macOS: - # 1. Build and link with system-wide third-party or user-built - # Tcl and Tk frameworks installed in /Library/Frameworks. - # 2. Build and link using a user-specified macOS SDK so that the - # built Python can be exported to other systems. In this case, - # search only the SDK's /Library/Frameworks (normally empty) - # and /System/Library/Frameworks. - # - # Any other use cases are handled either by detect_tkinter_fromenv(), - # or detect_tkinter(). The former handles non-standard locations of - # Tcl/Tk, defined via the _TCLTK_INCLUDES and _TCLTK_LIBS environment - # variables. The latter handles any Tcl/Tk versions installed in - # standard Unix directories. - # - # It would be desirable to also handle here the case where - # you want to build and link with a framework build of Tcl and Tk - # that is not in /Library/Frameworks, say, in your private - # $HOME/Library/Frameworks directory or elsewhere. It turns - # out to be difficult to make that work automatically here - # without bringing into play more tools and magic. That case - # can be handled using a recipe with the right arguments - # to detect_tkinter_fromenv(). - # - # Note also that the fallback case here is to try to use the - # Apple-supplied Tcl and Tk frameworks in /System/Library but - # be forewarned that they are deprecated by Apple and typically - # out-of-date and buggy; their use should be avoided if at - # all possible by installing a newer version of Tcl and Tk in - # /Library/Frameworks before building Python without - # an explicit SDK or by configuring build arguments explicitly. - - from os.path import join, exists - - sysroot = macosx_sdk_root() # path to the SDK or '/' - - if macosx_sdk_specified(): - # Use case #2: an SDK other than '/' was specified. - # Only search there. - framework_dirs = [ - join(sysroot, 'Library', 'Frameworks'), - join(sysroot, 'System', 'Library', 'Frameworks'), - ] - else: - # Use case #1: no explicit SDK selected. - # Search the local system-wide /Library/Frameworks, - # not the one in the default SDK, otherwise fall back to - # /System/Library/Frameworks whose header files may be in - # the default SDK or, on older systems, actually installed. - framework_dirs = [ - join('/', 'Library', 'Frameworks'), - join(sysroot, 'System', 'Library', 'Frameworks'), - ] - - # Find the directory that contains the Tcl.framework and - # Tk.framework bundles. - for F in framework_dirs: - # both Tcl.framework and Tk.framework should be present - for fw in 'Tcl', 'Tk': - if not exists(join(F, fw + '.framework')): - break - else: - # ok, F is now directory with both frameworks. Continue - # building - break - else: - # Tk and Tcl frameworks not found. Normal "unix" tkinter search - # will now resume. - return False - - include_dirs = [ - join(F, fw + '.framework', H) - for fw in ('Tcl', 'Tk') - for H in ('Headers',) - ] - - # Add the base framework directory as well - compile_args = ['-F', F] - - # Do not build tkinter for archs that this Tk was not built with. - cflags = sysconfig.get_config_vars('CFLAGS')[0] - archs = re.findall(r'-arch\s+(\w+)', cflags) - - tmpfile = os.path.join(self.build_temp, 'tk.arch') - if not os.path.exists(self.build_temp): - os.makedirs(self.build_temp) - - run_command( - "file {}/Tk.framework/Tk | grep 'for architecture' > {}".format(F, tmpfile) - ) - with open(tmpfile) as fp: - detected_archs = [] - for ln in fp: - a = ln.split()[-1] - if a in archs: - detected_archs.append(ln.split()[-1]) - os.unlink(tmpfile) - - arch_args = [] - for a in detected_archs: - arch_args.append('-arch') - arch_args.append(a) - - compile_args += arch_args - link_args = [','.join(['-Wl', '-F', F, '-framework', 'Tcl', '-framework', 'Tk']), *arch_args] - - # The X11/xlib.h file bundled in the Tk sources can cause function - # prototype warnings from the compiler. Since we cannot easily fix - # that, suppress the warnings here instead. - if '-Wstrict-prototypes' in cflags.split(): - compile_args.append('-Wno-strict-prototypes') - - self.add(Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'], - define_macros=[('WITH_APPINIT', 1)], - include_dirs=include_dirs, - libraries=[], - extra_compile_args=compile_args, - extra_link_args=link_args)) - return True - def detect_tkinter(self): - # The _tkinter module. - # - # Detection of Tcl/Tk is attempted in the following order: - # - Through environment variables. - # - Platform specific detection of Tcl/Tk (currently only macOS). - # - Search of various standard Unix header/library paths. - # - # Detection stops at the first successful method. - - # Check for Tcl and Tk at the locations indicated by _TCLTK_INCLUDES - # and _TCLTK_LIBS environment variables. - if self.detect_tkinter_fromenv(): - return True - - # Rather than complicate the code below, detecting and building - # AquaTk is a separate method. Only one Tkinter will be built on - # Darwin - either AquaTk, if it is found, or X11 based Tk. - if (MACOS and self.detect_tkinter_darwin()): - return True - - # Assume we haven't found any of the libraries or include files - # The versions with dots are used on Unix, and the versions without - # dots on Windows, for detection by cygwin. - tcllib = tklib = tcl_includes = tk_includes = None - for version in ['8.6', '86', '8.5', '85', '8.4', '84', '8.3', '83', - '8.2', '82', '8.1', '81', '8.0', '80']: - tklib = self.compiler.find_library_file(self.lib_dirs, - 'tk' + version) - tcllib = self.compiler.find_library_file(self.lib_dirs, - 'tcl' + version) - if tklib and tcllib: - # Exit the loop when we've found the Tcl/Tk libraries - break - - # Now check for the header files - if tklib and tcllib: - # Check for the include files on Debian and {Free,Open}BSD, where - # they're put in /usr/include/{tcl,tk}X.Y - dotversion = version - if '.' not in dotversion and "bsd" in HOST_PLATFORM.lower(): - # OpenBSD and FreeBSD use Tcl/Tk library names like libtcl83.a, - # but the include subdirs are named like .../include/tcl8.3. - dotversion = dotversion[:-1] + '.' + dotversion[-1] - tcl_include_sub = [] - tk_include_sub = [] - for dir in self.inc_dirs: - tcl_include_sub += [dir + os.sep + "tcl" + dotversion] - tk_include_sub += [dir + os.sep + "tk" + dotversion] - tk_include_sub += tcl_include_sub - tcl_includes = find_file('tcl.h', self.inc_dirs, tcl_include_sub) - tk_includes = find_file('tk.h', self.inc_dirs, tk_include_sub) - - if (tcllib is None or tklib is None or - tcl_includes is None or tk_includes is None): - self.announce("INFO: Can't locate Tcl/Tk libs and/or headers", 2) - return False - - # OK... everything seems to be present for Tcl/Tk. - - include_dirs = [] - libs = [] - defs = [] - added_lib_dirs = [] - for dir in tcl_includes + tk_includes: - if dir not in include_dirs: - include_dirs.append(dir) - - # Check for various platform-specific directories - if HOST_PLATFORM == 'sunos5': - include_dirs.append('/usr/openwin/include') - added_lib_dirs.append('/usr/openwin/lib') - elif os.path.exists('/usr/X11R6/include'): - include_dirs.append('/usr/X11R6/include') - added_lib_dirs.append('/usr/X11R6/lib64') - added_lib_dirs.append('/usr/X11R6/lib') - elif os.path.exists('/usr/X11R5/include'): - include_dirs.append('/usr/X11R5/include') - added_lib_dirs.append('/usr/X11R5/lib') - else: - # Assume default location for X11 - include_dirs.append('/usr/X11/include') - added_lib_dirs.append('/usr/X11/lib') - - # If Cygwin, then verify that X is installed before proceeding - if CYGWIN: - x11_inc = find_file('X11/Xlib.h', [], include_dirs) - if x11_inc is None: - return False - - # Check for BLT extension - if self.compiler.find_library_file(self.lib_dirs + added_lib_dirs, - 'BLT8.0'): - defs.append( ('WITH_BLT', 1) ) - libs.append('BLT8.0') - elif self.compiler.find_library_file(self.lib_dirs + added_lib_dirs, - 'BLT'): - defs.append( ('WITH_BLT', 1) ) - libs.append('BLT') - - # Add the Tcl/Tk libraries - libs.append('tk'+ version) - libs.append('tcl'+ version) - - # Finally, link with the X11 libraries (not appropriate on cygwin) - if not CYGWIN: - libs.append('X11') - - # XXX handle these, but how to detect? - # *** Uncomment and edit for PIL (TkImaging) extension only: - # -DWITH_PIL -I../Extensions/Imaging/libImaging tkImaging.c \ - # *** Uncomment and edit for TOGL extension only: - # -DWITH_TOGL togl.c \ - # *** Uncomment these for TOGL extension only: - # -lGL -lGLU -lXext -lXmu \ - - self.add(Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'], - define_macros=[('WITH_APPINIT', 1)] + defs, - include_dirs=include_dirs, - libraries=libs, - library_dirs=added_lib_dirs)) - return True + self.addext(Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'])) def configure_ctypes(self, ext): return True From webhook-mailer at python.org Thu Mar 31 09:14:34 2022 From: webhook-mailer at python.org (markshannon) Date: Thu, 31 Mar 2022 13:14:34 -0000 Subject: [Python-checkins] bpo-47120: Replace the JUMP_ABSOLUTE opcode by the relative JUMP_BACKWARD (GH-32115) Message-ID: https://github.com/python/cpython/commit/a00518d9ad9a8f408a9699191019d75dd8406c32 commit: a00518d9ad9a8f408a9699191019d75dd8406c32 branch: main author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com> committer: markshannon date: 2022-03-31T14:14:15+01:00 summary: bpo-47120: Replace the JUMP_ABSOLUTE opcode by the relative JUMP_BACKWARD (GH-32115) files: A Misc/NEWS.d/next/Core and Builtins/2022-03-25-21-51-10.bpo-47120.9YJ-Xw.rst M Doc/library/dis.rst M Doc/whatsnew/3.11.rst M Include/opcode.h M Lib/dis.py M Lib/importlib/_bootstrap_external.py M Lib/opcode.py M Lib/test/test_dis.py M Lib/test/test_peepholer.py M Objects/frameobject.c M Programs/test_frozenmain.h M Python/ceval.c M Python/compile.c M Python/opcode_targets.h M Python/specialize.c diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 877e11b7376b7..d1a0cecd82841 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -895,6 +895,13 @@ iterations of the loop. Increments bytecode counter by *delta*. +.. opcode:: JUMP_BACKWARD (delta) + + Decrements bytecode counter by *delta*. + + .. versionadded:: 3.11 + + .. opcode:: POP_JUMP_IF_TRUE (target) If TOS is true, sets the bytecode counter to *target*. TOS is popped. @@ -974,11 +981,6 @@ iterations of the loop. .. versionadded:: 3.1 -.. opcode:: JUMP_ABSOLUTE (target) - - Set bytecode counter to *target*. - - .. opcode:: JUMP_NO_INTERRUPT (target) Set bytecode counter to *target*. Do not check for interrupts. diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 129e87ebafc2a..1bd958724f3be 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -522,6 +522,7 @@ CPython bytecode changes * :opcode:`JUMP_IF_NOT_EXC_MATCH` no longer pops the active exception. +* Replaced :opcode:`JUMP_ABSOLUTE` by the relative :opcode:`JUMP_BACKWARD`. Deprecated ========== diff --git a/Include/opcode.h b/Include/opcode.h index 0ce7c158bbd58..3a7db438ede1f 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -67,7 +67,6 @@ extern "C" { #define JUMP_FORWARD 110 #define JUMP_IF_FALSE_OR_POP 111 #define JUMP_IF_TRUE_OR_POP 112 -#define JUMP_ABSOLUTE 113 #define POP_JUMP_IF_FALSE 114 #define POP_JUMP_IF_TRUE 115 #define LOAD_GLOBAL 116 @@ -94,6 +93,7 @@ extern "C" { #define LOAD_DEREF 137 #define STORE_DEREF 138 #define DELETE_DEREF 139 +#define JUMP_BACKWARD 140 #define CALL_FUNCTION_EX 142 #define EXTENDED_ARG 144 #define LIST_APPEND 145 @@ -135,7 +135,7 @@ extern "C" { #define COMPARE_OP_FLOAT_JUMP 27 #define COMPARE_OP_INT_JUMP 28 #define COMPARE_OP_STR_JUMP 29 -#define JUMP_ABSOLUTE_QUICK 34 +#define JUMP_BACKWARD_QUICK 34 #define LOAD_ATTR_ADAPTIVE 36 #define LOAD_ATTR_INSTANCE_VALUE 37 #define LOAD_ATTR_MODULE 38 @@ -168,7 +168,7 @@ extern "C" { #define PRECALL_NO_KW_METHOD_DESCRIPTOR_O 79 #define PRECALL_NO_KW_STR_1 80 #define PRECALL_NO_KW_TUPLE_1 81 -#define PRECALL_NO_KW_TYPE_1 140 +#define PRECALL_NO_KW_TYPE_1 113 #define PRECALL_PYFUNC 141 #define RESUME_QUICK 143 #define STORE_ATTR_ADAPTIVE 150 @@ -196,7 +196,7 @@ static const uint32_t _PyOpcode_RelativeJump[8] = { 0U, 536870912U, 134234112U, - 0U, + 4096U, 0U, 0U, 0U, @@ -205,8 +205,8 @@ static const uint32_t _PyOpcode_Jump[8] = { 0U, 0U, 536870912U, - 2316288000U, - 67U, + 2316156928U, + 4163U, 0U, 0U, 0U, @@ -289,8 +289,8 @@ const uint8_t _PyOpcode_Deopt[256] = { [IMPORT_NAME] = IMPORT_NAME, [IMPORT_STAR] = IMPORT_STAR, [IS_OP] = IS_OP, - [JUMP_ABSOLUTE] = JUMP_ABSOLUTE, - [JUMP_ABSOLUTE_QUICK] = JUMP_ABSOLUTE, + [JUMP_BACKWARD] = JUMP_BACKWARD, + [JUMP_BACKWARD_QUICK] = JUMP_BACKWARD, [JUMP_FORWARD] = JUMP_FORWARD, [JUMP_IF_FALSE_OR_POP] = JUMP_IF_FALSE_OR_POP, [JUMP_IF_NOT_EG_MATCH] = JUMP_IF_NOT_EG_MATCH, diff --git a/Lib/dis.py b/Lib/dis.py index 3b7747b03ffb1..d9936ce1a002c 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -30,6 +30,7 @@ LOAD_CONST = opmap['LOAD_CONST'] LOAD_GLOBAL = opmap['LOAD_GLOBAL'] BINARY_OP = opmap['BINARY_OP'] +JUMP_BACKWARD = opmap['JUMP_BACKWARD'] CACHE = opmap["CACHE"] @@ -441,7 +442,8 @@ def _get_instructions_bytes(code, varname_from_oparg=None, argval = arg*2 argrepr = "to " + repr(argval) elif op in hasjrel: - argval = offset + 2 + arg*2 + signed_arg = -arg if op == JUMP_BACKWARD else arg + argval = offset + 2 + signed_arg*2 argrepr = "to " + repr(argval) elif op in haslocal or op in hasfree: argval, argrepr = _get_name_info(arg, varname_from_oparg) @@ -566,6 +568,8 @@ def findlabels(code): for offset, op, arg in _unpack_opargs(code): if arg is not None: if op in hasjrel: + if op == JUMP_BACKWARD: + arg = -arg label = offset + 2 + arg*2 elif op in hasjabs: label = arg*2 diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 48b55bb821f8b..744fefd5e21e7 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -396,6 +396,7 @@ def _write_atomic(path, data, mode=0o666): # Python 3.11a6 3486 (Use inline caching for PRECALL and CALL) # Python 3.11a6 3487 (Remove the adaptive "oparg counter" mechanism) # Python 3.11a6 3488 (LOAD_GLOBAL can push additional NULL) +# Python 3.11a6 3489 (Add JUMP_BACKWARD, remove JUMP_ABSOLUTE) # Python 3.12 will start with magic number 3500 @@ -410,7 +411,7 @@ def _write_atomic(path, data, mode=0o666): # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array # in PC/launcher.c must also be updated. -MAGIC_NUMBER = (3488).to_bytes(2, 'little') + b'\r\n' +MAGIC_NUMBER = (3489).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c _PYCACHE = '__pycache__' diff --git a/Lib/opcode.py b/Lib/opcode.py index 0b463d3f183aa..6bc64177ac8fc 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -128,10 +128,9 @@ def jabs_op(name, op, entries=0): hascompare.append(107) name_op('IMPORT_NAME', 108) # Index in name list name_op('IMPORT_FROM', 109) # Index in name list -jrel_op('JUMP_FORWARD', 110) # Number of bytes to skip +jrel_op('JUMP_FORWARD', 110) # Number of words to skip jabs_op('JUMP_IF_FALSE_OR_POP', 111) # Target byte offset from beginning of code jabs_op('JUMP_IF_TRUE_OR_POP', 112) # "" -jabs_op('JUMP_ABSOLUTE', 113) # "" jabs_op('POP_JUMP_IF_FALSE', 114) # "" jabs_op('POP_JUMP_IF_TRUE', 115) # "" name_op('LOAD_GLOBAL', 116, 5) # Index in name list @@ -166,6 +165,7 @@ def jabs_op(name, op, entries=0): hasfree.append(138) def_op('DELETE_DEREF', 139) hasfree.append(139) +jrel_op('JUMP_BACKWARD', 140) # Number of words to skip (backwards) def_op('CALL_FUNCTION_EX', 142) # Flags @@ -259,8 +259,8 @@ def jabs_op(name, op, entries=0): "COMPARE_OP_INT_JUMP", "COMPARE_OP_STR_JUMP", ], - "JUMP_ABSOLUTE": [ - "JUMP_ABSOLUTE_QUICK", + "JUMP_BACKWARD": [ + "JUMP_BACKWARD_QUICK", ], "LOAD_ATTR": [ "LOAD_ATTR_ADAPTIVE", diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 16bfee188e046..99db8ba0ac3b9 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -149,7 +149,7 @@ def bug708901(): >> FOR_ITER 2 (to 40) STORE_FAST 0 (res) -%3d JUMP_ABSOLUTE 17 (to 34) +%3d JUMP_BACKWARD 3 (to 34) %3d >> LOAD_CONST 0 (None) RETURN_VALUE @@ -354,7 +354,7 @@ def bug42562(): BINARY_OP 13 (+=) STORE_NAME 0 (x) - 2 JUMP_ABSOLUTE 4 (to 8) + 2 JUMP_BACKWARD 6 (to 8) """ dis_traceback = """\ @@ -574,7 +574,7 @@ def foo(x): LOAD_FAST 1 (z) BINARY_OP 0 (+) LIST_APPEND 2 - JUMP_ABSOLUTE 4 (to 8) + JUMP_BACKWARD 8 (to 8) >> RETURN_VALUE """ % (dis_nested_1, __file__, @@ -1227,14 +1227,14 @@ def _prepare_test_cases(): Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=68, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=70, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=40, argval=80, argrepr='to 80', offset=76, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=16, argval=32, argrepr='to 32', offset=78, starts_line=6, is_jump_target=False, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=140, arg=24, argval=32, argrepr='to 32', offset=78, starts_line=6, is_jump_target=False, positions=None), Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=80, starts_line=7, is_jump_target=True, positions=None), Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=82, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=84, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=48, argval=96, argrepr='to 96', offset=90, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=92, starts_line=8, is_jump_target=False, positions=None), Instruction(opname='JUMP_FORWARD', opcode=110, arg=16, argval=128, argrepr='to 128', offset=94, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=16, argval=32, argrepr='to 32', offset=96, starts_line=7, is_jump_target=True, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=140, arg=33, argval=32, argrepr='to 32', offset=96, starts_line=7, is_jump_target=True, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=98, starts_line=10, is_jump_target=True, positions=None), Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=110, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=112, starts_line=None, is_jump_target=False, positions=None), @@ -1255,7 +1255,7 @@ def _prepare_test_cases(): Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=174, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=176, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=93, argval=186, argrepr='to 186', offset=182, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=64, argval=128, argrepr='to 128', offset=184, starts_line=15, is_jump_target=False, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=140, arg=29, argval=128, argrepr='to 128', offset=184, starts_line=15, is_jump_target=False, positions=None), Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=186, starts_line=16, is_jump_target=True, positions=None), Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=188, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=190, starts_line=None, is_jump_target=False, positions=None), diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py index 6f24b291b00b5..ab715e2e8f6cb 100644 --- a/Lib/test/test_peepholer.py +++ b/Lib/test/test_peepholer.py @@ -127,7 +127,7 @@ def f(): return list for elem in ('LOAD_CONST', 'POP_JUMP_IF_FALSE'): self.assertNotInBytecode(f, elem) - for elem in ('JUMP_ABSOLUTE',): + for elem in ('JUMP_BACKWARD',): self.assertInBytecode(f, elem) self.check_lnotab(f) diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-25-21-51-10.bpo-47120.9YJ-Xw.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-25-21-51-10.bpo-47120.9YJ-Xw.rst new file mode 100644 index 0000000000000..65208c73543d3 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-25-21-51-10.bpo-47120.9YJ-Xw.rst @@ -0,0 +1,2 @@ +Replaced :opcode:`JUMP_ABSOLUTE` by the relative jump :opcode:`JUMP_BACKWARD`. + diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 13dfbf6b9db41..d49931048a625 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -237,7 +237,6 @@ mark_stacks(PyCodeObject *code_obj, int len) stacks[i+1] = next_stack; break; } - case JUMP_ABSOLUTE: case JUMP_NO_INTERRUPT: j = get_arg(code, i); assert(j < len); @@ -264,6 +263,12 @@ mark_stacks(PyCodeObject *code_obj, int len) assert(stacks[j] == UNINITIALIZED || stacks[j] == next_stack); stacks[j] = next_stack; break; + case JUMP_BACKWARD: + j = i + 1 - get_arg(code, i); + assert(j >= 0); + assert(stacks[j] == UNINITIALIZED || stacks[j] == next_stack); + stacks[j] = next_stack; + break; case GET_ITER: case GET_AITER: next_stack = push_value(pop_value(next_stack), Iterator); diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h index 8cae77a4899f1..a3c09529116cc 100644 --- a/Programs/test_frozenmain.h +++ b/Programs/test_frozenmain.h @@ -12,7 +12,7 @@ unsigned char M_test_frozenmain[] = { 68,0,93,25,90,6,2,0,101,2,100,6,101,6,155,0, 100,7,101,5,101,6,25,0,0,0,0,0,0,0,0,0, 155,0,157,4,166,1,0,0,171,1,0,0,0,0,0,0, - 0,0,1,0,113,60,100,1,83,0,41,8,233,0,0,0, + 0,0,1,0,140,26,100,1,83,0,41,8,233,0,0,0, 0,78,122,18,70,114,111,122,101,110,32,72,101,108,108,111, 32,87,111,114,108,100,122,8,115,121,115,46,97,114,103,118, 218,6,99,111,110,102,105,103,41,5,90,12,112,114,111,103, diff --git a/Python/ceval.c b/Python/ceval.c index a7b377724bb54..8f73ea1c01ac5 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2218,7 +2218,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int Py_DECREF(v); if (err != 0) goto error; - PREDICT(JUMP_ABSOLUTE); + PREDICT(JUMP_BACKWARD_QUICK); DISPATCH(); } @@ -2230,7 +2230,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int Py_DECREF(v); if (err != 0) goto error; - PREDICT(JUMP_ABSOLUTE); + PREDICT(JUMP_BACKWARD_QUICK); DISPATCH(); } @@ -3396,7 +3396,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int if (_PyDict_SetItem_Take2((PyDictObject *)map, key, value) != 0) { goto error; } - PREDICT(JUMP_ABSOLUTE); + PREDICT(JUMP_BACKWARD_QUICK); DISPATCH(); } @@ -3926,6 +3926,11 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int DISPATCH(); } + TARGET(JUMP_BACKWARD) { + _PyCode_Warmup(frame->f_code); + JUMP_TO_INSTRUCTION(JUMP_BACKWARD_QUICK); + } + TARGET(POP_JUMP_IF_FALSE) { PREDICTED(POP_JUMP_IF_FALSE); PyObject *cond = POP(); @@ -4053,12 +4058,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int DISPATCH(); } - TARGET(JUMP_ABSOLUTE) { - PREDICTED(JUMP_ABSOLUTE); - _PyCode_Warmup(frame->f_code); - JUMP_TO_INSTRUCTION(JUMP_ABSOLUTE_QUICK); - } - TARGET(JUMP_NO_INTERRUPT) { /* This bytecode is used in the `yield from` or `await` loop. * If there is an interrupt, we want it handled in the innermost @@ -4069,10 +4068,10 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int DISPATCH(); } - TARGET(JUMP_ABSOLUTE_QUICK) { - PREDICTED(JUMP_ABSOLUTE_QUICK); + TARGET(JUMP_BACKWARD_QUICK) { + PREDICTED(JUMP_BACKWARD_QUICK); assert(oparg < INSTR_OFFSET()); - JUMPTO(oparg); + JUMPBY(-oparg); CHECK_EVAL_BREAKER(); DISPATCH(); } diff --git a/Python/compile.c b/Python/compile.c index 06edcf1810e64..7a073777ee1cf 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -76,6 +76,7 @@ #define SETUP_CLEANUP 254 #define SETUP_WITH 253 #define POP_BLOCK 252 +#define JUMP 251 #define IS_TOP_LEVEL_AWAIT(c) ( \ (c->c_flags->cf_flags & PyCF_ALLOW_TOP_LEVEL_AWAIT) \ @@ -127,7 +128,9 @@ is_relative_jump(struct instr *i) static inline int is_jump(struct instr *i) { - return i->i_opcode >= SETUP_WITH || is_bit_set_in_table(_PyOpcode_Jump, i->i_opcode); + return i->i_opcode >= SETUP_WITH || + i->i_opcode == JUMP || + is_bit_set_in_table(_PyOpcode_Jump, i->i_opcode); } static int @@ -985,7 +988,8 @@ stack_effect(int opcode, int oparg, int jump) /* Jumps */ case JUMP_FORWARD: - case JUMP_ABSOLUTE: + case JUMP_BACKWARD: + case JUMP: case JUMP_NO_INTERRUPT: return 0; @@ -2839,7 +2843,7 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond) return 0; if (!compiler_jump_if(c, e->v.IfExp.body, next, cond)) return 0; - ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, end); + ADDOP_JUMP_NOLINE(c, JUMP, end); compiler_use_next_block(c, next2); if (!compiler_jump_if(c, e->v.IfExp.orelse, next, cond)) return 0; @@ -2870,11 +2874,11 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond) basicblock *end = compiler_new_block(c); if (end == NULL) return 0; - ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, end); + ADDOP_JUMP_NOLINE(c, JUMP, end); compiler_use_next_block(c, cleanup); ADDOP(c, POP_TOP); if (!cond) { - ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, next); + ADDOP_JUMP_NOLINE(c, JUMP, next); } compiler_use_next_block(c, end); return 1; @@ -2908,7 +2912,7 @@ compiler_ifexp(struct compiler *c, expr_ty e) if (!compiler_jump_if(c, e->v.IfExp.test, next, 0)) return 0; VISIT(c, expr, e->v.IfExp.body); - ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, end); + ADDOP_JUMP_NOLINE(c, JUMP, end); compiler_use_next_block(c, next); VISIT(c, expr, e->v.IfExp.orelse); compiler_use_next_block(c, end); @@ -2995,7 +2999,7 @@ compiler_if(struct compiler *c, stmt_ty s) } VISIT_SEQ(c, stmt, s->v.If.body); if (asdl_seq_LEN(s->v.If.orelse)) { - ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, end); + ADDOP_JUMP_NOLINE(c, JUMP, end); compiler_use_next_block(c, next); VISIT_SEQ(c, stmt, s->v.If.orelse); } @@ -3027,7 +3031,7 @@ compiler_for(struct compiler *c, stmt_ty s) VISIT_SEQ(c, stmt, s->v.For.body); /* Mark jump as artificial */ UNSET_LOC(c); - ADDOP_JUMP(c, JUMP_ABSOLUTE, start); + ADDOP_JUMP(c, JUMP, start); compiler_use_next_block(c, cleanup); compiler_pop_fblock(c, FOR_LOOP, start); @@ -3072,7 +3076,7 @@ compiler_async_for(struct compiler *c, stmt_ty s) /* Success block for __anext__ */ VISIT(c, expr, s->v.AsyncFor.target); VISIT_SEQ(c, stmt, s->v.AsyncFor.body); - ADDOP_JUMP(c, JUMP_ABSOLUTE, start); + ADDOP_JUMP(c, JUMP, start); compiler_pop_fblock(c, FOR_LOOP, start); @@ -3184,7 +3188,7 @@ compiler_break(struct compiler *c) if (!compiler_unwind_fblock(c, loop, 0)) { return 0; } - ADDOP_JUMP(c, JUMP_ABSOLUTE, loop->fb_exit); + ADDOP_JUMP(c, JUMP, loop->fb_exit); return 1; } @@ -3200,7 +3204,7 @@ compiler_continue(struct compiler *c) if (loop == NULL) { return compiler_error(c, "'continue' not properly in loop"); } - ADDOP_JUMP(c, JUMP_ABSOLUTE, loop->fb_block); + ADDOP_JUMP(c, JUMP, loop->fb_block); return 1; } @@ -3261,7 +3265,7 @@ compiler_try_finally(struct compiler *c, stmt_ty s) ADDOP_NOLINE(c, POP_BLOCK); compiler_pop_fblock(c, FINALLY_TRY, body); VISIT_SEQ(c, stmt, s->v.Try.finalbody); - ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, exit); + ADDOP_JUMP_NOLINE(c, JUMP, exit); /* `finally` block */ compiler_use_next_block(c, end); @@ -3315,7 +3319,7 @@ compiler_try_star_finally(struct compiler *c, stmt_ty s) ADDOP_NOLINE(c, POP_BLOCK); compiler_pop_fblock(c, FINALLY_TRY, body); VISIT_SEQ(c, stmt, s->v.TryStar.finalbody); - ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, exit); + ADDOP_JUMP_NOLINE(c, JUMP, exit); /* `finally` block */ compiler_use_next_block(c, end); @@ -3345,13 +3349,13 @@ compiler_try_star_finally(struct compiler *c, stmt_ty s) [] SETUP_FINALLY L1 [] [] POP_BLOCK - [] JUMP_FORWARD L0 + [] JUMP L0 [exc] L1: ) [exc, E1] JUMP_IF_NOT_EXC_MATCH L2 ) only if E1 [exc] (or POP if no V1) [] - JUMP_FORWARD L0 + JUMP L0 [exc] L2: .............................etc....................... @@ -3384,7 +3388,7 @@ compiler_try_except(struct compiler *c, stmt_ty s) if (s->v.Try.orelse && asdl_seq_LEN(s->v.Try.orelse)) { VISIT_SEQ(c, stmt, s->v.Try.orelse); } - ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, end); + ADDOP_JUMP_NOLINE(c, JUMP, end); n = asdl_seq_LEN(s->v.Try.handlers); compiler_use_next_block(c, except); @@ -3447,7 +3451,7 @@ compiler_try_except(struct compiler *c, stmt_ty s) ADDOP_LOAD_CONST(c, Py_None); compiler_nameop(c, handler->v.ExceptHandler.name, Store); compiler_nameop(c, handler->v.ExceptHandler.name, Del); - ADDOP_JUMP(c, JUMP_FORWARD, end); + ADDOP_JUMP(c, JUMP, end); /* except: */ compiler_use_next_block(c, cleanup_end); @@ -3477,7 +3481,7 @@ compiler_try_except(struct compiler *c, stmt_ty s) UNSET_LOC(c); ADDOP(c, POP_BLOCK); ADDOP(c, POP_EXCEPT); - ADDOP_JUMP(c, JUMP_FORWARD, end); + ADDOP_JUMP(c, JUMP, end); } compiler_use_next_block(c, except); } @@ -3501,7 +3505,7 @@ compiler_try_except(struct compiler *c, stmt_ty s) [] SETUP_FINALLY L1 [] [] POP_BLOCK - [] JUMP_FORWARD L0 + [] JUMP L0 [exc] L1: COPY 1 ) save copy of the original exception [orig, exc] BUILD_LIST ) list for raised/reraised excs ("result") @@ -3514,7 +3518,7 @@ compiler_try_except(struct compiler *c, stmt_ty s) [orig, res, rest] SETUP_FINALLY R1 [orig, res, rest] - [orig, res, rest] JUMP_FORWARD L2 + [orig, res, rest] JUMP L2 [orig, res, rest, i, v] R1: LIST_APPEND 3 ) exc raised in except* body - add to res [orig, res, rest, i] POP @@ -3528,7 +3532,7 @@ compiler_try_except(struct compiler *c, stmt_ty s) [exc] COPY 1 [exc, exc] POP_JUMP_IF_NOT_NONE RER [exc] POP_TOP - [] JUMP_FORWARD L0 + [] JUMP L0 [exc] RER: SWAP 2 [exc, prev_exc_info] POP_EXCEPT @@ -3572,7 +3576,7 @@ compiler_try_star_except(struct compiler *c, stmt_ty s) VISIT_SEQ(c, stmt, s->v.TryStar.body); compiler_pop_fblock(c, TRY_EXCEPT, body); ADDOP_NOLINE(c, POP_BLOCK); - ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, orelse); + ADDOP_JUMP_NOLINE(c, JUMP, orelse); Py_ssize_t n = asdl_seq_LEN(s->v.TryStar.handlers); compiler_use_next_block(c, except); @@ -3657,7 +3661,7 @@ compiler_try_star_except(struct compiler *c, stmt_ty s) compiler_nameop(c, handler->v.ExceptHandler.name, Store); compiler_nameop(c, handler->v.ExceptHandler.name, Del); } - ADDOP_JUMP(c, JUMP_FORWARD, except); + ADDOP_JUMP(c, JUMP, except); /* except: */ compiler_use_next_block(c, cleanup_end); @@ -3675,13 +3679,13 @@ compiler_try_star_except(struct compiler *c, stmt_ty s) ADDOP_I(c, LIST_APPEND, 3); // exc ADDOP(c, POP_TOP); // lasti - ADDOP_JUMP(c, JUMP_ABSOLUTE, except); + ADDOP_JUMP(c, JUMP, except); compiler_use_next_block(c, except); if (i == n - 1) { /* Add exc to the list (if not None it's the unhandled part of the EG) */ ADDOP_I(c, LIST_APPEND, 1); - ADDOP_JUMP(c, JUMP_FORWARD, reraise_star); + ADDOP_JUMP(c, JUMP, reraise_star); } } /* Mark as artificial */ @@ -3701,7 +3705,7 @@ compiler_try_star_except(struct compiler *c, stmt_ty s) ADDOP(c, POP_TOP); ADDOP(c, POP_BLOCK); ADDOP(c, POP_EXCEPT); - ADDOP_JUMP(c, JUMP_FORWARD, end); + ADDOP_JUMP(c, JUMP, end); compiler_use_next_block(c, reraise); ADDOP(c, POP_BLOCK); ADDOP_I(c, SWAP, 2); @@ -4542,7 +4546,7 @@ compiler_compare(struct compiler *c, expr_ty e) basicblock *end = compiler_new_block(c); if (end == NULL) return 0; - ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, end); + ADDOP_JUMP_NOLINE(c, JUMP, end); compiler_use_next_block(c, cleanup); ADDOP_I(c, SWAP, 2); ADDOP(c, POP_TOP); @@ -5172,7 +5176,7 @@ compiler_sync_comprehension_generator(struct compiler *c, } compiler_use_next_block(c, if_cleanup); if (start) { - ADDOP_JUMP(c, JUMP_ABSOLUTE, start); + ADDOP_JUMP(c, JUMP, start); compiler_use_next_block(c, anchor); } @@ -5266,7 +5270,7 @@ compiler_async_comprehension_generator(struct compiler *c, } } compiler_use_next_block(c, if_cleanup); - ADDOP_JUMP(c, JUMP_ABSOLUTE, start); + ADDOP_JUMP(c, JUMP, start); compiler_pop_fblock(c, ASYNC_COMPREHENSION_GENERATOR, start); @@ -5542,7 +5546,7 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos) ADDOP(c, POP_TOP); - ADDOP_JUMP(c, JUMP_ABSOLUTE, exit); + ADDOP_JUMP(c, JUMP, exit); /* For exceptional outcome: */ compiler_use_next_block(c, final); @@ -5571,7 +5575,7 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos) LOAD_CONST (None, None, None) CALL_FUNCTION_EX 0 - JUMP_FORWARD EXIT + JUMP EXIT E: WITH_EXCEPT_START (calls EXPR.__exit__) POP_JUMP_IF_TRUE T: RERAISE @@ -5638,7 +5642,7 @@ compiler_with(struct compiler *c, stmt_ty s, int pos) if (!compiler_call_exit_with_nones(c)) return 0; ADDOP(c, POP_TOP); - ADDOP_JUMP(c, JUMP_FORWARD, exit); + ADDOP_JUMP(c, JUMP, exit); /* For exceptional outcome: */ compiler_use_next_block(c, final); @@ -6687,7 +6691,7 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) } } assert(control); - if (!compiler_addop_j(c, JUMP_FORWARD, end) || + if (!compiler_addop_j(c, JUMP, end) || !emit_and_reset_fail_pop(c, pc)) { goto error; @@ -6699,7 +6703,7 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) // Need to NULL this for the PyObject_Free call in the error block. old_pc.fail_pop = NULL; // No match. Pop the remaining copy of the subject and fail: - if (!compiler_addop(c, POP_TOP) || !jump_to_fail_pop(c, pc, JUMP_FORWARD)) { + if (!compiler_addop(c, POP_TOP) || !jump_to_fail_pop(c, pc, JUMP)) { goto error; } compiler_use_next_block(c, end); @@ -6906,7 +6910,7 @@ compiler_match_inner(struct compiler *c, stmt_ty s, pattern_context *pc) ADDOP(c, POP_TOP); } VISIT_SEQ(c, stmt, m->body); - ADDOP_JUMP(c, JUMP_FORWARD, end); + ADDOP_JUMP(c, JUMP, end); // If the pattern fails to match, we want the line number of the // cleanup to be associated with the failed pattern, not the last line // of the body @@ -7045,9 +7049,10 @@ stackdepth(struct compiler *c) stackdepth_push(&sp, instr->i_target, target_depth); } depth = new_depth; - if (instr->i_opcode == JUMP_ABSOLUTE || - instr->i_opcode == JUMP_NO_INTERRUPT || - instr->i_opcode == JUMP_FORWARD || + assert(instr->i_opcode != JUMP_FORWARD); + assert(instr->i_opcode != JUMP_BACKWARD); + if (instr->i_opcode == JUMP_NO_INTERRUPT || + instr->i_opcode == JUMP || instr->i_opcode == RETURN_VALUE || instr->i_opcode == RAISE_VARARGS || instr->i_opcode == RERAISE) @@ -7559,14 +7564,14 @@ normalize_jumps(struct assembler *a) continue; } struct instr *last = &b->b_instr[b->b_iused-1]; - if (last->i_opcode == JUMP_ABSOLUTE) { + assert(last->i_opcode != JUMP_FORWARD); + assert(last->i_opcode != JUMP_BACKWARD); + if (last->i_opcode == JUMP) { if (last->i_target->b_visited == 0) { last->i_opcode = JUMP_FORWARD; } - } - if (last->i_opcode == JUMP_FORWARD) { - if (last->i_target->b_visited == 1) { - last->i_opcode = JUMP_ABSOLUTE; + else { + last->i_opcode = JUMP_BACKWARD; } } } @@ -7602,7 +7607,14 @@ assemble_jump_offsets(struct assembler *a, struct compiler *c) if (is_jump(instr)) { instr->i_oparg = instr->i_target->b_offset; if (is_relative_jump(instr)) { - instr->i_oparg -= bsize; + if (instr->i_oparg < bsize) { + assert(instr->i_opcode == JUMP_BACKWARD); + instr->i_oparg = bsize - instr->i_oparg; + } + else { + assert(instr->i_opcode != JUMP_BACKWARD); + instr->i_oparg -= bsize; + } } if (instr_size(instr) != isize) { extended_arg_recompile = 1; @@ -8621,10 +8633,14 @@ optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts) inst->i_target = inst->i_target->b_next; } target = &inst->i_target->b_instr[0]; + assert(target->i_opcode != JUMP_FORWARD); + assert(target->i_opcode != JUMP_BACKWARD); } else { target = &nop; } + assert(inst->i_opcode != JUMP_FORWARD); + assert(inst->i_opcode != JUMP_BACKWARD); switch (inst->i_opcode) { /* Remove LOAD_CONST const; conditional jump */ case LOAD_CONST: @@ -8647,7 +8663,7 @@ optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts) inst->i_opcode = NOP; jump_if_true = nextop == POP_JUMP_IF_TRUE; if (is_true == jump_if_true) { - bb->b_instr[i+1].i_opcode = JUMP_ABSOLUTE; + bb->b_instr[i+1].i_opcode = JUMP; bb->b_nofallthrough = 1; } else { @@ -8667,7 +8683,7 @@ optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts) } jump_if_true = nextop == JUMP_IF_TRUE_OR_POP; if (is_true == jump_if_true) { - bb->b_instr[i+1].i_opcode = JUMP_ABSOLUTE; + bb->b_instr[i+1].i_opcode = JUMP; bb->b_nofallthrough = 1; } else { @@ -8738,8 +8754,7 @@ optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts) case POP_JUMP_IF_FALSE: i -= jump_thread(inst, target, POP_JUMP_IF_FALSE); break; - case JUMP_ABSOLUTE: - case JUMP_FORWARD: + case JUMP: case JUMP_IF_FALSE_OR_POP: i -= jump_thread(inst, target, JUMP_IF_FALSE_OR_POP); break; @@ -8761,8 +8776,7 @@ optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts) case POP_JUMP_IF_TRUE: i -= jump_thread(inst, target, POP_JUMP_IF_TRUE); break; - case JUMP_ABSOLUTE: - case JUMP_FORWARD: + case JUMP: case JUMP_IF_TRUE_OR_POP: i -= jump_thread(inst, target, JUMP_IF_TRUE_OR_POP); break; @@ -8782,36 +8796,38 @@ optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts) case POP_JUMP_IF_NOT_NONE: case POP_JUMP_IF_NONE: switch (target->i_opcode) { - case JUMP_ABSOLUTE: - case JUMP_FORWARD: + case JUMP: i -= jump_thread(inst, target, inst->i_opcode); } break; case POP_JUMP_IF_FALSE: switch (target->i_opcode) { - case JUMP_ABSOLUTE: - case JUMP_FORWARD: + case JUMP: i -= jump_thread(inst, target, POP_JUMP_IF_FALSE); } break; case POP_JUMP_IF_TRUE: switch (target->i_opcode) { - case JUMP_ABSOLUTE: - case JUMP_FORWARD: + case JUMP: i -= jump_thread(inst, target, POP_JUMP_IF_TRUE); } break; - case JUMP_ABSOLUTE: - case JUMP_FORWARD: + case JUMP: switch (target->i_opcode) { - case JUMP_ABSOLUTE: - case JUMP_FORWARD: - i -= jump_thread(inst, target, JUMP_ABSOLUTE); + case JUMP: + i -= jump_thread(inst, target, JUMP); } break; case FOR_ITER: - if (target->i_opcode == JUMP_FORWARD) { + if (target->i_opcode == JUMP) { + /* This will not work now because the jump (at target) could + * be forward or backward and FOR_ITER only jumps forward. We + * can re-enable this if ever we implement a backward version + * of FOR_ITER. + */ + /* i -= jump_thread(inst, target, FOR_ITER); + */ } break; case SWAP: @@ -8852,7 +8868,9 @@ extend_block(basicblock *bb) { return 0; } struct instr *last = &bb->b_instr[bb->b_iused-1]; - if (last->i_opcode != JUMP_ABSOLUTE && last->i_opcode != JUMP_FORWARD) { + if (last->i_opcode != JUMP && + last->i_opcode != JUMP_FORWARD && + last->i_opcode != JUMP_BACKWARD) { return 0; } if (last->i_target->b_exit && last->i_target->b_iused <= MAX_COPY_SIZE) { @@ -8923,6 +8941,8 @@ normalize_basic_block(basicblock *bb) { /* Mark blocks as exit and/or nofallthrough. Raise SystemError if CFG is malformed. */ for (int i = 0; i < bb->b_iused; i++) { + assert(bb->b_instr[i].i_opcode != JUMP_FORWARD); + assert(bb->b_instr[i].i_opcode != JUMP_BACKWARD); switch(bb->b_instr[i].i_opcode) { case RETURN_VALUE: case RAISE_VARARGS: @@ -8930,8 +8950,7 @@ normalize_basic_block(basicblock *bb) { bb->b_exit = 1; bb->b_nofallthrough = 1; break; - case JUMP_ABSOLUTE: - case JUMP_FORWARD: + case JUMP: case JUMP_NO_INTERRUPT: bb->b_nofallthrough = 1; /* fall through */ @@ -9116,9 +9135,10 @@ optimize_cfg(struct compiler *c, struct assembler *a, PyObject *consts) for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { if (b->b_iused > 0) { struct instr *b_last_instr = &b->b_instr[b->b_iused - 1]; - if (b_last_instr->i_opcode == JUMP_ABSOLUTE || - b_last_instr->i_opcode == JUMP_NO_INTERRUPT || - b_last_instr->i_opcode == JUMP_FORWARD) { + assert(b_last_instr->i_opcode != JUMP_FORWARD); + assert(b_last_instr->i_opcode != JUMP_BACKWARD); + if (b_last_instr->i_opcode == JUMP || + b_last_instr->i_opcode == JUMP_NO_INTERRUPT) { if (b_last_instr->i_target == b->b_next) { assert(b->b_next->b_iused); b->b_nofallthrough = 0; diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index dbcacee7e0205..3afaf0b029831 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -33,7 +33,7 @@ static void *opcode_targets[256] = { &&TARGET_MATCH_MAPPING, &&TARGET_MATCH_SEQUENCE, &&TARGET_MATCH_KEYS, - &&TARGET_JUMP_ABSOLUTE_QUICK, + &&TARGET_JUMP_BACKWARD_QUICK, &&TARGET_PUSH_EXC_INFO, &&TARGET_LOAD_ATTR_ADAPTIVE, &&TARGET_LOAD_ATTR_INSTANCE_VALUE, @@ -112,7 +112,7 @@ static void *opcode_targets[256] = { &&TARGET_JUMP_FORWARD, &&TARGET_JUMP_IF_FALSE_OR_POP, &&TARGET_JUMP_IF_TRUE_OR_POP, - &&TARGET_JUMP_ABSOLUTE, + &&TARGET_PRECALL_NO_KW_TYPE_1, &&TARGET_POP_JUMP_IF_FALSE, &&TARGET_POP_JUMP_IF_TRUE, &&TARGET_LOAD_GLOBAL, @@ -139,7 +139,7 @@ static void *opcode_targets[256] = { &&TARGET_LOAD_DEREF, &&TARGET_STORE_DEREF, &&TARGET_DELETE_DEREF, - &&TARGET_PRECALL_NO_KW_TYPE_1, + &&TARGET_JUMP_BACKWARD, &&TARGET_PRECALL_PYFUNC, &&TARGET_CALL_FUNCTION_EX, &&TARGET_RESUME_QUICK, diff --git a/Python/specialize.c b/Python/specialize.c index 244318a609e66..08c69041e78b0 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -270,8 +270,8 @@ _PyCode_Quicken(PyCodeObject *code) else { assert(!_PyOpcode_Caches[opcode]); switch (opcode) { - case JUMP_ABSOLUTE: - _Py_SET_OPCODE(instructions[i], JUMP_ABSOLUTE_QUICK); + case JUMP_BACKWARD: + _Py_SET_OPCODE(instructions[i], JUMP_BACKWARD_QUICK); break; case RESUME: _Py_SET_OPCODE(instructions[i], RESUME_QUICK); From webhook-mailer at python.org Thu Mar 31 09:57:03 2022 From: webhook-mailer at python.org (asvetlov) Date: Thu, 31 Mar 2022 13:57:03 -0000 Subject: [Python-checkins] bpo-14911: Corrected generator.throw() documentation (GH-32207) Message-ID: https://github.com/python/cpython/commit/8be7c2bc5ad5e295f0f855bb31db412eef2c7c92 commit: 8be7c2bc5ad5e295f0f855bb31db412eef2c7c92 branch: main author: Dave Goncalves committer: asvetlov date: 2022-03-31T16:56:48+03:00 summary: bpo-14911: Corrected generator.throw() documentation (GH-32207) Co-authored-by: Andrew Svetlov files: M Doc/howto/functional.rst M Doc/reference/datamodel.rst M Doc/reference/expressions.rst M Objects/genobject.c diff --git a/Doc/howto/functional.rst b/Doc/howto/functional.rst index c7f8bc8f17f43..695b9b31a762b 100644 --- a/Doc/howto/functional.rst +++ b/Doc/howto/functional.rst @@ -589,7 +589,7 @@ generator function. In addition to :meth:`~generator.send`, there are two other methods on generators: -* :meth:`throw(type, value=None, traceback=None) ` is used to +* :meth:`throw(value) ` is used to raise an exception inside the generator; the exception is raised by the ``yield`` expression where the generator's execution is paused. diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 804332ffab6fd..8ac9a8c0566bf 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -2984,7 +2984,8 @@ generators, coroutines do not directly support iteration. :exc:`StopIteration`, or other exception) is the same as when iterating over the :meth:`__await__` return value, described above. -.. method:: coroutine.throw(type[, value[, traceback]]) +.. method:: coroutine.throw(value) + coroutine.throw(type[, value[, traceback]]) Raises the specified exception in the coroutine. This method delegates to the :meth:`~generator.throw` method of the iterator that caused diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index bb6d1dc1cdd04..b914c48d3d4cd 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -561,14 +561,27 @@ is already executing raises a :exc:`ValueError` exception. could receive the value. -.. method:: generator.throw(type[, value[, traceback]]) +.. method:: generator.throw(value) + generator.throw(type[, value[, traceback]]) - Raises an exception of type ``type`` at the point where the generator was paused, + Raises an exception at the point where the generator was paused, and returns the next value yielded by the generator function. If the generator exits without yielding another value, a :exc:`StopIteration` exception is raised. If the generator function does not catch the passed-in exception, or raises a different exception, then that exception propagates to the caller. + In typical use, this is called with a single exception instance similar to the + way the :keyword:`raise` keyword is used. + + For backwards compatability, however, the second signature is + supported, following a convention from older versions of Python. + The *type* argument should be an exception class, and *value* + should be an exception instance. If the *value* is not provided, the + *type* constructor is called to get an instance. If *traceback* + is provided, it is set on the exception, otherwise any existing + :attr:`~BaseException.__traceback__` attribute stored in *value* may + be cleared. + .. index:: exception: GeneratorExit diff --git a/Objects/genobject.c b/Objects/genobject.c index f071390d6d32b..cdb2a0f76b085 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -410,8 +410,11 @@ gen_close(PyGenObject *gen, PyObject *args) PyDoc_STRVAR(throw_doc, -"throw(typ[,val[,tb]]) -> raise exception in generator,\n\ -return next yielded value or raise StopIteration."); +"throw(value)\n\ +throw(type[,value[,tb]])\n\ +\n\ +Raise exception in generator, return next yielded value or raise\n\ +StopIteration."); static PyObject * _gen_throw(PyGenObject *gen, int close_on_genexit, @@ -1157,8 +1160,11 @@ PyDoc_STRVAR(coro_send_doc, return next iterated value or raise StopIteration."); PyDoc_STRVAR(coro_throw_doc, -"throw(typ[,val[,tb]]) -> raise exception in coroutine,\n\ -return next iterated value or raise StopIteration."); +"throw(value)\n\ +throw(type[,value[,traceback]])\n\ +\n\ +Raise exception in coroutine, return next iterated value or raise\n\ +StopIteration."); PyDoc_STRVAR(coro_close_doc, "close() -> raise GeneratorExit inside coroutine."); From webhook-mailer at python.org Thu Mar 31 10:11:47 2022 From: webhook-mailer at python.org (rhettinger) Date: Thu, 31 Mar 2022 14:11:47 -0000 Subject: [Python-checkins] Remove unnecessary registration of weakref.WeakSet to _collections_abc.Set (GH-32211) Message-ID: https://github.com/python/cpython/commit/5458b7e39eb41b146c650b76e04ac67213138a82 commit: 5458b7e39eb41b146c650b76e04ac67213138a82 branch: main author: G?ry Ogam committer: rhettinger date: 2022-03-31T09:11:35-05:00 summary: Remove unnecessary registration of weakref.WeakSet to _collections_abc.Set (GH-32211) files: M Lib/weakref.py diff --git a/Lib/weakref.py b/Lib/weakref.py index 42aba654de549..25b70927e29c3 100644 --- a/Lib/weakref.py +++ b/Lib/weakref.py @@ -33,7 +33,6 @@ "WeakSet", "WeakMethod", "finalize"] -_collections_abc.Set.register(WeakSet) _collections_abc.MutableSet.register(WeakSet) class WeakMethod(ref): From webhook-mailer at python.org Thu Mar 31 10:23:13 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 31 Mar 2022 14:23:13 -0000 Subject: [Python-checkins] bpo-14911: Corrected generator.throw() documentation (GH-32207) Message-ID: https://github.com/python/cpython/commit/625f6704c0d783360574bbab2f78b0b9bbed5891 commit: 625f6704c0d783360574bbab2f78b0b9bbed5891 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-31T07:23:04-07:00 summary: bpo-14911: Corrected generator.throw() documentation (GH-32207) Co-authored-by: Andrew Svetlov (cherry picked from commit 8be7c2bc5ad5e295f0f855bb31db412eef2c7c92) Co-authored-by: Dave Goncalves files: M Doc/howto/functional.rst M Doc/reference/datamodel.rst M Doc/reference/expressions.rst M Objects/genobject.c diff --git a/Doc/howto/functional.rst b/Doc/howto/functional.rst index c7f8bc8f17f43..695b9b31a762b 100644 --- a/Doc/howto/functional.rst +++ b/Doc/howto/functional.rst @@ -589,7 +589,7 @@ generator function. In addition to :meth:`~generator.send`, there are two other methods on generators: -* :meth:`throw(type, value=None, traceback=None) ` is used to +* :meth:`throw(value) ` is used to raise an exception inside the generator; the exception is raised by the ``yield`` expression where the generator's execution is paused. diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 3c32210a6ac7b..a5739e6e5e472 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -2913,7 +2913,8 @@ generators, coroutines do not directly support iteration. :exc:`StopIteration`, or other exception) is the same as when iterating over the :meth:`__await__` return value, described above. -.. method:: coroutine.throw(type[, value[, traceback]]) +.. method:: coroutine.throw(value) + coroutine.throw(type[, value[, traceback]]) Raises the specified exception in the coroutine. This method delegates to the :meth:`~generator.throw` method of the iterator that caused diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 9f136c9a88ff3..f77927d86d9d6 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -556,14 +556,27 @@ is already executing raises a :exc:`ValueError` exception. could receive the value. -.. method:: generator.throw(type[, value[, traceback]]) +.. method:: generator.throw(value) + generator.throw(type[, value[, traceback]]) - Raises an exception of type ``type`` at the point where the generator was paused, + Raises an exception at the point where the generator was paused, and returns the next value yielded by the generator function. If the generator exits without yielding another value, a :exc:`StopIteration` exception is raised. If the generator function does not catch the passed-in exception, or raises a different exception, then that exception propagates to the caller. + In typical use, this is called with a single exception instance similar to the + way the :keyword:`raise` keyword is used. + + For backwards compatability, however, the second signature is + supported, following a convention from older versions of Python. + The *type* argument should be an exception class, and *value* + should be an exception instance. If the *value* is not provided, the + *type* constructor is called to get an instance. If *traceback* + is provided, it is set on the exception, otherwise any existing + :attr:`~BaseException.__traceback__` attribute stored in *value* may + be cleared. + .. index:: exception: GeneratorExit diff --git a/Objects/genobject.c b/Objects/genobject.c index 33fc4a592492a..123c17aae7e7c 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -403,8 +403,11 @@ gen_close(PyGenObject *gen, PyObject *args) PyDoc_STRVAR(throw_doc, -"throw(typ[,val[,tb]]) -> raise exception in generator,\n\ -return next yielded value or raise StopIteration."); +"throw(value)\n\ +throw(type[,value[,tb]])\n\ +\n\ +Raise exception in generator, return next yielded value or raise\n\ +StopIteration."); static PyObject * _gen_throw(PyGenObject *gen, int close_on_genexit, @@ -1001,8 +1004,11 @@ PyDoc_STRVAR(coro_send_doc, return next iterated value or raise StopIteration."); PyDoc_STRVAR(coro_throw_doc, -"throw(typ[,val[,tb]]) -> raise exception in coroutine,\n\ -return next iterated value or raise StopIteration."); +"throw(value)\n\ +throw(type[,value[,traceback]])\n\ +\n\ +Raise exception in coroutine, return next iterated value or raise\n\ +StopIteration."); PyDoc_STRVAR(coro_close_doc, "close() -> raise GeneratorExit inside coroutine."); From webhook-mailer at python.org Thu Mar 31 10:24:44 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 31 Mar 2022 14:24:44 -0000 Subject: [Python-checkins] bpo-14911: Corrected generator.throw() documentation (GH-32207) Message-ID: https://github.com/python/cpython/commit/98d57737de73342d33d1b90dc0285f586465d22b commit: 98d57737de73342d33d1b90dc0285f586465d22b branch: 3.9 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-31T07:24:39-07:00 summary: bpo-14911: Corrected generator.throw() documentation (GH-32207) Co-authored-by: Andrew Svetlov (cherry picked from commit 8be7c2bc5ad5e295f0f855bb31db412eef2c7c92) Co-authored-by: Dave Goncalves files: M Doc/howto/functional.rst M Doc/reference/datamodel.rst M Doc/reference/expressions.rst M Objects/genobject.c diff --git a/Doc/howto/functional.rst b/Doc/howto/functional.rst index c7f8bc8f17f43..695b9b31a762b 100644 --- a/Doc/howto/functional.rst +++ b/Doc/howto/functional.rst @@ -589,7 +589,7 @@ generator function. In addition to :meth:`~generator.send`, there are two other methods on generators: -* :meth:`throw(type, value=None, traceback=None) ` is used to +* :meth:`throw(value) ` is used to raise an exception inside the generator; the exception is raised by the ``yield`` expression where the generator's execution is paused. diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 84320f41f6cae..033d65fd7c90f 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -2854,7 +2854,8 @@ generators, coroutines do not directly support iteration. :exc:`StopIteration`, or other exception) is the same as when iterating over the :meth:`__await__` return value, described above. -.. method:: coroutine.throw(type[, value[, traceback]]) +.. method:: coroutine.throw(value) + coroutine.throw(type[, value[, traceback]]) Raises the specified exception in the coroutine. This method delegates to the :meth:`~generator.throw` method of the iterator that caused diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 4ffb6512107f2..502c022501eff 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -557,14 +557,27 @@ is already executing raises a :exc:`ValueError` exception. could receive the value. -.. method:: generator.throw(type[, value[, traceback]]) +.. method:: generator.throw(value) + generator.throw(type[, value[, traceback]]) - Raises an exception of type ``type`` at the point where the generator was paused, + Raises an exception at the point where the generator was paused, and returns the next value yielded by the generator function. If the generator exits without yielding another value, a :exc:`StopIteration` exception is raised. If the generator function does not catch the passed-in exception, or raises a different exception, then that exception propagates to the caller. + In typical use, this is called with a single exception instance similar to the + way the :keyword:`raise` keyword is used. + + For backwards compatability, however, the second signature is + supported, following a convention from older versions of Python. + The *type* argument should be an exception class, and *value* + should be an exception instance. If the *value* is not provided, the + *type* constructor is called to get an instance. If *traceback* + is provided, it is set on the exception, otherwise any existing + :attr:`~BaseException.__traceback__` attribute stored in *value* may + be cleared. + .. index:: exception: GeneratorExit diff --git a/Objects/genobject.c b/Objects/genobject.c index 5ba4de82ea70e..95614729c8fab 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -384,8 +384,11 @@ gen_close(PyGenObject *gen, PyObject *args) PyDoc_STRVAR(throw_doc, -"throw(typ[,val[,tb]]) -> raise exception in generator,\n\ -return next yielded value or raise StopIteration."); +"throw(value)\n\ +throw(type[,value[,tb]])\n\ +\n\ +Raise exception in generator, return next yielded value or raise\n\ +StopIteration."); static PyObject * _gen_throw(PyGenObject *gen, int close_on_genexit, @@ -943,8 +946,11 @@ PyDoc_STRVAR(coro_send_doc, return next iterated value or raise StopIteration."); PyDoc_STRVAR(coro_throw_doc, -"throw(typ[,val[,tb]]) -> raise exception in coroutine,\n\ -return next iterated value or raise StopIteration."); +"throw(value)\n\ +throw(type[,value[,traceback]])\n\ +\n\ +Raise exception in coroutine, return next iterated value or raise\n\ +StopIteration."); PyDoc_STRVAR(coro_close_doc, "close() -> raise GeneratorExit inside coroutine."); From webhook-mailer at python.org Thu Mar 31 11:15:02 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 31 Mar 2022 15:15:02 -0000 Subject: [Python-checkins] bpo-47182: Fix crash by named unicode characters after interpreter reinitialization (GH-32212) Message-ID: https://github.com/python/cpython/commit/44e915028d75f7cef141aa1aada962465a5907d6 commit: 44e915028d75f7cef141aa1aada962465a5907d6 branch: main author: Christian Heimes committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-31T08:14:50-07:00 summary: bpo-47182: Fix crash by named unicode characters after interpreter reinitialization (GH-32212) Automerge-Triggered-By: GH:tiran files: A Misc/NEWS.d/next/Core and Builtins/2022-03-31-15-37-02.bpo-47182.e_4SsC.rst M Lib/test/test_embed.py M Objects/unicodeobject.c diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index f0c88de68e89e..7e5e4c144851e 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -343,6 +343,11 @@ def test_finalize_structseq(self): out, err = self.run_embedded_interpreter("test_repeated_init_exec", code) self.assertEqual(out, 'Tests passed\n' * INIT_LOOPS) + def test_ucnhash_capi_reset(self): + # bpo-47182: unicodeobject.c:ucnhash_capi was not reset on shutdown. + code = "print('\\N{digit nine}')" + out, err = self.run_embedded_interpreter("test_repeated_init_exec", code) + self.assertEqual(out, '9\n' * INIT_LOOPS) class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): maxDiff = 4096 diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-31-15-37-02.bpo-47182.e_4SsC.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-31-15-37-02.bpo-47182.e_4SsC.rst new file mode 100644 index 0000000000000..08036bc680933 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-31-15-37-02.bpo-47182.e_4SsC.rst @@ -0,0 +1,2 @@ +Fix a crash when using a named unicode character like ``"\N{digit nine}"`` +after the main interpreter has been initialized a second time. diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 5a1d2c0630167..2d4096397784f 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -16085,6 +16085,9 @@ _PyUnicode_Fini(PyInterpreterState *interp) if (_Py_IsMainInterpreter(interp)) { // _PyUnicode_ClearInterned() must be called before _PyUnicode_Fini() assert(interned == NULL); + // bpo-47182: force a unicodedata CAPI capsule re-import on + // subsequent initialization of main interpreter. + ucnhash_capi = NULL; } _PyUnicode_FiniEncodings(&state->fs_codec); From webhook-mailer at python.org Thu Mar 31 12:13:36 2022 From: webhook-mailer at python.org (markshannon) Date: Thu, 31 Mar 2022 16:13:36 -0000 Subject: [Python-checkins] bpo-40421: Add missing getters for frame object attributes to C-API. (GH-32114) Message-ID: https://github.com/python/cpython/commit/74b95d86e0f14603f878c4df3133bc8a93f8f80a commit: 74b95d86e0f14603f878c4df3133bc8a93f8f80a branch: main author: Mark Shannon committer: markshannon date: 2022-03-31T17:13:25+01:00 summary: bpo-40421: Add missing getters for frame object attributes to C-API. (GH-32114) files: A Misc/NEWS.d/next/C API/2022-03-25-13-40-46.bpo-40421.wJREl2.rst M Doc/c-api/frame.rst M Doc/whatsnew/3.11.rst M Include/cpython/frameobject.h M Lib/test/test_capi.py M Modules/_testcapimodule.c M Objects/frameobject.c diff --git a/Doc/c-api/frame.rst b/Doc/c-api/frame.rst index 0c11bc163b417..6d265e45659f9 100644 --- a/Doc/c-api/frame.rst +++ b/Doc/c-api/frame.rst @@ -30,6 +30,17 @@ See also :ref:`Reflection `. .. versionadded:: 3.9 +.. c:function:: PyObject* PyFrame_GetBuiltins(PyFrameObject *frame) + + Get the *frame*'s ``f_builtins`` attribute. + + Return a :term:`strong reference`. The result cannot be ``NULL``. + + *frame* must not be ``NULL``. + + .. versionadded:: 3.11 + + .. c:function:: PyCodeObject* PyFrame_GetCode(PyFrameObject *frame) Get the *frame* code. @@ -41,6 +52,30 @@ See also :ref:`Reflection `. .. versionadded:: 3.9 +.. c:function:: PyObject* PyFrame_GetGenerator(PyFrameObject *frame) + + Get the generator, coroutine, or async generator that owns this frame, + or ``NULL`` if this frame is not owned by a generator. + Does not raise an exception, even if the return value is ``NULL``. + + Return a :term:`strong reference`, or ``NULL``. + + *frame* must not be ``NULL``. + + .. versionadded:: 3.11 + + +.. c:function:: PyObject* PyFrame_GetGlobals(PyFrameObject *frame) + + Get the *frame*'s ``f_globals`` attribute. + + Return a :term:`strong reference`. The result cannot be ``NULL``. + + *frame* must not be ``NULL``. + + .. versionadded:: 3.11 + + .. c:function:: PyObject* PyFrame_GetLocals(PyFrameObject *frame) Get the *frame*'s ``f_locals`` attribute (:class:`dict`). diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 1bd958724f3be..16715c32502e4 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -868,6 +868,9 @@ New Features :c:func:`PyFloat_Unpack8`. (Contributed by Victor Stinner in :issue:`46906`.) +* Add new functions to get frame object attributes: + :c:func:`PyFrame_GetBuiltins`, :c:func:`PyFrame_GetGenerator`, + :c:func:`PyFrame_GetGlobals`. Porting to Python 3.11 ---------------------- @@ -985,13 +988,13 @@ Porting to Python 3.11 * ``f_back``: use :c:func:`PyFrame_GetBack`. * ``f_blockstack``: removed. - * ``f_builtins``: use ``PyObject_GetAttrString((PyObject*)frame, "f_builtins")``. + * ``f_builtins``: use :c:func:`PyFrame_GetBuiltins`. * ``f_code``: use :c:func:`PyFrame_GetCode`. - * ``f_gen``: removed. - * ``f_globals``: use ``PyObject_GetAttrString((PyObject*)frame, "f_globals")``. + * ``f_gen``: use :c:func:`PyFrame_GetGenerator`. + * ``f_globals``: use :c:func:`PyFrame_GetGlobals`. * ``f_iblock``: removed. * ``f_lasti``: use ``PyObject_GetAttrString((PyObject*)frame, "f_lasti")``. - Code using ``f_lasti`` with ``PyCode_Addr2Line()`` must use + Code using ``f_lasti`` with ``PyCode_Addr2Line()`` should use :c:func:`PyFrame_GetLineNumber` instead. * ``f_lineno``: use :c:func:`PyFrame_GetLineNumber` * ``f_locals``: use :c:func:`PyFrame_GetLocals`. diff --git a/Include/cpython/frameobject.h b/Include/cpython/frameobject.h index d54d3652a0dbc..ffeb8bd04a46f 100644 --- a/Include/cpython/frameobject.h +++ b/Include/cpython/frameobject.h @@ -24,3 +24,8 @@ PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *); PyAPI_FUNC(PyFrameObject *) PyFrame_GetBack(PyFrameObject *frame); PyAPI_FUNC(PyObject *) PyFrame_GetLocals(PyFrameObject *frame); + +PyAPI_FUNC(PyObject *) PyFrame_GetGlobals(PyFrameObject *frame); +PyAPI_FUNC(PyObject *) PyFrame_GetBuiltins(PyFrameObject *frame); + +PyAPI_FUNC(PyObject *) PyFrame_GetGenerator(PyFrameObject *frame); diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index d9615430327a4..238acf94526a3 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -1087,5 +1087,25 @@ class Subclass(BaseException, self.module.StateAccessType): self.assertIs(Subclass().get_defining_module(), self.module) +class Test_FrameAPI(unittest.TestCase): + + def getframe(self): + return sys._getframe() + + def getgenframe(self): + yield sys._getframe() + + def test_frame_getters(self): + frame = self.getframe() + self.assertEquals(frame.f_locals, _testcapi.frame_getlocals(frame)) + self.assertIs(frame.f_globals, _testcapi.frame_getglobals(frame)) + self.assertIs(frame.f_builtins, _testcapi.frame_getbuiltins(frame)) + + def test_frame_get_generator(self): + gen = self.getgenframe() + frame = next(gen) + self.assertIs(gen, _testcapi.frame_getgenerator(frame)) + + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/C API/2022-03-25-13-40-46.bpo-40421.wJREl2.rst b/Misc/NEWS.d/next/C API/2022-03-25-13-40-46.bpo-40421.wJREl2.rst new file mode 100644 index 0000000000000..95b7b69347ce4 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2022-03-25-13-40-46.bpo-40421.wJREl2.rst @@ -0,0 +1,3 @@ +Add ``PyFrame_GetBuiltins``, ``PyFrame_GetGenerator`` and +``PyFrame_GetGlobals`` C-API functions to access frame object attributes +safely from C code. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 019c2b85b6156..759656ae1f8a1 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -5853,6 +5853,46 @@ test_float_unpack(PyObject *self, PyObject *args) return PyFloat_FromDouble(d); } +static PyObject * +frame_getlocals(PyObject *self, PyObject *frame) +{ + if (!PyFrame_Check(frame)) { + PyErr_SetString(PyExc_TypeError, "argument must be a frame"); + return NULL; + } + return PyFrame_GetLocals((PyFrameObject *)frame); +} + +static PyObject * +frame_getglobals(PyObject *self, PyObject *frame) +{ + if (!PyFrame_Check(frame)) { + PyErr_SetString(PyExc_TypeError, "argument must be a frame"); + return NULL; + } + return PyFrame_GetGlobals((PyFrameObject *)frame); +} + +static PyObject * +frame_getgenerator(PyObject *self, PyObject *frame) +{ + if (!PyFrame_Check(frame)) { + PyErr_SetString(PyExc_TypeError, "argument must be a frame"); + return NULL; + } + return PyFrame_GetGenerator((PyFrameObject *)frame); +} + +static PyObject * +frame_getbuiltins(PyObject *self, PyObject *frame) +{ + if (!PyFrame_Check(frame)) { + PyErr_SetString(PyExc_TypeError, "argument must be a frame"); + return NULL; + } + return PyFrame_GetBuiltins((PyFrameObject *)frame); +} + static PyObject *negative_dictoffset(PyObject *, PyObject *); static PyObject *test_buildvalue_issue38913(PyObject *, PyObject *); @@ -6142,6 +6182,10 @@ static PyMethodDef TestMethods[] = { {"test_tstate_capi", test_tstate_capi, METH_NOARGS, NULL}, {"float_pack", test_float_pack, METH_VARARGS, NULL}, {"float_unpack", test_float_unpack, METH_VARARGS, NULL}, + {"frame_getlocals", frame_getlocals, METH_O, NULL}, + {"frame_getglobals", frame_getglobals, METH_O, NULL}, + {"frame_getgenerator", frame_getgenerator, METH_O, NULL}, + {"frame_getbuiltins", frame_getbuiltins, METH_O, NULL}, {NULL, NULL} /* sentinel */ }; diff --git a/Objects/frameobject.c b/Objects/frameobject.c index d49931048a625..581de22587219 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -1134,6 +1134,28 @@ PyFrame_GetLocals(PyFrameObject *frame) return frame_getlocals(frame, NULL); } +PyObject* +PyFrame_GetGlobals(PyFrameObject *frame) +{ + return frame_getglobals(frame, NULL); +} + +PyObject* +PyFrame_GetBuiltins(PyFrameObject *frame) +{ + return frame_getbuiltins(frame, NULL); +} + +PyObject * +PyFrame_GetGenerator(PyFrameObject *frame) +{ + if (frame->f_frame->owner != FRAME_OWNED_BY_GENERATOR) { + return NULL; + } + PyGenObject *gen = _PyFrame_GetGenerator(frame->f_frame); + return Py_NewRef(gen); +} + PyObject* _PyEval_BuiltinsFromGlobals(PyThreadState *tstate, PyObject *globals) { From webhook-mailer at python.org Thu Mar 31 16:30:00 2022 From: webhook-mailer at python.org (ericsnowcurrently) Date: Thu, 31 Mar 2022 20:30:00 -0000 Subject: [Python-checkins] bpo-47146: Stop Depending On regen-deepfreeze For regen-global-objects (gh-32218) Message-ID: https://github.com/python/cpython/commit/e7bb7c2f047b4f97e4426c42ae209c969808069d commit: e7bb7c2f047b4f97e4426c42ae209c969808069d branch: main author: Eric Snow committer: ericsnowcurrently date: 2022-03-31T14:29:52-06:00 summary: bpo-47146: Stop Depending On regen-deepfreeze For regen-global-objects (gh-32218) This effectively reverts the Makefile change in gh-31637. I've added some notes so it is more clear what is going on. We also update the "Check if generated files are up to date" job to run "make regen-deepfreeze" to ensure "make regen-global-objects" catches deepfreeze.c. https://bugs.python.org/issue47146 files: M .github/workflows/build.yml M Makefile.pre.in M Tools/scripts/freeze_modules.py diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bda6dde37d185..0ca8d3910814a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -82,6 +82,9 @@ jobs: run: make regen-configure - name: Build CPython run: | + # Deepfreeze will usually cause global objects to be added or removed, + # so we run it before regen-global-objects gets rum (in regen-all). + make regen-deepfreeze make -j4 regen-all make regen-stdlib-module-names - name: Check for changes diff --git a/Makefile.pre.in b/Makefile.pre.in index e784b43d0362d..6dda71bc49cff 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1161,8 +1161,9 @@ Python/deepfreeze/deepfreeze.c: $(DEEPFREEZE_DEPS) Python/frozen_modules/__phello__.spam.h:__phello__.spam \ 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 @@ -1171,24 +1172,11 @@ regen-importlib: regen-frozen ############################################################################ # Global objects -GLOBAL_OBJECTS_TARGETS = \ - $(srcdir)/Include/internal/pycore_global_objects.h \ - $(srcdir)/Include/internal/pycore_global_strings.h - -# The global objects will get regenerated as soon these files -# are required, including as a prerequisite for regen-deepfreeze. -$(GLOBAL_OBJECTS_TARGETS): generate-global-objects - -.PHONY: generate-global-objects -generate-global-objects: $(srcdir)/Tools/scripts/generate_global_objects.py - $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_global_objects.py - -.PHONY: generate-global-objects-after-deepfreeze -generate-global-objects-after-deepfreeze: regen-deepfreeze $(srcdir)/Tools/scripts/generate_global_objects.py - $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_global_objects.py - .PHONY: regen-global-objects -regen-global-objects: regen-deepfreeze generate-global-objects-after-deepfreeze +regen-global-objects: $(srcdir)/Tools/scripts/generate_global_objects.py + $(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 diff --git a/Tools/scripts/freeze_modules.py b/Tools/scripts/freeze_modules.py index c8d8a7dd1fbab..dd208c7847194 100644 --- a/Tools/scripts/freeze_modules.py +++ b/Tools/scripts/freeze_modules.py @@ -606,7 +606,6 @@ def regen_makefile(modules): ]) deepfreezerules.append(f"\t{frozen_header}:{src.frozenid} \\") deepfreezerules.append('\t-o Python/deepfreeze/deepfreeze.c') - deepfreezerules.append('') pyfiles[-1] = pyfiles[-1].rstrip(" \\") frozenfiles[-1] = frozenfiles[-1].rstrip(" \\") From webhook-mailer at python.org Thu Mar 31 16:42:38 2022 From: webhook-mailer at python.org (gpshead) Date: Thu, 31 Mar 2022 20:42:38 -0000 Subject: [Python-checkins] bpo-47151: Fallback to fork when vfork fails in subprocess. (GH-32186) Message-ID: https://github.com/python/cpython/commit/4a08c4c469d36f99d3a5e0f17ad82ab35dcf2835 commit: 4a08c4c469d36f99d3a5e0f17ad82ab35dcf2835 branch: main author: Gregory P. Smith committer: gpshead date: 2022-03-31T13:42:28-07:00 summary: bpo-47151: Fallback to fork when vfork fails in subprocess. (GH-32186) bpo-47151: Fallback to fork when vfork fails in subprocess. An OS kernel can specifically decide to disallow vfork() in a process. No need for that to prevent us from launching subprocesses. files: A Misc/NEWS.d/next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst M Modules/_posixsubprocess.c diff --git a/Misc/NEWS.d/next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst b/Misc/NEWS.d/next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst new file mode 100644 index 0000000000000..d4d02459d35de --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst @@ -0,0 +1,3 @@ +When subprocess tries to use vfork, it now falls back to fork if vfork +returns an error. This allows use in situations where vfork isn't allowed +by the OS kernel. diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index de599f8c970e3..440c7c5b33599 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -685,6 +685,12 @@ do_fork_exec(char *const exec_array[], assert(preexec_fn == Py_None); pid = vfork(); + if (pid == -1) { + /* If vfork() fails, fall back to using fork(). When it isn't + * allowed in a process by the kernel, vfork can return -1 + * with errno EINVAL. https://bugs.python.org/issue47151. */ + pid = fork(); + } } else #endif { From webhook-mailer at python.org Thu Mar 31 17:06:12 2022 From: webhook-mailer at python.org (asvetlov) Date: Thu, 31 Mar 2022 21:06:12 -0000 Subject: [Python-checkins] bpo-45099: Document asyncio internal API (GH-32166) Message-ID: https://github.com/python/cpython/commit/ab89ccff3ca6efc2a8e6f5f45c30d568fb3d212f commit: ab89ccff3ca6efc2a8e6f5f45c30d568fb3d212f branch: main author: Andrew Svetlov committer: asvetlov date: 2022-04-01T00:06:07+03:00 summary: bpo-45099: Document asyncio internal API (GH-32166) files: A Doc/library/asyncio-extending.rst A Misc/NEWS.d/next/Documentation/2022-03-29-13-25-49.bpo-45099.dagdhx.rst M Doc/library/asyncio.rst diff --git a/Doc/library/asyncio-extending.rst b/Doc/library/asyncio-extending.rst new file mode 100644 index 0000000000000..619723e61b5f9 --- /dev/null +++ b/Doc/library/asyncio-extending.rst @@ -0,0 +1,93 @@ +.. currentmodule:: asyncio + + +========= +Extending +========= + +The main direction for :mod:`asyncio` extending is writing custom *event loop* +classes. Asyncio has helpers that could be used to simplify this task. + +.. note:: + + Third-parties should reuse existing asyncio code with caution, + a new Python version is free to break backward compatibility + in *internal* part of API. + + +Writing a Custom Event Loop +=========================== + +:class:`asyncio.AbstractEventLoop` declares very many methods. Implementing all them +from scratch is a tedious job. + +A loop can get many common methods implementation for free by inheriting from +:class:`asyncio.BaseEventLoop`. + +In turn, the successor should implement a bunch of *private* methods declared but not +implemented in :class:`asyncio.BaseEventLoop`. + +For example, ``loop.create_connection()`` checks arguments, resolves DNS addresses, and +calls ``loop._make_socket_transport()`` that should be implemented by inherited class. +The ``_make_socket_transport()`` method is not documented and is considered as an +*internal* API. + + + +Future and Task private constructors +==================================== + +:class:`asyncio.Future` and :class:`asyncio.Task` should be never created directly, +please use corresponding :meth:`loop.create_future` and :meth:`loop.create_task`, +or :func:`asyncio.create_task` factories instead. + +However, third-party *event loops* may *reuse* built-in future and task implementations +for the sake of getting a complex and highly optimized code for free. + +For this purpose the following, *private* constructors are listed: + +.. method:: Future.__init__(*, loop=None) + +Create a built-in future instance. + +*loop* is an optional event loop instance. + +.. method:: Task.__init__(coro, *, loop=None, name=None, context=None) + +Create a built-in task instance. + +*loop* is an optional event loop instance. The rest of arguments are described in +:meth:`loop.create_task` description. + + +Task lifetime support +===================== + +A third party task implementation should call the following functions to keep a task +visible by :func:`asyncio.get_tasks` and :func:`asyncio.current_task`: + +.. function:: _register_task(task) + + Register a new *task* as managed by *asyncio*. + + Call the function from a task constructor. + +.. function:: _unregister_task(task) + + Unregister a *task* from *asyncio* internal structures. + + The function should be called when a task is about to finish. + +.. function:: _enter_task(loop, task) + + Switch the current task to the *task* argument. + + Call the function just before executing a portion of embedded *coroutine* + (:meth:`coroutine.send` or :meth:`coroutine.throw`). + +.. function:: _leave_task(loop, task) + + Switch the current task back from *task* to ``None``. + + Call the function just after :meth:`coroutine.send` or :meth:`coroutine.throw` + execution. diff --git a/Doc/library/asyncio.rst b/Doc/library/asyncio.rst index 8b3a060ffad52..8f4d55a9de059 100644 --- a/Doc/library/asyncio.rst +++ b/Doc/library/asyncio.rst @@ -84,6 +84,7 @@ Additionally, there are **low-level** APIs for asyncio-protocol.rst asyncio-policy.rst asyncio-platforms.rst + asyncio-extending.rst .. toctree:: :caption: Guides and Tutorials diff --git a/Misc/NEWS.d/next/Documentation/2022-03-29-13-25-49.bpo-45099.dagdhx.rst b/Misc/NEWS.d/next/Documentation/2022-03-29-13-25-49.bpo-45099.dagdhx.rst new file mode 100644 index 0000000000000..7b38682b452d2 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2022-03-29-13-25-49.bpo-45099.dagdhx.rst @@ -0,0 +1 @@ +Document internal :mod:`asyncio` API. From webhook-mailer at python.org Thu Mar 31 17:09:59 2022 From: webhook-mailer at python.org (miss-islington) Date: Thu, 31 Mar 2022 21:09:59 -0000 Subject: [Python-checkins] bpo-47151: Fallback to fork when vfork fails in subprocess. (GH-32186) Message-ID: https://github.com/python/cpython/commit/9ed179b07df6ce7432f972f5d069a7c8dee56e79 commit: 9ed179b07df6ce7432f972f5d069a7c8dee56e79 branch: 3.10 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: miss-islington <31488909+miss-islington at users.noreply.github.com> date: 2022-03-31T14:09:50-07:00 summary: bpo-47151: Fallback to fork when vfork fails in subprocess. (GH-32186) bpo-47151: Fallback to fork when vfork fails in subprocess. An OS kernel can specifically decide to disallow vfork() in a process. No need for that to prevent us from launching subprocesses. (cherry picked from commit 4a08c4c469d36f99d3a5e0f17ad82ab35dcf2835) Co-authored-by: Gregory P. Smith files: A Misc/NEWS.d/next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst M Modules/_posixsubprocess.c diff --git a/Misc/NEWS.d/next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst b/Misc/NEWS.d/next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst new file mode 100644 index 0000000000000..d4d02459d35de --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-30-01-17-43.bpo-47151.z-nQkR.rst @@ -0,0 +1,3 @@ +When subprocess tries to use vfork, it now falls back to fork if vfork +returns an error. This allows use in situations where vfork isn't allowed +by the OS kernel. diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index a58159a277bea..18a81c6ed8b35 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -681,6 +681,12 @@ do_fork_exec(char *const exec_array[], assert(preexec_fn == Py_None); pid = vfork(); + if (pid == -1) { + /* If vfork() fails, fall back to using fork(). When it isn't + * allowed in a process by the kernel, vfork can return -1 + * with errno EINVAL. https://bugs.python.org/issue47151. */ + pid = fork(); + } } else #endif { From webhook-mailer at python.org Thu Mar 31 21:25:32 2022 From: webhook-mailer at python.org (asvetlov) Date: Fri, 01 Apr 2022 01:25:32 -0000 Subject: [Python-checkins] bpo-47167: Allow overriding a future compliance check in asyncio.Task (GH-32197) Message-ID: https://github.com/python/cpython/commit/d4bb38f82bf18b00db3129031ce4969b6f0caab9 commit: d4bb38f82bf18b00db3129031ce4969b6f0caab9 branch: main author: Andrew Svetlov committer: asvetlov date: 2022-04-01T04:25:15+03:00 summary: bpo-47167: Allow overriding a future compliance check in asyncio.Task (GH-32197) files: A Misc/NEWS.d/next/Library/2022-03-30-18-35-50.bpo-47167.nCNHsB.rst M Doc/library/asyncio-extending.rst M Lib/asyncio/tasks.py M Lib/test/test_asyncio/test_tasks.py M Modules/_asynciomodule.c M Modules/clinic/_asynciomodule.c.h diff --git a/Doc/library/asyncio-extending.rst b/Doc/library/asyncio-extending.rst index 619723e61b5f9..215d215bb14fe 100644 --- a/Doc/library/asyncio-extending.rst +++ b/Doc/library/asyncio-extending.rst @@ -48,16 +48,27 @@ For this purpose the following, *private* constructors are listed: .. method:: Future.__init__(*, loop=None) -Create a built-in future instance. + Create a built-in future instance. -*loop* is an optional event loop instance. + *loop* is an optional event loop instance. .. method:: Task.__init__(coro, *, loop=None, name=None, context=None) -Create a built-in task instance. + Create a built-in task instance. -*loop* is an optional event loop instance. The rest of arguments are described in -:meth:`loop.create_task` description. + *loop* is an optional event loop instance. The rest of arguments are described in + :meth:`loop.create_task` description. + + .. versionchanged:: 3.11 + + *context* argument is added. + +.. method:: Tasl._check_future(future) + + Return ``True`` if *future* is attached to the same loop as the task, ``False`` + otherwise. + + .. versionadded:: 3.11 Task lifetime support diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index 27fe58da15136..3952b5f2a7743 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -252,6 +252,10 @@ def uncancel(self): self._num_cancels_requested -= 1 return self._num_cancels_requested + def _check_future(self, future): + """Return False if task and future loops are not compatible.""" + return futures._get_loop(future) is self._loop + def __step(self, exc=None): if self.done(): raise exceptions.InvalidStateError( @@ -292,7 +296,7 @@ def __step(self, exc=None): blocking = getattr(result, '_asyncio_future_blocking', None) if blocking is not None: # Yielded Future must come from Future.__iter__(). - if futures._get_loop(result) is not self._loop: + if not self._check_future(result): new_exc = RuntimeError( f'Task {self!r} got Future ' f'{result!r} attached to a different loop') diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 8df1957bbe9e7..80afb27351362 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -2383,7 +2383,13 @@ def add_done_callback(self, *args, **kwargs): return super().add_done_callback(*args, **kwargs) class Task(CommonFuture, BaseTask): - pass + def __init__(self, *args, **kwargs): + self._check_future_called = 0 + super().__init__(*args, **kwargs) + + def _check_future(self, future): + self._check_future_called += 1 + return super()._check_future(future) class Future(CommonFuture, BaseFuture): pass @@ -2409,6 +2415,8 @@ async def func(): dict(fut.calls), {'add_done_callback': 1}) + self.assertEqual(1, task._check_future_called) + # Add patched Task & Future back to the test case cls.Task = Task cls.Future = Future diff --git a/Misc/NEWS.d/next/Library/2022-03-30-18-35-50.bpo-47167.nCNHsB.rst b/Misc/NEWS.d/next/Library/2022-03-30-18-35-50.bpo-47167.nCNHsB.rst new file mode 100644 index 0000000000000..a37dd25810f2e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-30-18-35-50.bpo-47167.nCNHsB.rst @@ -0,0 +1 @@ +Allow overriding a future compliance check in :class:`asyncio.Task`. diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 632a4465c224a..d8d3da91cdd8e 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -23,6 +23,7 @@ _Py_IDENTIFIER(call_soon); _Py_IDENTIFIER(cancel); _Py_IDENTIFIER(get_event_loop); _Py_IDENTIFIER(throw); +_Py_IDENTIFIER(_check_future); /* State of the _asyncio module */ @@ -1795,6 +1796,8 @@ class _asyncio.Task "TaskObj *" "&Task_Type" static int task_call_step_soon(TaskObj *, PyObject *); static PyObject * task_wakeup(TaskObj *, PyObject *); static PyObject * task_step(TaskObj *, PyObject *); +static int task_check_future(TaskObj *, PyObject *); +static int task_check_future_exact(TaskObj *, PyObject *); /* ----- Task._step wrapper */ @@ -2269,7 +2272,6 @@ Returns the remaining number of cancellation requests. static PyObject * _asyncio_Task_uncancel_impl(TaskObj *self) /*[clinic end generated code: output=58184d236a817d3c input=68f81a4b90b46be2]*/ -/*[clinic end generated code]*/ { if (self->task_num_cancels_requested > 0) { self->task_num_cancels_requested -= 1; @@ -2277,6 +2279,21 @@ _asyncio_Task_uncancel_impl(TaskObj *self) return PyLong_FromLong(self->task_num_cancels_requested); } +/*[clinic input] +_asyncio.Task._check_future -> bool + + future: object + +Return False if task and future loops are not compatible. +[clinic start generated code]*/ + +static int +_asyncio_Task__check_future_impl(TaskObj *self, PyObject *future) +/*[clinic end generated code: output=a3bfba79295c8d57 input=3b1d6dfd6fe90aa5]*/ +{ + return task_check_future_exact(self, future); +} + /*[clinic input] _asyncio.Task.get_stack @@ -2502,6 +2519,7 @@ static PyMethodDef TaskType_methods[] = { _ASYNCIO_TASK_CANCEL_METHODDEF _ASYNCIO_TASK_CANCELLING_METHODDEF _ASYNCIO_TASK_UNCANCEL_METHODDEF + _ASYNCIO_TASK__CHECK_FUTURE_METHODDEF _ASYNCIO_TASK_GET_STACK_METHODDEF _ASYNCIO_TASK_PRINT_STACK_METHODDEF _ASYNCIO_TASK__MAKE_CANCELLED_ERROR_METHODDEF @@ -2569,6 +2587,43 @@ TaskObj_dealloc(PyObject *self) Py_TYPE(task)->tp_free(task); } +static int +task_check_future_exact(TaskObj *task, PyObject *future) +{ + int res; + if (Future_CheckExact(future) || Task_CheckExact(future)) { + FutureObj *fut = (FutureObj *)future; + res = (fut->fut_loop == task->task_loop); + } else { + PyObject *oloop = get_future_loop(future); + if (oloop == NULL) { + return -1; + } + res = (oloop == task->task_loop); + Py_DECREF(oloop); + } + return res; +} + + +static int +task_check_future(TaskObj *task, PyObject *future) +{ + if (Task_CheckExact(task)) { + return task_check_future_exact(task, future); + } else { + PyObject * ret = _PyObject_CallMethodIdOneArg((PyObject *)task, + &PyId__check_future, + future); + if (ret == NULL) { + return -1; + } + int is_true = PyObject_IsTrue(ret); + Py_DECREF(ret); + return is_true; + } +} + static int task_call_step_soon(TaskObj *task, PyObject *arg) { @@ -2790,7 +2845,11 @@ task_step_impl(TaskObj *task, PyObject *exc) FutureObj *fut = (FutureObj*)result; /* Check if `result` future is attached to a different loop */ - if (fut->fut_loop != task->task_loop) { + res = task_check_future(task, result); + if (res == -1) { + goto fail; + } + if (res == 0) { goto different_loop; } @@ -2862,15 +2921,13 @@ task_step_impl(TaskObj *task, PyObject *exc) } /* Check if `result` future is attached to a different loop */ - PyObject *oloop = get_future_loop(result); - if (oloop == NULL) { + res = task_check_future(task, result); + if (res == -1) { goto fail; } - if (oloop != task->task_loop) { - Py_DECREF(oloop); + if (res == 0) { goto different_loop; } - Py_DECREF(oloop); if (!blocking) { goto yield_insteadof_yf; diff --git a/Modules/clinic/_asynciomodule.c.h b/Modules/clinic/_asynciomodule.c.h index 4b64367a3f631..163b0f95691b3 100644 --- a/Modules/clinic/_asynciomodule.c.h +++ b/Modules/clinic/_asynciomodule.c.h @@ -466,6 +466,43 @@ _asyncio_Task_uncancel(TaskObj *self, PyObject *Py_UNUSED(ignored)) return _asyncio_Task_uncancel_impl(self); } +PyDoc_STRVAR(_asyncio_Task__check_future__doc__, +"_check_future($self, /, future)\n" +"--\n" +"\n" +"Return False if task and future loops are not compatible."); + +#define _ASYNCIO_TASK__CHECK_FUTURE_METHODDEF \ + {"_check_future", (PyCFunction)(void(*)(void))_asyncio_Task__check_future, METH_FASTCALL|METH_KEYWORDS, _asyncio_Task__check_future__doc__}, + +static int +_asyncio_Task__check_future_impl(TaskObj *self, PyObject *future); + +static PyObject * +_asyncio_Task__check_future(TaskObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"future", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "_check_future", 0}; + PyObject *argsbuf[1]; + PyObject *future; + int _return_value; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + future = args[0]; + _return_value = _asyncio_Task__check_future_impl(self, future); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + PyDoc_STRVAR(_asyncio_Task_get_stack__doc__, "get_stack($self, /, *, limit=None)\n" "--\n" @@ -890,4 +927,4 @@ _asyncio__leave_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, exit: return return_value; } -/*[clinic end generated code: output=64b3836574e8a18c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=fdb7129263a8712e input=a9049054013a1b77]*/